Convertitore binario a decimale


32

Convertitore binario a decimale

Per quanto posso vedere, non abbiamo una semplice sfida di conversione da binaria a decimale.


Scrivi un programma o una funzione che accetta un numero intero binario positivo e genera il suo valore decimale.

Non è consentito utilizzare alcuna funzione di conversione di base integrata. Le funzioni da intero a decimale (ad es. Una funzione che si trasforma 101010in [1, 0, 1, 0, 1, 0]o "101010") sono esenti da questa regola e quindi consentite.

Regole:

  • Il codice deve supportare i numeri binari fino al valore numerico più alto supportato dalla tua lingua (per impostazione predefinita)
  • Puoi scegliere di avere zeri iniziali nella rappresentazione binaria
  • L'output decimale potrebbe non avere zeri iniziali.
  • I formati di input e output sono opzionali, ma non possono esserci separatori tra le cifre. (1,0,1,0,1,0,1,0)non è un formato di input valido, ma entrambi 10101010e lo (["10101010"])sono.
    • Devi prendere l'input nella direzione "normale". non lo 1110è .147

Casi test:

1
1

10
2

101010
42

1101111111010101100101110111001110001000110100110011100000111
2016120520371234567

Questa sfida è collegata ad alcune altre sfide, ad esempio questo , questo e questo .



L'output deve essere senza segno o può essere firmato? Inoltre, se la mia lingua cambia automaticamente tra numeri interi a 32 e 64 bit a seconda della lunghezza del valore, l'output può essere firmato in entrambi gli intervalli? Ad esempio: ci sono due valori binari che verranno convertiti in decimali -1( 32 1'se 64 1's)
latte il

Inoltre, l'output può essere mobile, deve essere un numero intero?
Carcigenicato il

@Carcigenicate Deve essere un numero intero, ma può essere di qualsiasi tipo di dati. Finché round(x)==xstai bene :) 2.000viene accettato l'output per 10.
Stewie Griffin,

Che dolce. Grazie.
Carcigenicato il

Risposte:


56

Gelatina , 5 byte

DḤ+¥/

Provalo online!

Spiegazione

enter image description here

Il cast

  • Dè una monade (funzione argomento singolo): cifre, che si trasformano 1234in [1, 2, 3, 4].

  • è una monade che raddoppia il suo unico argomento.

  • + è una diade (funzione a due argomenti) che aggiunge i suoi argomenti sinistro e destro.

Da lì, diventa un po 'complicato.

Ecco cosa succede al momento dell'analisi

  • D, e +vengono letti. La catena sembra [D, Ḥ, +].

  • I prossimi due caratteri sono rapidi , che agiscono come operatori postfix di parse-time sui collegamenti (funzioni) che abbiamo letto finora.

  • Quando ¥viene letto, gli ultimi due collegamenti vengono visualizzati e sostituiti da un collegamento che agisce come la diade formata componendoli. Quindi ora la catena sembra [D, dyad(Ḥ+)].

  • Quando /viene letto, l'ultimo collegamento (che dovrebbe essere una diade) viene visualizzato e sostituito da una monade che si piega usando questa diade (intuitivamente: f/prende un elenco, sostituisce le virgole in esso con fe valuta il risultato).

  • Sembra la catena finale [D, fold(dyad(Ḥ+))], due monadi.

Ecco cosa succede in fase di esecuzione

  • L'input (un numero) viene letto implicitamente nel valore di lavoro (diciamo, 101010).

  • Dviene eseguito, sostituendo il valore di lavoro con le sue cifre ( [1,0,1,0,1,0]).

  • fold(dyad(Ḥ+))viene eseguito, sostituendo il valore di lavoro con 1∗0∗1∗0∗1∗0, dove si trova la diade Ḥ+.

Quindi cosa x∗yvaluta?

  • In una definizione diadica, il valore di lavoro è inizialmente a sinistra argomento x.

  • , il doppio monade, raddoppia questo valore. Il valore di lavoro è ora 2x.

  • +, Il più diade, manca un argomento di destra, quindi questo è un gancio : un modello speciale sintattica dove il diritto argomento di questa diade viene iniettato+ . Questo produce 2x + yil valore operativo finale, che viene restituito.

Quindi l'intera espressione valuta:

1∗0∗1∗0∗1∗0 = 2×(2×(2×(2×(2×1+0)+1)+0)+1)+0
            = 32×1 + 16×0 + 8×1 + 4×0 + 2×1 + 1×0
            = 42

10
Le tue spiegazioni stanno migliorando sempre di più :-)
Luis Mendo il

2
Eh, immagino tu lo faccia da ora in poi? È fantastico, +1.
Erik the Outgolfer,

4
Penso che questo sia il primo pezzo di Jelly che abbia mai capito. +1!
Blue

Bravo. In realtà capisco quello che inizialmente pensavo fosse solo un casino di personaggi apparentemente casuali. Spiegazione meravigliosa.
pesce suino

1
@Mark Jelly ha una sua codepage per rendere i programmi apparenti, ahem, leggibili, ma i programmi potrebbero anche essere solo distrazioni.
Lynn,

20

Python 2, 49 37 31 30 byte

Ora questo richiederà un numero binario in una rappresentazione decimale, poiché Python può gestire numeri interi arbitrariamente grandi.

b=lambda n:n and n%2+2*b(n/10)

grazie a xnor per aver salvato un byte :)

Il modo più semplice per vedere come funziona è vedere una formula di base per convertire i binari in decimali:

= 101010 
= 1*(2^5) + 0*(2^4) + 1*(2^3) + 0*(2^2) + 1*(2^1) + 0*(2^0)
= 1*32 + 0*16 + 1*8 + 0*4 + 1*2 + 0*1
= 42

Questo è un modo "standard" di conversione. Puoi espandere la terza riga in questo modo:

= ((((1*2 + 0)*2 + 1)*2 + 0)*2 + 1)*2 + 0

E questo è essenzialmente ciò che sta facendo il metodo ricorsivo che ho fatto.

Soluzioni alternative che ho avuto:

b=lambda n:n and n%10+2*b(n/10)
b=lambda n:n%10+2*(n and b(n/10))
b=lambda n:0if n<1else n%10+2*b(n/10)
b=lambda n:0**(n/10)or n%10+2*b(n/10)
b=lambda n,o=0:o*(n<'0')or b(n[1:],2*o+int(n[0]))
lambda j:sum(int(b)*2**a for a,b in enumerate(j,1))

6
Puoi fare n%5o n%2invece di n%10.
xnor

@xnor Ah, non sono sicuro di come mi sia perso! Grazie :)
Kade il

12

05AB1E , 6 byte

Codice:

$¦v·y+

Per la spiegazione, prendiamo l'esempio 101010 . Iniziamo con il numero 1 (che è rappresentato dalla prima cifra). Successivamente, abbiamo due casi:

  • Se la cifra è 0 , moltiplicare il numero per 2.
  • Se la cifra è a 1 , moltiplica il numero per 2 e aggiungi 1.

Quindi per il caso 101010 , viene calcolato quanto segue:

  • 1 01010, inizia con il numero 1 .
  • 1 0 1010, moltiplicare per due, risultando in 2 .
  • 10 1 010, moltiplicalo per due e aggiungi uno, risultando in 5 .
  • 101 0 10, moltiplicare per due, risultando in 10 .
  • 1010 1 0, moltiplicalo per due e aggiungi uno, risultando in 21 .
  • 10101 0 , moltiplicare per due, risultando in 42 , che è il risultato desiderato.

Spiegazione del codice:

$         # Push 1 and input
 ¦        # Remove the first character
  v       # For each character (starting with the first)
   ·      #   Multiply the carry number by two
    y+    #   Add the current character (converted automatically to a number)

Utilizza la codifica CP-1252 . Provalo online!


Ben fatto! (non funziona per 0 anche se ho appena notato)
Emigna il

@Emigna Sì, per fortuna il tuo codice deve funzionare solo per numeri binari positivi.
Adnan,

Non ho nemmeno visto quella parte. Molto bello allora :)
Emigna il

9

Haskell, 16 111 + 57 = 168 byte

import Data.String
instance IsString[Int]where fromString=map((-48+).fromEnum)
f::[Int]->Int
f=foldl1((+).(2*))

57 byte per la flag di compilazione -XOverloadedStrings, -XOverlappingInstancese-XFlexibleInstances .

La sfida ha un formato I / O ingombrante , poiché dipende fortemente dal modo in cui i tipi di dati sono espressi nel codice sorgente. La mia prima versione (16 byte), vale a dire

foldl1((+).(2*))

accetta un elenco di numeri interi, ad esempio, [1,0,1,0,1,0]ed è stato dichiarato non valido perché ,tra gli elementi sono presenti elenchi letterali di Haskell . Gli elenchi di per sé non sono vietati. Nella mia nuova versione utilizzo la stessa funzione, ora denominataf , ma sovraccarico "Cita sequenze di caratteri racchiuse". La funzione prende ancora un elenco di numeri interi come puoi vedere nell'annotazione del tipo [Int] -> Int, ma gli elenchi con numeri interi a una cifra ora possono essere scritti come "1234", ad es.

f "101010"

che valuta 42. Sfortunato Haskell, perché il formato dell'elenco nativo non si adatta alle regole della sfida. A proposito, f [1,0,1,0,1,0]funziona ancora.


2
Purtroppo un elenco non è un input valido.
Jonathan Allan,

@JonathanAllan: Why? E se è così, come dovrebbe essere necessario un input? In Haskell una stringa è solo un elenco di caratteri.
nimi,

Non so perché ... ma mi sono chiesta presto e ho fatto una modifica per aggiungere " (1,0,1,0,1,0,1,0)non è un formato di input valido, ma entrambi 10101010e lo (["10101010"])sono". inoltre un commento suggerisce che l'array di caratteri è accettabile se è così che viene interpretato un input di stringa.
Jonathan Allan,

1
@JonathanAllan: qualsiasi "numero intero binario" (l'input che dobbiamo prendere) è intrinsecamente separato, è una sequenza di potenze di 2. La limitazione riguarda i separatori espliciti (tra le cifre) e non la separazione. In qualche modo devo prendere cifre separate.
nimi,

2
Op qui: se è possibile inserire 10101010, "10101010"o qualcosa di simile e farlo funzionare, l'invio è valido. Puoi chiamarlo stringa, elenco, numero intero o altro. Immissione [1][0][1][0]o [1,0,1,0]non va bene. Fondamentalmente, dovrebbe essere possibile colpire un gruppo di quelli e zeri di fila da qualche parte. È chiaro?
Stewie Griffin,

7

Retina, 15 byte

Converte da binario a unario, quindi da unario a decimale.

1
01
+`10
011
1

Provalo online


Non è consentito utilizzare alcuna funzione di conversione di base integrata. ~ OP
Roman Gräf,

10
@ RomanGräf Non ce ne sono. Stavo semplicemente descrivendo il processo della mia soluzione.
mbomb007,

7

PHP, 44 byte

for(;""<$c=$argv[1][$i++];)$n+=$n+$c;echo$n;

Avrei potuto giurare di aver già visto quella domanda prima. Ma bene.

Legge il numero da sinistra a destra, sposta a sinistra e aggiunge il bit corrente.


7

JavaScript (ES6), 33 31 byte

s=>[...s].map(c=>r+=+c+r,r=0)|r

Modifica: più breve ma meno dolce: 2 byte salvati grazie a @ETHproductions.


Come spesso accade, .mapè più breve:s=>[...s].map(c=>+c+r+r,r=0)|r
ETHproductions

@ETHproductions In che modo la tua funzione restituisce qualcosa di diverso da 0?
Neil,

Siamo spiacenti, dovrebbe esseres=>[...s].map(c=>r+=+c+r,r=0)|r
ETHproductions

7

Labirinto , 17 15 byte

-+:
8 +
4_,`)/!

Provalo online!

Image of the code

Labyrinth è un linguaggio bidimensionale basato su stack. Nel labirinto, l'esecuzione del codice segue il percorso del codice come un labirinto con spazi che agiscono come muri e iniziano dal carattere non spaziale più in alto a sinistra. Il flusso di codice è determinato dal segno della parte superiore dello stack. Poiché lo stack ha zeri impliciti in fondo, le prime quattro istruzioni ( -+:+) non hanno alcun effetto.

Loop che inizia al ,

  • , Spingere il valore del codice ASCII del carattere di input successivo fino all'arresto dello stack o premere -1 se EOF.
  • _48 spinge 48 in cima alla pila
  • - Pop y, pop x, push x-y . Le precedenti istruzioni hanno l'effetto di sottrarre 48 dall'input restituendo 0 per "0" e 1 per "1".
  • +Pop y, pop x, push x+y.
  • : Duplica la parte superiore della pila
  • + Questa e l'istruzione precedente hanno l'effetto di moltiplicare il valore corrente per 2

Quindi la parte circolare del codice, in effetti, moltiplica il numero corrente per 2 e aggiunge 1 o 0 a seconda che sia stato inserito il carattere 1 o 0.

Coda

Se la parte superiore dello stack è negativa (significa che è stato trovato EOF), il codice girerà a sinistra al bivio (andando verso il punto e virgola).

  • `` Annulla la parte superiore dello stack per ottenere 1
  • ) Icrementa la cima dello stack per ottenere 2
  • /Pop y, pop x, push x / y (divisione intera). Ciò ha l'effetto di annullare l'ultimo *2dal ciclo.
  • !Emette la rappresentazione intera della parte superiore dello stack. A questo punto il programma si gira perché ha raggiunto un vicolo cieco e quindi esce con un errore perché tenta di dividere per zero.

Grazie a @Martin Ender per avermi salvato 2 byte (e insegnandomi come pensare meglio in Labyrinth).


Invece di _48-te puoi semplicemente farlo, #%ma sfortunatamente non vedo come possa essere d'aiuto con il conteggio dei byte.
Martin Ender,

È possibile salvare un byte con `)invece di ;_2però.
Martin Ender,

@MartinEnder, non capisco il tuo commento #%. Puoi spiegare come funziona in sostituzione _48-di convertire da ASCII a int. Grazie per il )suggerimento. Farò quel cambiamento.
Robert Hickman,

A quel punto nel tuo programma ci sono sempre due valori nello stack, quindi #è solo l'abbreviazione di _2. Sebbene _2%non sia un metodo di conversione generale per ASCII in numero intero, funziona qui perché sei interessato solo alle prime due cifre come input possibile. Un'alternativa sarebbe _1&(poiché il modulo 2 estrae semplicemente il bit meno significativo).
Martin Ender,

Oh. È geniale. Ma sì, non sono sicuro di come utilizzare quella sostituzione ( #%) per abbreviare il codice in generale.
Robert Hickman,

6

Brain-Flak , 46 , 28 byte

([]){{}({}<>({}){})<>([])}<>

Provalo online!

Molti byte salvati grazie a @Riley!

Poiché il brain-flak non può accettare input binari, input è un elenco di "0" e "1".

Spiegazione:

#Push the height of the stack
([])

#While true:
{

 #Pop the height of the stack
 {}

 #Push this top number to (the other stack * 2)
 ({}<>({}){})

 #Toggle back on to the main stack
 <>

 #Push the new height of the stack
 ([])

#endwhile
}

#Toggle back to the other stack, implicitly display.
<>

Adoro la spiegazione! Così difficile da leggere senza
difetti

2
^. Non riesco nemmeno a leggere i miei programmi se non mi lascio qualche commento.
Riley,

You can get it down to 32 bytes by getting rid of the whole if part,and for the step "add number to other stack" just add it to the (other stack)*2. ([]){({}[()]<({}<>({}){})><>)}<>
Riley

And you can save another 4 by just popping at the start of the while and pushing the height again at the end. ([]){{}({}<>({}){})<>([])}<>
Riley

@Riley Oh my gosh, that's genius. Thankyou very much!
DJMcMayhem

6

Java, 84 79 46 48 bytes

  • Version 3.1

Changed to long/48 bytes:

s->{long x=0;for(char c:s)x=c-48l+x*2;return x;}
  • Version 3.0

Did some golfing/46 bytes:

s->{int x=0;for(char c:s)x=c-48+x*2;return x;}
  • Version 2.0

Thanks to @Geobits!/79 bytes:

s->{int i=Math.pow(2,s.length-1),j=0;for(char c:s){j+=c>48?i:0;i/=2;}return j;}
  • Version 1.0

84 bytes:

s->{for(int i=-1,j=0;++i<s.length;)if(s[i]>48)j+=Math.pow(2,s.length-i+1);return j;}

1
guess i should have done an iterative solution. lulz. good job
Poke

Is your input type List<Character> or String? If it's the latter, I was unaware Java8 could do that! If it's the former is that allowed by the challenge?
Poke

s should be char[]. I hope that's allowed...
Roman Gräf

What is the return type here? I think it should be long because "The code must support binary numbers up to the highest numeric value your language supports" per the OP but for smaller values I would think it returns an int
Poke

1
Probably fine on input type per this. Might want to take the 2 byte hit for output imo
Poke

4

Befunge-98, 12 bytes

2j@.~2%\2*+

Try it online!

Reads one char at a time from input, converts it to 0 or 1 by taking its value modulo 2 (0 is char(48), 1 is char(49)), then uses the usual algorithm of doubling the current value and adding the new digit each time.

Bonus: This works with any kind of input string, I've been trying for a while now to find any funny input->output combination, but I wasn't able to produce anything (sadly, "answer"=46). Can you?


LOL. I was playing the same game with my answer. Most interesting number I could generate was 666.
James Holderness

Nice one! I hadn't managed to find anything fitting for 666 :D It would be a lot easier if capitalization had an effect on values...
Leo

@James Holderness - I've been doing the same and I've only found 'theleapyear' to bring back 366, yours is really good.
Teal pelican

4

Javascript (ES7) 41 40 36 bytes

f=([c,...b])=>c?c*2**b.length+f(b):0

takes a string as input

Shaved a byte thanks to ETHproductions

f=([c,...b])=>c?c*2**b.length+f(b):0
document.write([
    f('101010'),
    f('11010'),
    f('10111111110'),
    f('1011110010110'),
].join("<br>"))


1
The right-to-left associativity of ** is weird, but nice job using it here. 1<<b.length would do the same thing, but it would require parentheses to keep from being parsed as (c*1)<<(b.length+...). I think you can save a byte by replacing b[0] with b+b (see here).
ETHproductions

4

C# 6, 85 37 36 bytes

long b(long n)=>n>0?n%2+2*b(n/10):0;
  • Thanks to Kade for saving 41 bytes!
  • Changing to C# 6 saved another 7 bytes.

Maybe this could provide some inspiration? ;)
Kade

@Kade It does, thanks! I was looking at the Python answer which uses the same technique at the same moment you linked that :D I can get even shorter with C# 6.
Yytsi


3

C, 53

v(char*s){int v=0,c;while(c=*s++)v+=v+c-48;return v;}

Same as my javascript answer

Test Ideone


You can save 4 bytes by declaring v and c as global variables (though you need to change the name of v, since it's already the name of the function) like this: w=0;c;v(char*s){while(c=*s++)w+=w+c-48;return w;}
Steadybox

@Steadybox it could be w,c; but I don't want use globals when the answer is a function (even in code-golf)
edc65

@Steadybox Globals defaults to 0 as well, so you can drop the =0.
algmyr

3

Perl, 25 bytes

-3 bytes thanks to @Dom Hastings.

24 bytes of code + 1 byte for -p flag.

$\|=$&<<$v++while s/.$//

To run it:

perl -pe '$\|=$&<<$v++while s/.$//' <<< 101010

Explanations:

$\|=$&<<$v++  # Note that: we use $\ to store the result
              # at first $v=0, and each time it's incremented by one
              # $& contains the current bit (matched with the regex, see bellow)
              # So this operation sets a $v-th bit of $\ to the value of the $v-th bit of the input
while         # keep doing this while...
s/.$//        #  ... there is a character at the end of the string, which we remove.
         # $\ is implicitly printed thanks to -p flag

3

Pushy, 10 bytes

Takes input as a list of 0/1 on the command line: $ pushy binary.pshy 1,0,1,0,1,0.

L:vK2*;OS#

The algorithm really shows the beauty of having a second stack:

            \ Implicit: Input on stack
L:    ;     \ len(input) times do:
  v         \   Push last number to auxiliary stack
   K2*      \   Double all items
       OS#  \ Output sum of auxiliary stack

This method works because the stack will be doubled stack length - n times before reaching number n, which is then dumped into the second stack for later. Here's what the process looks like for input 101010:

1: [1,0,1,0,1,0]
2: []

1: [2,0,2,0,2]
2: [0]

1: [4,0,4,0]
2: [2]

1: [8,0,8]
2: [2,0]

1: [16,0]
2: [2,0,8]

1: [32]
2: [2,0,8,0]

1: []
2: [2,0,8,0,32]

2 + 8 + 32 -> 42

3

Matlab, 30 Bytes

@(x)sum(2.^find(flip(x)-48)/2)

The last test case has rounding errors (because of double), so if you need full precision:

@(x)sum(2.^uint64(find(flip(x)-48))/2,'native')

with 47 Bytes.


I can't test this, but I believe @(x)sum(2.^(find(flip(x)-48)-1)) will give the correct result for all cases for 32 bytes. flip works like fliplr if x is one dimensional.
Stewie Griffin

Nice solution! I also ran into the rounding error, thanks for the fix. What is the format of x? Calling flip or fliplr on a number just returns that number.
MattWH

x is the binary string, so call it with f=@(x)..; f('1111001010').
Jonas

3

Retina, 12 bytes

Byte count assumes ISO 8859-1 encoding.

+%`\B
¶$`:
1

Try it online!

Alternative solution:

+1`\B
:$`:
1

Explanation

This will probably be easier to explain based on my old, less golfed, version and then showing how I shortened it. I used to convert binary to decimal like this:

^
,
+`,(.)
$`$1,
1

The only sensible way to construct a decimal number in Retina is by counting things (because Retina has a couple of features that let it print a decimal number representing an amount). So really the only possible approach is to convert the binary to unary, and then to count the number of unary digits. The last line does the counting, so the first four convert binary to unary.

How do we do that? In general, to convert from a list of bits to an integer, we initialise the result to 0 and then go through the bits from most to least significant, double the value we already have and add the current bit. E.g. if the binary number is 1011, we'd really compute:

(((0 * 2 + 1) * 2 + 0) * 2 + 1) * 2 + 1 = 11
           ^        ^        ^        ^

Where I've marked the individual bits for clarity.

The trick to doing this in unary is a) that doubling simply means repeating the number and b) since we're counting the 1s at the end, we don't even need to distinguish between 0s and 1s in the process. This will become clearer in a second.

What the program does is that it first adds a comma to the beginning as marker for how much of the input we've already processed:

^
,

Left of the marker, we'll have the value we're accumulating (which is correctly initialised to the unary representation of zero), and right of the value will be the next bit to process. Now we apply the following substitution in a loop:

,(.)
$`$1,

Just looking at ,(.) and $1,, this moves the marker one bit to the right each time. But we also insert $`, which is everything in front of the marker, i.e. the current value, which we're doubling. Here are the individual steps when processing input 1011, where I've marked the result of inserting $` above each line (it's empty for the first step):

,1011

1,011
 _
110,11
   ___
1101101,1
       _______
110110111011011,

You'll see that we've retained and doubled the zero along with everything else, but since we're disregarding them at the end, it doesn't matter how often we've doubled them, as long as the number of 1s is correct. If you count them, there are 11 of them, just what we need.

So that leaves the question of how to golf this down to 12 bytes. The most expensive part of the 18-byte version is having to use the marker. The goal is to get rid of that. We really want to double the prefix of every bit, so a first idea might be this:

.
$`$&

The problem is that these substitutions happen simultaneously, so first bit doesn't get doubled for each bit, but it just gets copied once each time. For input 1011 we'd get (marking the inserted $`):

 _ __ ___
1101011011

We do still need to process the input recursively so that the doubled first prefix is doubled again by the second and so on. One idea is to insert markers everywhere and repeatedly replace them with the prefix:

\B
,
+%`,
¶$`

After replacing each marker with the prefix for the first time, we need to remember where the beginning of the input was, so we insert linefeeds as well and use the % option to make sure that the next $` only picks up things up the closest linefeed.

This does work, but it's still too long (16 bytes when counting 1s at the end). How about we turn things around? The places where we want to insert markers are identified by \B (a position between two digits). Why don't we simply insert prefixes into those positions? This almost works, but the difference is that in the previous solution, we actually removed one marker in each substitution, and that's important to make the process terminate. However, the \B aren't character but just positions, so nothing gets removed. We can however stop the \B from matching by instead inserting a non-digit character into this place. That turns the non-word boundary into a word boundary, which is the equivalent of removing the marker character earlier. And that's what the 12-byte solution does:

+%`\B
¶$`:

Just for completeness, here are the individual steps of processing 1011, with an empty line after each step:

1
1:0
10:1
101:1

1
1:0
1
1:0:1
1
1:0
10:1:1

1
1:0
1
1:0:1
1
1:0
1
1:0:1:1

Again, you'll find that the last result contains exactly 11 1s.

As an exercise for the reader, can you see how this generalises quite easily to other bases (for a few additional bytes per increment in the base)?


2

T-SQL, 202 Bytes

DECLARE @b varchar(max)='1',@ int=1 declare @l int=LEN(@b)declare @o bigint=CAST(SUBSTRING(@b,@l,1)AS bigint)WHILE @<@l BEGIN SET @o=@o+POWER(CAST(SUBSTRING(@b,@l-@,1)*2AS bigint),@)SET @=@+1 END PRINT @o

2

PHP, 64 bytes

foreach(str_split(strrev($argv[1]))as$k=>$v)$t+=$v*2**$k;echo$t;

We reverse our binary number, split it into its component digits, and sum them based on position.


2

Bash + GNU utilities, 29 bytes

sed 's/./2*&+/g;s/.*/K&p/'|dc

I/O via stdin/stdout.

The sed expression splits the binary up into each digit and builds a RPN expression for dc to evaluate.


2

PowerShell v2+, 55 bytes

param($n)$j=1;$n[$n.length..0]|%{$i+=+"$_"*$j;$j*=2};$i

Feels too long ... Can't seem to golf it down any -- tips appreciated.

Explanation

param($n)$j=1;$n[$n.length..0]|%{$i+=+"$_"*$j;$j*=2};$i
param($n)$j=1;                                          # Take input $n as string, set $j=1
              $n[$n.length..0]                          # Reverses, also converts to char-array
                              |%{                  };   # Loop over that array
                                 $i+=+"$_"*$j;          # Increment by current value of $j times current digit
                                              $j*=2     # Increase $j for next loop iteration
                                                     $i # Leave $i on pipeline
                                                        # Implicit output

2

JavaScript (ES6), 32 bytes

f=([...n])=>n+n&&+n.pop()+2*f(n)

Recursion saves the day again! Though the parameterization seems a little long...


Since it's a single "argument", does [...n] need to be surrounded in parentheses?
Cyoce

@Cyoce Unfortunately, yes, or JS throws a SyntaxError.
ETHproductions

2

Mathematica, 27 13 11 bytes

Fold[#+##&]

Accepts a List of bits as input (e.g. {1, 0, 1, 1, 0} -- Mathematica's binary representation of the number 22)


Following up from the comment on Greg's answer, how is "splitting all the digits in the input" not a base conversion function?
Martin Ender

@MartinEnder I'm using it like the Characters function.
JungHwan Min

@MartinEnder Actually, as seen in @nimi's answer, I could just accept a list of 1s and 0s because that is the only way to represent a binary number in Mathematica, meaning I don't need IntegerDigits in the first place.
JungHwan Min

That assumes that base 10 is the "natural" representation of an integer. An actual integer value has no preferred base attached to it (I guess you could say the way it's stored is probably base 256 or maybe even base 2 but that's an implementation detail). Just because we (normally) use base 10 to write integer literals there doesn't mean integer values are already in base 10.
Martin Ender

@MartinEnder @Lynn's Jelly code uses D, which does the same thing as IntegerDigits
JungHwan Min

2

Clojure, 114 105 63 41 bytes

V4: 41 bytes

-22 bytes thanks to @cliffroot. Since digit is a character, it can be converted to it's code via int, then have 48 subtracted from it to get the actual number. The map was also factored out. I don't know why it seemed necessary.

#(reduce(fn[a d](+(* a 2)(-(int d)48)))%)

V3: 63 bytes

(fn[s](reduce #(+(* %1 2)%2)(map #(Integer/parseInt(str %))s)))

-42 bytes (!) by peeking at other answers. My "zipping" was evidently very naïve. Instead of raising 2 to the current place's power, then multiplying it by the current digit and adding the result to the accumulator, it just multiplies the accumulator by 2, adds on the current digit, then adds it to the accumulator. Also converted the reducing function to a macro to shave off a bit.

Thanks to @nimi, and @Adnan!

Ungolfed:

(defn to-dec [binary-str]
  (reduce (fn [acc digit]
            (+ (* acc 2) digit))
          (map #(Integer/parseInt (str %)) binary-str)))

V2: 105 bytes

#(reduce(fn[a[p d]](+ a(*(Integer/parseInt(str d))(long(Math/pow 2 p)))))0(map vector(range)(reverse %)))

-9 bytes by reversing the string so I don't need to create an awkward descending range.

V1: 114 bytes

Well, I'm certainly not winning! In my defense, this is the first program I've ever written that converts between bases, so I had to learn how to do it. It also doesn't help that Math/pow returns a double that requires converting from, and Integer/parseInt doesn't accept a character, so the digit needs to be wrapped prior to passing.

#(reduce(fn[a[p d]](+ a(*(Integer/parseInt(str d))(long(Math/pow 2 p)))))0(map vector(range(dec(count %))-1 -1)%))

Zips the string with a descending index representing the place number. Reduces over the resulting list.

Ungolfed:

(defn to-dec [binary-str]
  (reduce (fn [acc [place digit]]
            (let [parsed-digit (Integer/parseInt (str digit))
                  place-value (long (Math/pow 2 place))]
              (+ acc (* parsed-digit place-value))))
          0
          (map vector (range (dec (count binary-str)) -1 -1) binary-str)))

#(reduce(fn[a b](+(* a 2)(-(int b)48)))0 %) improved version. Moved map part of code directly into reduce, changed integer parsing method, make external function with shorthand lambda syntax.
cliffroot

@cliffroot int can be used to parse!? That'll knock off like 10 bytes in every challenge I've done here lol.
Carcigenicate

Oh, I see what you're doing. Taking the ascii code, then subtracting to get the value. I guess this would only work in select circumstances only. Oh well, thanks for the tip.
Carcigenicate

2

Perl, 21 19 16 + 4 = 20 bytes

-4 bytes thanks to @Dada

Run with -F -p (including the extra space after the F). Pipe values to the function using echo -n

$\+=$_+$\for@F}{

Run as echo -n "101010" | perl -F -pE '$\+=$_+$\for@F}{'

I feel this is sufficiently different from @Dada's answer that it merits its own entry.

Explanation:

-F                              #Splits the input character by character into the @F array
-p                              #Wraps the entire program in while(<>){ ... print} turning it into
while(<>){$\+=$_+$\for@F}{print}
                   for@F        #Loops through the @F array in order ($_ as alias), and...
          $\+=$_+$\             #...doubles $\, and then adds $_ to it (0 or 1)...
while(<>){              }       #...as long as there is input.
                         {print}#Prints the contents of $_ (empty outside of its scope), followed by the output record separator $\

This uses my personal algorithm of choice for binary-to-decimal conversion. Given a binary number, start your accumulator at 0, and go through its bits one by one. Double the accumulator each bit, then add the bit itself to your accumulator, and you end up with the decimal value. It works because each bit ends up being doubled the appropriate number of times for its position based on how many more bits are left in the original binary number.


Even shorter : perl -F -pE '$\+=$_+$\for@F}{'
Dada

I honestly laughed at how short this is now. Thank you.
Gabriel Benamy

Yea, it's pretty neat, well done!
Dada

2

R (32-bit), 64 Bytes

Input for the function should be given as character. The base functions of R support 32-bit integers.

Input:

# 32-bit version (base)
f=function(x)sum(as.double(el(strsplit(x,"")))*2^(nchar(x):1-1))
f("1")
f("10")
f("101010")
f("1101111111010101100101110111001110001000110100110011100000111")

Output:

> f("1")
[1] 1
> f("10")
[1] 2
> f("101010")
[1] 42
> f("1101111111010101100101110111001110001000110100110011100000111")
[1] 2.016121e+18

R (64-bit), 74 Bytes

Input for the function should be given as character. The package bit64 has to be used for 64-bit integers.

Input:

# 64-bit version (bit64)
g=function(x)sum(bit64::as.integer64(el(strsplit(x,"")))*2^(nchar(x):1-1))
g("1")
g("10")
g("101010")
g("1101111111010101100101110111001110001000110100110011100000111")

Output:

> g("1")
integer64
[1] 1
> g("10")
integer64
[1] 2
> g("101010")
integer64
[1] 42
> g("1101111111010101100101110111001110001000110100110011100000111")
integer64
[1] 2016120520371234567

2
You can do: el(strsplit(x,"")) instead of strsplit(x,split="")[[1]] to save a couple of bytes.
Billywob

Thanks a lot! Especially for the el function - I was not aware of it.
djhurio

2

Dyalog APL, 12 bytes

(++⊢)/⌽⍎¨⍞

get string input

⍎¨ convert each character to number

reverse

(...)/ insert the following function between the numbers

++⊢ the sum of the arguments plus the right argument


ngn shaved 2 bytes.


1

k, 8 bytes

Same method as the Haskell answer above.

{y+2*x}/

Example:

{y+2*x}/1101111111010101100101110111001110001000110100110011100000111b
2016120520371234567
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.