Somma di sottostringhe binarie


16

Questa sfida è semplice, dato un numero decimale, converti in binario e calcola la somma delle sottostringhe del numero binario, la cui lunghezza è inferiore al numero originale. Ecco un esempio:

Input:
  11
Binary:
  11 -> 1011
Substrings:
  101 = 5
  011 = 3
  10  = 2
  01  = 1
  11  = 3
  1   = 1
  0   = 0
  1   = 1
  1   = 1
Sum:
  5+3+2+1+3+1+0+1+1=17
Output:
  17

Il tuo programma dovrebbe prendere un singolo intero decimale come input e produrre la somma delle sottostringhe binarie, come visto sopra. Si può presumere che l'input avrà sempre più di due cifre nella sua rappresentazione binaria e che in input non causerà alcun errore durante l'esecuzione del programma.

Questo è , vince il codice più corto in byte!

Casi test:

2  => 1
3  => 2
4  => 3
5  => 5
6  => 7
7  => 9
8  => 7
9  => 10
10 => 14
11 => 17

4
Curiosamente, l'esclusione della sottostringa a lunghezza intera rappresenta una sfida extra significativa.
Peter Taylor,

Risposte:


12

Gelatina, 10 7 byte

BṡRḄFS_

Provalo online!

Come funziona

BṡRḄFS_  Main link. Input: n

B        Convert n to base 2.
  R      Yield [1, ..., n].
 ṡ       Get all overlapping slices of lengths 1 to n.
         This yields empty arrays if the slice size is longer than the binary list.
   Ḅ     Convert each binary list to integer.
    F    Flatten the resulting, nested list.
     S   Compute the sum of the result.
      _  Subtract n from the sum.

Quale codifica ti dà 1 byte / carattere per quel programma?
Toby Speight,

1
@TobySpeight Jelly utilizza una propria
uno spaghetto il

8

Pyth, 10

sPiR2.:.BQ

Provalo online o esegui Test Suite

Spiegazione:

sPiR2.:.BQ    ##   Q = eval(input())
       .BQ    ##   get binary string of Q
     .:       ##   get all substrings of that
  iR2         ##   convert them all to base 10
sP            ##   sum all but the last element, which is the input number

6

CJam, 27 21 byte

Invia a Dennis per avermi aiutato a salvare 6 byte!

q~:Q{)Q2bew2fb~}%1bQ-

Funziona solo con la versione più recente di CJam (disponibile su TIO). Provalo online !

Vecchia versione:

qi2b_,,0-\f{ew}{{2b}%}%e_:+

Provalo online .


5

Python 3, 111 caratteri

N=bin(int(input()))[2:];L=len(N);r=range;print(sum(int(n,2)for n in[N[j:j+i]for i in r(1,L)for j in r(L-i+1)]))

EDIT : Spiegazione:

N=bin(int(input()))[2:]

Converti la stringa di input in un int, quindi l'int in una stringa binaria e rimuovi i suoi primi due caratteri, poiché il binmetodo restituisce una stringa nel formato di0b...

Prendi tutte le sottostringhe della stringa binaria, convertile in decimale usando int(n, 2)e sommale.

[N[j:j+i]for i in r(1,L)for j in r(L-i+1)]

è un elenco di tutte le sottostringhe. Versione non golfata:

def all_substrings(N):
    result = []
    for i in range(1, len(N)):
        for j in range(len(N) - i + 1):
            result.append(N[j:j+i])
    return result

Spero che sia di aiuto.


4

CJam (22 byte)

Questo è un byte più lungo dell'attuale migliore risposta CJam, ma l'approccio può probabilmente essere adattato ad alcune altre lingue in modo abbastanza redditizio.

3,ri_2b_,,:).*\+fbW%:-

Demo online

Analisi

Supponiamo che la domanda fosse

calcola la somma delle sottostringhe del numero binario

senza un po '

la cui lunghezza è inferiore al numero originale

Quindi non è troppo difficile dimostrare che il bit più significativo si verifica con il peso totale 1*(2^B-1)dove si Btrova il numero di bit; il secondo bit più significativo si verifica con il peso totale 2*(2^(B-1)-1); fino al bit più significativo del Bth, che si verifica con il peso totale B*(2^1-1).

Tenendo conto ora della sottrazione del numero originale x, finiamo con la somma

sum_i (x & 2^i) * 2^i * 2*(B-i)  -  sum_i (x & 2^i) * (B-i)  -  x

Dissezione

3,        e# Put [0 1 2] on the stack - we'll need it later
ri_       e# Get the input x and copy it
2b        e# Convert the copy to base 2
_,,:).*   e# Pointwise multiply by 1 plus the index
\+        e# Append x to the resulting array, giving A
fb        e# Map a base conversion
W%:-      e# Reverse and fold a subtraction

La conversione in base 2 fornisce la prima parte della somma principale più x; alla base 1 dà la seconda parte in più x; e alla base 0 dà giusto x, quindi sottraendo la base-1 dalla base-2 si xannulla s, e sottraendo la base-0 si ottiene il risultato desiderato.


3

JavaScript (ES6), 78 byte

n=>[...n.toString(2)].map(c=>[...s+=c].map((_,i)=>n-='0b'+s.slice(i)),s='')|-n

L'esterno mapcrea sottostringhe principali della nrappresentazione binaria; quello interno estrae le sottostringhe finali delle sottostringhe principali, coprendo così tutte le possibili sottostringhe, inclusa la rappresentazione binaria originale.

Ogni sottostringa viene convertita dal ritorno binario in decimale e sottratta dall'input originale in quanto è leggermente più breve rispetto all'aggiunta insieme e alla sottrazione dell'input originale.


2

Mathematica, 73 70 byte

Tr[FromDigits[#,2]&/@StringCases[#~IntegerString~2,__,Overlaps->All]]&

Funzione. Integer-> Intero


1
Peccato che la matematica non abbia grandi strumenti per gestire le liste.
A Simmons,

1

Retina , 64

.*
$*
+`(1+)\1
$1a
a1
1
r&!M`.*
&!M`.*
^.*

+`1(a*)\b
a$.1$*1;
;

Provalo online!

Descrizione di fase per fase di alto livello: converti decimale in unario, unario in binario, ottieni prefissi, ottieni suffissi di prefissi, scarica il numero originale, converti binario in unario, restituisci il conteggio. Scriverò una descrizione più dettagliata una volta che avrò finito di giocare a golf, molte di queste fasi sembrano sospette ...


1

C, 71 byte

f(n){int a=0,m=0,i;for(;++m<n;m+=m)for(i=n;i+i>m;i/=2)a+=i&m;return a;}

Manteniamo un accumulatore ae una maschera m. La maschera inizia da 1 e diventa un po 'più lunga ogni volta attorno al circuito esterno. Nel ciclo interno, una copia idell'ingresso viene spostata successivamente a destra fino a quando non è più corta della maschera, accumulando ogni volta il valore mascherato.

Programma di test

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
    while (*++argv) {
        int n = atoi(*argv);
        printf("%d -> %d\n", n, f(n));
    }
    return 0;
}

Uscita di prova

./73793 $(seq 0 11)
0 -> 0
1 -> 0
2 -> 1
3 -> 2
4 -> 3
5 -> 5
6 -> 7
7 -> 9
8 -> 7
9 -> 10
10 -> 14
11 -> 17

1

C #, 148 byte

int x(int i){int s,r=0,j=i,p=System.Convert.ToString(i,2).Length+1,k;for(;--p>-1;){k=j;s=-1;for(;++s<p;)r+=(k>>=1);j=(i&((1<<p-1)-1))<<1;}return r;}

Oppure, se aggiungo Import "using static System.Math;" poi 138 con

int x(int i){int s,r=0,j=i,p=(int)Round(Log(i,2)+1.49,0),k;for(;--p>-1;){k=j;s=-1;for(;++s<p;)r+=(k>>=1);j=(i&((1<<p-1)-1))<<1;}return r;}

I linguaggi OOP come C # non vinceranno una gara del genere, ma volevo provarla comunque. Ecco una versione + tester più abbellita.

class Program
{
    // Tester: 50 bytes
    static void Main(string[] args)
    {
        int i=2;
        do System.Console.WriteLine($"{i} -> {x(i++)}"); while (i < 12);
        System.Console.Read();
    }
    // Function: 65 bytes (size according to ILDASM.exe)
    static int x(int iOrg)
    {
        int pos, shift, retVal=0, iPrev=iOrg, iTemp;
        pos = System.Convert.ToString(iOrg, 2).Length;
        do {
            iTemp = iPrev; shift = 0;
            do retVal += (iTemp >>= 1); while (++shift < pos);
            iPrev = (iOrg & ((1 << pos - 1) - 1)) << 1;
        } while (--pos > -1); 
        return retVal;
    }
}

Il do-while nidificato aggiunge il valore spostato a destra di iTemp (dopo averlo assegnato) fintanto che shift + 1 è più piccolo di pos. La riga successiva calcola il valore spostato successivo di iPrev

x1 = 1 << p -1; // 1 << 4 -1 = 8 [1000]
x2 = x1 - 1;    // 8 -  1 = 7    [0111]
x3 = i & x2;    // 1011 & 0111 = 0011 
x4 = x3 << 1;   // 0011 << 1 = 00110
i2 = x4;

x1 e x2 calcolano la maschera, x3 la applica e poi la sposta a sinistra, poiché l'ultima cifra viene sempre rilasciata. Per 11, si presenta così:

START -> _1011[11]
101
10
1   -->  X0110[6], r=0+5+2+1=8
 011
 01
 0  -->  XX110[6], r=8+4=12
  11
  1 -->  XXX10[2], r=12+4=16
   1 ->  XXXX0[X], r=16+1=17

Lo so, la maggior parte delle risposte in C funzionano senza problemi anche in C # (@ Tony-Speight ha funzionato senza problemi), ma questo sfiderebbe lo scopo. Inoltre, non ho guardato i commenti (beh, tranne le intestazioni in grassetto) fino a quando non ho finito io stesso, quindi non c'era pericolo di farlo "come C".
DW.com,

0

PowerShell v2 +, 138 byte

param($a)$a=[convert]::ToString($a,2);(($b=$a.length-1)..1|%{$l=$_;0..($b-$l+1)|%{[convert]::ToInt32($a.substring($_,$l),2)}})-join'+'|iex

Ooof. Quella conversione da / a binaria è costosa.

Accetta l'input $a, quindi utilizza la chiamata .NET[convert]::ToString($a,2) per trasformarla in rappresentazione binaria. Da lì, passiamo attraverso due anelli: il primo conta indietro dalla fine della stringa fino a 1, e il secondo conta verso l'alto da 0. (Il primo è il tempo di estrazione di una sottostringa e il secondo è l'indice di dove nella stringa iniziare la sottostringa.) Impostiamo un aiuto $llungo la strada per passarlo attraverso l'anello interno.

All'interno del ciclo interno, usiamo un'altra chiamata .NET[convert]::ToInt32() per convertire l'appropriato .substring()dalla base 2in un numero intero. Ciascuno di questi viene quindi lasciato in cantiere. Incapsuliamo tutto ciò con le parentesi ()e -joinloro insieme a un +, quindi lo gettiamo via a iex(abbreviazione di Invoke-Expressione simile a eval).

Penso che questo richieda tecnicamente v2 o più recente per chiamare correttamente le chiamate .NET.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.