Converter da base 10 para a base 2 sem conversões básicas incorporadas


16

Antecedentes :

Você recebeu uma atribuição para converter números da base 10 em base 2 sem usar nenhuma função de conversão de base pré-fabricada. Você também não pode usar nenhuma biblioteca importada.

problema :

Converta uma sequência de entrada da base 10 (decimal) para a base 2 (binária). Você não pode usar nenhum código / função / conversão de base pré-fabricado ou bibliotecas importadas. Como esse é o , a resposta mais curta em bytes será vencedora.

A entrada será algo entre -32768 e 32767 (inclua manipulação de byte de sinal no seu código)


3
P: o que significa "manipulação de bytes de sinal" significa - devo gerar "-xxxx" para um número negativo? Então alguns de nós estão errados, incl. me, como eu de saída "11 ... 11" para -1 (aka como não assinado)
blabla999

Manipulação de sinal byte - o MSB de controles variáveis assinados se eles são negativos
TheDoctor

11
claro, mas eu tenho que> imprimi-los como sinal '-' seguido de magnitude?
blabla999

@ blabla999 - Não, você não #
TheDoctor

3
the MSB of signed variables controls if they are negative- isso soa como bit de sinal; no entanto, como o intervalo -32768..32767sugere, você deseja o complemento de 2. Assim que você quer ..?
mniip

Respostas:


4

GolfScript - 17 bytes

~{.1&\2/}16*;]-1%

Não é muito mais detalhado do que o incorporado ~2base.


11
Eu não sei golfscript mas uma amostra de algumas corridas levam-me a concluir que você deve remover o~
user12205

@ace Como a entrada inicial é uma string "37", por exemplo, a operação "37" & 1(em infixo) é uma operação em conjunto. O ~na frente converte a entrada em um número inteiro.
primo

Fiz o meu teste aqui golfscript.apphb.com/… isso significa que este intérprete está incorreto? (Desculpe, eu realmente não sei nada sobre golfe)
user12205

2
O intérprete está correto; porque você colocou o valor inteiro 10na pilha, não é necessário avaliá-lo. No entanto, quando lida stdin, a entrada será uma string ( teste aqui ). A descrição do problema também afirma explicitamente que a entrada é uma sequência.
primo

12

JavaScript, 46

for(x=prompt(o='');x;x>>>=1)o=(x&1)+o;alert(o)

Lol, eu nem sabia que >>>=existia um operador de 4 caracteres ( )! +1 (Além disso, se você o executar no console, poderá salvar os últimos 9 caracteres.)
Maçaneta da porta

11
Não tem 4 caracteres, são dois operadores: o >>> é o deslocamento para a direita bit a bit de preenchimento 0, seguido por uma atribuição. Tente: x=8; x>>>=1; x;e x=8; x>>>1; x;- no primeiro caso, o valor de x mudou; no segundo, não tem.
Graham Charles

3
@GrahamCharles >>>=é um único operador .
primo

Bem, olha isso! Obrigado, @primo ... você aprende algo todos os dias!
Graham Charles

2
@ComFreek Isso reverteria a ordem dos dígitos
copie

4

Brainf * ck, 98 77

Obviamente, isso não tem o objetivo de vencer, mas o que seria uma competição se não tivesse uma solução brainfk

++++[>++++<-]>>,<[->>++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]++++++[->++++++++<]>.[-]>[-<<<+>>>]<<<<]

Como brainfk só pode lidar com números inteiros de 8 bits e sem negativos, acho que não cumpre totalmente as regras, mas ei, eu nunca estive nele para vencê-lo.

Na verdade, isso funciona para entrada de 16 bits se o seu intérprete suportar

Eu até consegui produzir valores ASCII

Aqui está o código anotado:

++[>++++<-]                       preload 8 onto cell 1
>>,<                                input into cell 2
[-                                  iterate over cell 1
    >>++<                               put 2 in cell 3
    [->-[>+>>]>[+[-<+>]>+>>]<<<<<]      division algorithm: converts {n d} into {0 d_minus_n%d n%d n/d}
    >[-]++++++[->++++++++<]>           clears cell 4 and puts 48(ascii of 0) into cell 5
    .[-]                                output n%2 and clear it (the bit)
    >[-<<<+>>>]                         bring n/2 into cell 2 (to be used for division in next iteration)
<<<<]                               end iterate

Algoritmo mais curto (77):

+>,>-<[>>[->]++[-<+]-<-]++++++++[->++++++<]>+[->+>+>+>+>+>+>+>+<<<<<<<<]>[.>]

Este pode lidar apenas com números inteiros de 8 bits.

O algoritmo funciona usando um contador binário que é realmente muito curto (um incremento é o >[->]++[-<+]-<-que distribui os bits. O problema é que é difícil imprimir todos os bits

Esse último algoritmo pode ser adaptado para caber em qualquer número de bits à custa de bytes. Para poder lidar com números inteiros de N bits, são necessários 53 + 3 * N bytes para codificar.

exemplos:

(1 bit) +>,>-<[>>[->]++[-<+]-<-]++++++++[->++++++<]>+[->+<]>[.>]
(2 bit) +>,>-<[>>[->]++[-<+]-<-]++++++++[->++++++<]>+[->+>+<<]>[.>]
(3 bit) +>,>-<[>>[->]++[-<+]-<-]++++++++[->++++++<]>+[->+>+>+<<<]>[.>]
etc

3

Resposta APL obrigatória - 21 22

"01"[1+2|⌊⎕÷2⋆⊖0,⍳15]

Exemplos:

      "01"[1+2|⌊⎕÷2⋆⊖0,⍳15]
⎕: 0
0000000000000000
      "01"[1+2|⌊⎕÷2⋆⊖0,⍳15]
⎕: 13
0000000000001101
      "01"[1+2|⌊⎕÷2⋆⊖0,⍳15]
⎕: 9999
0010011100001111
      "01"[1+2|⌊⎕÷2⋆⊖0,⍳15]
⎕: -3
1111111111111101
      "01"[1+2|⌊⎕÷2⋆⊖0,⍳15]
⎕: 32767
0111111111111111

Você pode reduzir com quase 50% usando ⎕IO←0, e retornando uma matriz de bits em vez de uma string: 2|⌊⎕÷2*⊖⍳16.
Adám 18/06/16

3

Código da máquina de Turing, 272 bytes

Como sempre, estou usando a sintaxe da tabela de regras definida aqui. Você pode testá-lo nesse site ou, alternativamente, usando esta implementação java.

Muito do código é copiado do meu conversor de decimal para hexadecimal aqui.

0 * * l B
B * * l C
C * 0 r D
D * * r E
E * * r A
A _ * l 1
A * * r *
1 0 9 l 1
1 1 0 l 2
1 2 1 l 2
1 3 2 l 2
1 4 3 l 2
1 5 4 l 2
1 6 5 l 2
1 7 6 l 2
1 8 7 l 2
1 9 8 l 2
1 _ * r Y
Y * * * X
X * _ r X
X _ _ * halt
2 * * l 2
2 _ _ l 3
3 * 1 r 4
3 1 0 l 3
4 * * r 4
4 _ _ r A

Faz a contagem regressiva da entrada na base 10 e conta a partir de 0 na base 2. Ao diminuir o zero, apaga o bloco de entrada e termina.


2

Javascript 59

o='';i=parseInt(prompt());do{o=(i&1)+o}while(i>>=1)alert(o)

Você pode usar em +xvez deparseInt(x)
Cyoce

2

Perl, 44

Este é o meu primeiro programa Perl de todos os tempos, então, por favor, perdoe-me se isso puder ser facilitado ainda mais. Edit: Obrigado @primo por tirar 7 caracteres da minha resposta.

$x=<>;do{@s=($x&1,@s)}while($x>>=1);print@s

$x=<>;do{push@s,$x&1}while($x>>=1);print reverse@s

A lógica é essencialmente a mesma que a minha solução C anterior.

Além disso, usa 64 bits.


11
Você pode salvar o reverseconstruindo as para trás da matriz: @s=($x&1,@s).
primo

11
Agora que o concurso é longo, o melhor que eu encontrei foi 34: $\=$_%2 .$\while$_=$_>>1||<>;print. Ou, se as opções de linha de comando contarem um byte cada, 27: 1while$\=$_%2 .$\,$_>>=1}{using -p.
primo

2

Javascript - 56 48 e 36 28 caracteres

  • Não funciona com números negativos.

Graças ao @Blender por cortar 8 caracteres.

Este formulário recebe entrada e mostra a saída, 48 caracteres:

x=prompt();for(a="";x;x=~~(x/2))a=x%2+a;alert(a)

Se apenas uma instrução que coloca em uma variável aa forma binária de uma variável xé necessária (e você não se preocupa em destruir o xvalor como efeito colateral), aqui está ela com 28 caracteres:

for(a="";x;x=~~(x/2))a=x%2+a

11
Você pode substituir Math.floorpor ~~, pois o intervalo para os números é pequeno.
Blender

@ Blender Obrigado, eu sabia que existia alguma maneira, simplesmente não consegui encontrá-lo.
Victor Stafusa

@ Victor Eu não sei javascript, então eu posso estar errado, mas no final, quando você diz a=x%2+aque isso pode ser reduzido para a+=x%2? Funciona em todos os idiomas que conheço.
Albert Renshaw

@AlbertRenshaw Não, isso seria o mesmo que a=a+x%2, mas isso +é para concatenação de strings. Ou seja, sua sugestão resulta nos dígitos na ordem inversa.
Victor Stafusa

@Victor Ah! Obrigado!
Albert Renshaw

2

Python - 61 60 caracteres

x=input();print"".join("01"[x>>i&1]for i in range(15,-1,-1))

2
Você pode se livrar do espaço entre printe "".
Blender

@Blender Eu estava prestes a sugerir a mesma coisa :)
Albert Renshaw

@ Blender Ha verdade, nem percebi. Feito!
C0deH4cker 17/02

Se você chamá-lo a partir da linha de comando que você pode deixar de lado printcomo ele automaticamente retorna o resultado
paul.oderso

2

C, 55 caracteres

Imprime um zero inicial extra (por uma questão de 2 bytes).
Como a recursão printfinverte a ordem de impressão, o algoritmo extrai os bits da direita para a esquerda, mas imprime da esquerda para a direita.

EDIT : salvou um char usando em putcharvez de printf.

f(x){(x*=x<0?-printf("-"):1)&&f(x/2);putchar(48+x%2);}

2

Dyalog APL , 11 bytes

2|⌊⎕÷2*⌽⍳16

2|O restante da divisão, quando dividido pela metade do
valor arredondado da
entrada
÷dividido por cada um de
2*dois, à potência de cada um de
⍳16{0, 1, 2, ..., 15}

Requer ⎕IO←0qual é o padrão em muitos sistemas.

TryAPL online!


1

C, 81

char b[17];i=15;main(x){scanf("%d",&x);while(i+1)b[i--]=(x&1)+48,x>>=1;puts(b);}

A saída possui estritamente 16 bits (incluindo zeros de preenchimento)


1

Script do Google Apps + Planilhas Google, 147 144 121 bytes

Roteiro

function j(decNumb){var str='';do{str=String(decNumb%2)+str;decNumb=decNumb/2|0;}while(decNumb>=1);return parseInt(str);}

Folha

=j(b1)

Versão modificada deste script por ZygD.


Você pode remover algum espaço?
NoOneIsHere

1

Haskell, 66 bytes

c 0=0
c n=c(div n 2)*10+mod n 2
b('-':r)='-':b r
b r=show.c.read$r

Ligue para b "-1023", adicione main=interact bum programa completo ou experimente o Ideon.

crealiza a conversão para números inteiros positivos.
b r=show.c.read$rconverte uma string em um número, aplica ce converte novamente em string.
b('-':r)='-':b rretira uma possível liderança -e a anexa novamente ao resultado.



1

APL (NARS), 17 caracteres, 34 bytes

{2∣⌊⍵÷2*(⍺-1)..0}

É uma cópia e modificação da resposta de Adam /codegolf//a/90107 da maneira que se pode adicionar o parâmetro para o comprimento dos bits e ⎕IO para esta função (aqui ⎕IO = 1) deve não tem importância ...

  f←{2∣⌊⍵÷2*(⍺-1)..0}
  16 f 2
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
  32 f 2
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
  32 f ¯1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
  16 f ¯1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
  64 f ¯12345678
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 

parece fácil lidar com o número de bits dessa maneira (chequei o último resultado certo)


0

Smalltalk (Smalltalk / X), 63/78

a primeira versão cria uma cadeia intermediária (78):

t:=Number readFrom:Stdin.
((15to:1by:-1)collect:[:i|$0+(t>>i&1)]as:String)print

na verdade, não há necessidade de criar a string; basta imprimir os caracteres (63):

t:=Number readFrom:Stdin.
15to:1by:-1 do:[:i|($0+(t>>i&1))print]

mhmh - existe uma maneira mais curta de ler para um número?


0

Python 3.x: 65 caracteres

b=lambda n:n<2 and'01'[n]or b(n//2)+b(n%2);print(b(int(input())))

0

Bash, 44

f=b+=n/2**e%2*10**e,2**e++/n?f=b:f;echo $[f]

Passe um valor de entrada para o script através da variável de ambiente n. A representação decimal do resultado binário não pode exceder LONG_MAX.

Isso também deve ser compatível com ksh93e zsh, se be esão inicializados para 0e expansão aritmética adequada for utilizada.


11
Não acredito que isso seja válido, pois assume que njá está definido, tornando-o um snippet. Isso pode ser corrigido usando a entrada como argumento da linha de comando e definindo nisso no seu script.
a spaghetto

@quartata Variáveis ​​em um contexto matemático no shell são implicitamente zero. Para fins de golfe, faz mais sentido fazer do n=127 sh -c '...'que sh -c 'n=$1 ...' _ 127. Não há razão para preferir um ao outro nesse caso, pois ambos são uma maneira perfeitamente típica de passar valores.
ormaaj

0

C # - 104

string p(int d){var r="";long i=1;while(r.Length<=64){var g=d&i;r=(g!=0)? "1"+r:"0"+r;i=i<<1;}return r;}

Este método converterá decimal em binário em 64bits.

Quando executado, o método acima no Linqpad - rr = p (-32768); rr.Dump ();

Resultado: 01111111111111111111111111111111111111111111111111000000000000000


A especificação pede "uma sequência de entrada". Parece que esse método aceita um int.
Puxa

0

Java 8, 80 71 bytes

n->{String r="";for(int i=n<0?-n:n;i>0;i/=2)r=i%2+r;return n==0?"0":r;}

-9 bytes devido a uma regra nos comentários. As entradas negativas da base 10 podem retornar o valor positivo / absoluto da base 2 como saída aparentemente.

Explicação:

Experimente online.

n->{                   // Method with integer parameter and String return-type
  String r="";         //  Result-String, starting empty
  for(int i=n<0?-n:n;  //  Start `i` at the absolute (non-negative) value of the input
      i>0;             //  Loop as long as `i` is not 0
      i/=2)            //    After every iteration: integer-divide `i` by 2
    r=i%2+r;           //   Prepend the result with `i` modulo-2
  return n==0?         //  If the input is 0:
          "0"          //   Return literal "0"
         :             //  Else:
          r;           //   Return the result-String


0

Pequeno Básico , 133 bytes

Um script que entra e sai para o TextWindowconsole.

n=TextWindow.Read()
While n>0
c=c+1
x[c]=Math.Remainder(n,2)
n=Math.Floor(n/2)
EndWhile
For i=0To c-1
TextWindow.Write(x[c-i])
EndFor

Experimente em SmallBasic.com Requer o Silverlight e, portanto, deve ser executado no IE.

A E / S é obtida / fornecida no console preto.

-22 bytes graças a @Neil


Você não pode usar For i=0To c-1?
314 Neil

@ Neil - eu absolutamente posso. Great catch!
22618 Taylor Taylor

0

MATL , 15 17 bytes

t0<?16Ww+]`2&\t]x

Experimente no MATL Online

TIO

(+2 bytes removendo 0 inicial para números negativos, o bit de sinal deve ser o primeiro bit.)

A saída no MATL Online deve ser lida de baixo para cima (MSB está na parte inferior).

A parte principal é bem simples: `2&\t= enquanto o valor for maior que 0, divida por 2 e acumule os restantes.

Lidar com números negativos e dar-lhes a representação do complemento de 2 foi a parte complicada. No final, eu fui com o " subtrair de2N"para obter o complemento de dois de um número. Como somos obrigados a manipular valores de até -32768, para números negativos, o código cria 216=65536com 16W, adiciona a entrada a isso (por exemplo, 65536 + (-42)), que fornece algo que o MATLAB vê como um número positivo, mas representa a representação binária assinada da entrada na forma de 16 bits.




Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.