Conversor de binário para decimal
Tanto quanto posso ver, não temos um desafio simples de conversão de binário para decimal.
Escreva um programa ou função que pega um número inteiro binário positivo e gera seu valor decimal.
Você não tem permissão para usar nenhuma função de conversão básica embutida. Funções de número inteiro para decimal (por exemplo, uma função que se transforma 101010
em [1, 0, 1, 0, 1, 0]
ou "101010"
) são isentas desta regra e, portanto, são permitidas.
Regras:
- O código deve suportar números binários até o valor numérico mais alto suportado pelo seu idioma (por padrão)
- Você pode optar por ter zeros à esquerda na representação binária
- A saída decimal pode não ter zeros à esquerda.
- Os formatos de entrada e saída são opcionais, mas não pode haver separadores entre dígitos.
(1,0,1,0,1,0,1,0)
não é um formato de entrada válido, mas ambos10101010
e(["10101010"])
são.- Você deve pegar a entrada na direção "normal". não
1110
é .14
7
- Você deve pegar a entrada na direção "normal". não
Casos de teste:
1
1
10
2
101010
42
1101111111010101100101110111001110001000110100110011100000111
2016120520371234567
Este desafio está relacionado com alguns outros desafios, por exemplo este , este e este .
code-golf
base-conversion
binary
Stewie Griffin
fonte
fonte
-1
(32 1's
e64 1's
)round(x)==x
você esteja bem :)2.000
é aceito como saída10
.Respostas:
Gelatina , 5 bytes
Experimente online!
Explicação
O elenco
D
é uma mônada (função de argumento único): dígitos, transformando1234
- se em[1, 2, 3, 4]
.Ḥ
é uma mônada que dobra seu único argumento.+
é uma díade (função de dois argumentos) que adiciona seus argumentos esquerdo e direito.A partir daí, fica um pouco complicado.
Aqui está o que acontece no momento da análise
D
,,Ḥ
e+
são lidos. A corrente parece[D, Ḥ, +]
.Os próximos dois caracteres são rápidos , que agem como operadores de postfix de tempo de análise nos links (funções) que lemos até agora.
Quando
¥
é lido, os dois últimos links são exibidos e substituídos por um link que age como a díade formada pela composição deles. Então agora a cadeia parece[D, dyad(Ḥ+)]
.Quando
/
é lido, o último link (que deveria ser uma díade) é exibido e substituído por uma mônada que dobra usando essa díade (intuitivamente:f/
pega uma lista, substitui as vírgulas nelaf
e avalia o resultado).A cadeia final parece
[D, fold(dyad(Ḥ+))]
duas mônadas.Aqui está o que acontece em tempo de execução
A entrada (um número) é implicitamente lida no valor de trabalho (digamos
101010
).D
é executado, substituindo o valor de trabalho por seus dígitos ([1,0,1,0,1,0]
).fold(dyad(Ḥ+))
é executado, substituindo o valor de trabalho por1∗0∗1∗0∗1∗0
, onde∗
está a díadeḤ+
.Então, o que
x∗y
avaliar para?Em uma definição diádica, o valor de trabalho é inicialmente o argumento esquerdo
x
,.Ḥ
, a mônada dupla , dobra esse valor. O valor de trabalho é agora2x
.+
, a díade mais , carece de um argumento correto, então isso é um gancho : um padrão sintático especial em que o argumento correto dessa díade é injetado+
. Isso gera2x + y
como o valor final de trabalho, que é retornado.Portanto, toda a expressão é avaliada como:
fonte
Python 2,
49373130 bytesAgora, isso terá um número binário em uma representação decimal, pois o Python pode lidar com números inteiros arbitrariamente grandes.
graças ao xnor por salvar um byte :)
A maneira mais fácil de ver como isso funciona é ver uma fórmula básica para converter binário em decimal:
Esta é uma maneira 'padrão' de converter. Você pode expandir a terceira linha da seguinte maneira:
E é essencialmente isso que o método recursivo que eu fiz está fazendo.
Soluções alternativas que tive:
fonte
n%5
ou emn%2
vez den%10
.05AB1E , 6 bytes
Código:
Para a explicação, vamos dar o exemplo 101010 . Começamos com o número 1 (que é representado pelo primeiro dígito). Depois disso, temos dois casos:
Portanto, para o caso 101010 , o seguinte é calculado:
Explicação do código:
Usa a codificação CP-1252 . Experimente online!
fonte
Haskell,
16111 + 57 = 168 bytes+57 bytes para os sinalizadores de compilação
-XOverloadedStrings
,-XOverlappingInstances
e-XFlexibleInstances
.O desafio tem um formato de E / S complicado , porque depende muito de como os tipos de dados são expressos no código-fonte. Minha primeira versão (16 bytes), a saber
pega uma lista de números inteiros, por exemplo,
[1,0,1,0,1,0]
e foi declarada inválida porque as listas literais de Haskell têm,
entre os elementos. Listas em si não são proibidas. Na minha nova versão, uso a mesma função, agora chamadaf
, mas sobrecarrego "Citar sequências de caracteres incluídas". A função ainda pega uma lista de números inteiros, como você pode ver na anotação de tipo[Int] -> Int
, mas as listas com números inteiros de um dígito agora podem ser escritas como"1234"
, por exemplo,que avalia como
42
. Haskell azarado, porque o formato da lista nativa não se encaixa nas regras de desafio. Btw,f [1,0,1,0,1,0]
ainda funciona.fonte
(1,0,1,0,1,0,1,0)
não é um formato de entrada válido, mas ambos10101010
e(["10101010"])
são". além disso, um comentário sugere que a matriz de caracteres é aceitável se é assim que uma entrada de string é interpretada.10101010
,"10101010"
ou algo semelhante e fazê-lo funcionar, o envio é válido. Você pode chamá-lo de uma string, lista, número inteiro ou o que seja. Introduzir[1][0][1][0]
ou[1,0,1,0]
não está bem. Basicamente, deve ser possível apenas acertar vários zeros e zeros em algum lugar. Isso está claro?Retina, 15 bytes
Converte de binário em unário e unário em decimal.
Experimente online
fonte
PHP, 44 bytes
Eu poderia jurar que já vi essa pergunta antes. Mas, bem.
Lê o número da esquerda para a direita, muda para a esquerda e adiciona o bit atual.
fonte
JavaScript (ES6),
3331 bytesEdit: Mais curto, mas menos doce: 2 bytes salvos graças a @ETHproductions.
fonte
.map
é mais curto:s=>[...s].map(c=>+c+r+r,r=0)|r
s=>[...s].map(c=>r+=+c+r,r=0)|r
Labirinto ,
1715 bytesExperimente online!
Labirinto é uma linguagem bidimensional baseada em pilha. No labirinto, a execução do código segue o caminho do código como um labirinto, com espaços atuando como paredes e começando no caractere não espacial do canto superior esquerdo. O fluxo do código é determinado pelo sinal da parte superior da pilha. Como a pilha possui zeros implícitos na parte inferior, as quatro primeiras instruções (
-+:+
) não têm efeito.Loop começando no
,
,
Empurre o valor do código ascii do próximo caractere de entrada até a parada da pilha ou empurre -1 se EOF._48
empurra 48 para o topo da pilha-
Pop y, pop x, empurrex-y
. As instruções anteriores têm o efeito de subtrair 48 da entrada produzindo 0 para "0" e 1 para "1".+
Pop y, pop x, empurrex+y
.:
Duplique a parte superior da pilha+
Esta e a instrução anterior têm o efeito de multiplicar o valor atual por 2Portanto, a parte circular do código, na verdade, multiplica o número atual por 2 e adiciona 1 ou 0, dependendo se o caractere 1 ou 0 foi inserido.
Rabo
Se a parte superior da pilha for negativa (significando que o EOF foi encontrado), o código vira à esquerda no cruzamento (indo em direção ao ponto e vírgula).
)
Icrementar o topo da pilha para obter 2/
Pop y, pop x, pressione x / y (divisão inteira). Isso tem o efeito de desfazer o último*2
do loop.!
Saída a representação inteira da parte superior da pilha. Nesse ponto, o programa muda porque atinge um beco sem saída e sai com um erro porque tenta dividir por zero.Agradeço a @Martin Ender por me salvar 2 bytes (e por me ensinar a pensar melhor em Labyrinth).
fonte
_48-
você pode simplesmente fazer,#%
mas infelizmente não vejo como isso pode ajudar na contagem de bytes.`)
vez de no;_2
entanto.#%
. Você pode explicar como isso funciona como um substituto para_48-
converter de ascii para int. Obrigado pela)
dica. Eu vou fazer essa mudança.#
é apenas uma abreviação de_2
. Embora_2%
não seja um método geral de conversão de ASCII para inteiro, ele funciona aqui porque você está interessado apenas nos dois primeiros dígitos como entrada possível. Uma alternativa seria_1&
(já que o módulo 2 simplesmente extrai o bit menos significativo).#%
) para reduzir o código em geral.Flak cerebral ,
46, 28 bytesExperimente online!
Muitos bytes salvos graças ao @Riley!
Como a quebra cerebral não pode receber entrada binária, a entrada é uma lista de '0' e '1'.
Explicação:
fonte
([]){({}[()]<({}<>({}){})><>)}<>
([]){{}({}<>({}){})<>([])}<>
Java,
84794648 bytesAlterado para
long
/ 48 bytes:Jogou golfe / 46 bytes:
Graças a @ Geobits! / 79 bytes:
84 bytes:
fonte
s
deveria serchar[]
. Espero que isso seja permitido ...Befunge-98, 12 bytes
Experimente online!
Lê um caractere de cada vez da entrada, converte-o para 0 ou 1 assumindo seu valor módulo 2 (0 é char (48), 1 é char (49)) e, em seguida, usa o algoritmo usual de duplicar o valor atual e adicionar o valor novo dígito de cada vez.
Bônus: Isso funciona com qualquer tipo de string de entrada. Estou tentando há algum tempo encontrar alguma combinação engraçada de entrada-> saída, mas não consegui produzir nada (infelizmente, "resposta" = 46). Você pode?
fonte
Javascript (ES7)
414036 bytespega uma string como entrada
Raspou um byte graças à ETHproductions
fonte
**
é estranha, mas é um bom trabalho usá-la aqui.1<<b.length
faria a mesma coisa, mas exigiria parênteses para não ser analisado como(c*1)<<(b.length+...)
. Eu acho que você pode salvar um byte substituindob[0]
porb+b
( veja aqui ).C # 6,
853736 bytesfonte
05AB1E , 7 bytes
Experimente online!
Explicação
fonte
C, 53
Igual à minha resposta javascript
Ideona de teste
fonte
v
ec
como variáveis globais (embora seja necessário alterar o nome dev
, já que ele já é o nome da função) assim:w=0;c;v(char*s){while(c=*s++)w+=w+c-48;return w;}
w,c;
, mas eu não quero usar globais quando a resposta é uma função (mesmo em código-golf)=0
.Perl, 25 bytes
-3 bytes graças a @Dom Hastings.
24 bytes de código + 1 byte para
-p
sinalizador.Para executá-lo:
Explicações:
fonte
Pushy , 10 bytes
Toma entrada como uma lista de 0/1 na linha de comando:
$ pushy binary.pshy 1,0,1,0,1,0
.O algoritmo realmente mostra a beleza de ter uma segunda pilha:
Esse método funciona porque a pilha será duplicada
stack length - n
vezes antes de atingir o númeron
, que é despejado na segunda pilha para mais tarde. Aqui está a aparência do processo para entrada101010
:fonte
Matlab, 30 bytes
O último caso de teste possui erros de arredondamento (por causa de
double
), portanto, se você precisar de precisão total:com 47 bytes.
fonte
@(x)sum(2.^(find(flip(x)-48)-1))
que dará o resultado correto para todos os casos por 32 bytes.flip
funciona comofliplr
sex
é unidimensional.f=@(x)..; f('1111001010')
.Retina , 12 bytes
A contagem de bytes assume a codificação ISO 8859-1.
Experimente online!
Solução alternativa:
Explicação
Provavelmente será mais fácil explicar isso com base na minha versão antiga, menos golfe, e depois mostrar como a reduzi. Eu costumava converter binário em decimal como este:
A única maneira sensata de construir um número decimal no Retina é contando as coisas (porque o Retina possui alguns recursos que permitem imprimir um número decimal representando um valor). Então, realmente, a única abordagem possível é converter o binário em unário e, em seguida, contar o número de dígitos unários. A última linha faz a contagem; portanto, os quatro primeiros convertem o binário em unário.
Como fazemos isso? Em geral, para converter de uma lista de bits em um número inteiro, inicializamos o resultado
0
e depois passamos pelos bits do mais para o menos significativo, o dobro do valor que já temos e adicionamos o bit atual. Por exemplo, se o número binário for1011
, calcularíamos realmente:Onde marquei os bits individuais para maior clareza.
O truque para fazer isso em unário é a) que dobrar significa repetir o número eb) já que estamos contando os
1
s no final, nem precisamos distinguir0
s e1
s no processo. Isso ficará mais claro em um segundo.O que o programa faz é adicionar primeiro uma vírgula no início como marcador de quanto da entrada já processamos:
À esquerda do marcador, teremos o valor que estamos acumulando (que foi corretamente inicializado para a representação unária de zero) e à direita do valor será o próximo bit a ser processado. Agora aplicamos a seguinte substituição em um loop:
Apenas olhando
,(.)
e$1,
, isso move o marcador um pouco para a direita a cada vez. Mas também inserimos$`
, que é tudo à frente do marcador, ou seja, o valor atual, que estamos dobrando. Aqui estão as etapas individuais ao processar a entrada1011
, onde eu marquei o resultado da inserção$`
acima de cada linha (ela está vazia na primeira etapa):Você verá que retivemos e dobramos o zero junto com todo o resto, mas, como os desconsideramos no final, não importa com que frequência os duplicamos, desde que o número de
1
s seja corrigir. Se você os contar, existem11
, exatamente o que precisamos.Portanto, isso deixa a questão de como jogar isso em golfe até 12 bytes. A parte mais cara da versão de 18 bytes é usar o marcador. O objetivo é se livrar disso. Nós realmente queremos dobrar o prefixo de cada bit, então uma primeira idéia pode ser a seguinte:
O problema é que essas substituições ocorrem simultaneamente, portanto, o primeiro bit não é duplicado para cada bit, mas é copiado uma vez de cada vez. Para entrada
1011
, obteríamos (marcando o inserido$`
):Ainda precisamos processar a entrada recursivamente para que o primeiro prefixo duplicado seja duplicado novamente pelo segundo e assim por diante. Uma idéia é inserir marcadores em todos os lugares e substituí-los repetidamente pelo prefixo:
Depois de substituir cada marcador pelo prefixo pela primeira vez, precisamos lembrar onde estava o início da entrada; portanto, inserimos feeds de linha também e usamos a
%
opção para garantir que o próximo$`
aponte apenas o feed de linha mais próximo.Isso funciona, mas ainda é muito longo (16 bytes ao contar
1
s no final). Que tal mudar as coisas? Os locais onde queremos inserir marcadores são identificados por\B
(uma posição entre dois dígitos). Por que simplesmente não inserimos prefixos nessas posições? Isso quase funciona, mas a diferença é que, na solução anterior, removemos um marcador em cada substituição, e isso é importante para encerrar o processo. No entanto, o\B
personagem não é apenas uma posição, então nada é removido. No entanto, podemos parar o\B
da correspondência inserindo um caractere não dígito neste local. Isso transforma o limite de não palavra em um limite de palavra, o que equivale a remover o caractere marcador anteriormente. E é isso que a solução de 12 bytes faz:Apenas para completar, aqui estão as etapas individuais do processamento
1011
, com uma linha vazia após cada etapa:Novamente, você verá que o último resultado contém exatamente 11
1
s.Como um exercício para o leitor, você pode ver como isso se generaliza facilmente para outras bases (por alguns bytes adicionais por incremento na base)?
fonte
T-SQL, 202 bytes
fonte
PHP, 64 bytes
Invertemos nosso número binário, dividimos em seus dígitos componentes e os somamos com base na posição.
fonte
Utilitários Bash + GNU, 29 bytes
E / S via stdin / stdout.
A
sed
expressão divide o binário em cada dígito e cria uma expressão RPN paradc
avaliação.fonte
PowerShell v2 +, 55 bytes
Parece muito tempo ...Não consigo jogar golfe - dicas apreciadas.Explicação
fonte
JavaScript (ES6), 32 bytes
A recursão salva o dia novamente! Embora a parametrização pareça um pouco longa ...
fonte
[...n]
precisa estar entre parênteses?Mathematica,
271311 bytesAceita um
List
de bits como entrada (por exemplo{1, 0, 1, 1, 0}
- representação binária do número do Mathematica22
)fonte
Characters
função.IntegerDigits
em primeiro lugar.D
, o que faz a mesma coisa que:IntegerDigits
Clojure,
1141056341 bytesV4: 41 bytes
-22 bytes graças a @cliffroot. Como
digit
é um caractere, ele pode ser convertido em seu código via eint
, em seguida, 48 são subtraídos para obter o número real. O mapa também foi fatorado. Não sei por que parecia necessário.V3: 63 bytes
-42 bytes (!) Espiando outras respostas. Meu "fechamento" era evidentemente muito ingênuo. Em vez de elevar 2 à potência do local atual, multiplicando-o pelo dígito atual e adicionando o resultado ao acumulador, ele apenas multiplica o acumulador por 2, adiciona o dígito atual e o adiciona ao acumulador. Também converteu a função de redução em uma macro para se barbear um pouco.
Obrigado a @nimi e @Adnan!
Ungolfed:
V2: 105 bytes
-9 bytes, invertendo a string para que eu não precise criar um intervalo descendente estranho.
V1: 114 bytes
Bem, certamente não estou ganhando! Em minha defesa, este é o primeiro programa que eu já escrevi que se converte entre bases, então eu tive que aprender como fazê-lo. Também não ajuda que
Math/pow
retorne um dobro que exija a conversão de eInteger/parseInt
não aceite um caractere; portanto, o dígito precisa ser quebrado antes da passagem.Fecha a string com um índice decrescente que representa o número do local. Reduz sobre a lista resultante.
Ungolfed:
fonte
#(reduce(fn[a b](+(* a 2)(-(int b)48)))0 %)
versão melhorada. Moveumap
parte do código diretamente parareduce
, alterou o método de análise de números inteiros, criou funções externas com sintaxe abreviada de lambda.int
pode ser usado para analisar !? Isso vai bater 10 bytes em todos os desafios que eu fiz aqui, rs.Perl,
211916 + 4 = 20 bytes-4 bytes graças a @Dada
Corra com
-F -p
(incluindo o espaço extra após oF
). Conduza os valores para a função usandoecho -n
Correr como
echo -n "101010" | perl -F -pE '$\+=$_+$\for@F}{'
Eu sinto que isso é suficientemente diferente da resposta da @ Dadá que merece sua própria entrada.
Explicação:
Isso usa meu algoritmo pessoal de escolha para conversão de binário em decimal. Dado um número binário, inicie seu acumulador em 0 e repare os bits um a um. Dobre o acumulador a cada bit, adicione o próprio bit ao acumulador e você terá o valor decimal. Funciona porque cada bit acaba dobrando o número apropriado de vezes para sua posição, com base em quantos bits restam no número binário original.
fonte
perl -F -pE '$\+=$_+$\for@F}{'
R (32 bits), 64 bytes
A entrada para a função deve ser fornecida como caractere. As funções básicas do R suportam números inteiros de 32 bits.
Entrada:
Saída:
R (64 bits), 74 bytes
A entrada para a função deve ser fornecida como caractere. O pacote
bit64
deve ser usado para números inteiros de 64 bits.Entrada:
Saída:
fonte
el(strsplit(x,""))
vez destrsplit(x,split="")[[1]]
salvar alguns bytes.el
função - eu não estava ciente disso.Dyalog APL , 12 bytes
⍞
obter entrada de string⍎¨
converter cada caractere em número⌽
marcha ré(
...)/
insira a seguinte função entre os números++⊢
a soma dos argumentos mais o argumento certongn raspou 2 bytes.
fonte
k, 8 bytes
O mesmo método da resposta de Haskell acima.
Exemplo:
fonte