Convierta de base 10 a base 2 sin conversiones de base incorporadas

16

Antecedentes :

Se le ha asignado una tarea para convertir números de base 10 a base 2 sin usar ninguna función de conversión de base prefabricada. Tampoco puede usar ninguna biblioteca importada.

Problema :

Convierta una cadena de entrada de base 10 (decimal) a base 2 (binario). No puede utilizar ningún código / funciones / métodos de conversión base prefabricados ni bibliotecas importadas. Como se trata de , la respuesta más corta en bytes ganará.

La entrada será de -32768 a 32767 (incluye el manejo de bytes de signo en su código)

TheDoctor
fuente
3
P: ¿qué significa "manejo de byte de signo"? ¿Debo mostrar "-xxxx" para un número negativo? Entonces algunos de nosotros estamos equivocados, incl. yo, como salí "11 ... 11" para -1 (también conocido como sin signo)
blabla999
Manejo de bytes de signo: el MSB de los controles de variables firmadas si son negativos
TheDoctor
1
claro, pero ¿tengo que> imprimirlos <como signo '-' seguido de magnitud?
blabla999
@ blabla999 - No, no lo haces
TheDoctor
3
the MSB of signed variables controls if they are negative- Eso suena como bit de signo, sin embargo, como -32768..32767sugiere el rango , desea el complemento de 2. Entonces, ¿cuál quieres? ..
mniip

Respuestas:

4

GolfScript - 17 bytes

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

No es mucho más detallado que el incorporado ~2base.

primo
fuente
1
No conozco golfscript, pero algunas ejecuciones de muestra me llevan a la conclusión de que debe eliminar el~
user12205
@ace Debido a que la entrada inicial es una cadena "37", por ejemplo, la operación "37" & 1(en infijo) es una operación configurada. El ~en el frente convierte la entrada a un entero.
primo
Hice mi prueba aquí golfscript.apphb.com/… ¿Esto significa que este intérprete es incorrecto? (Lo siento, realmente no sé nada sobre golfscript)
user12205
2
El intérprete es correcto; porque ha introducido el valor entero 10en la pila, no es necesario evaluarlo. Sin embargo, cuando se lee desde stdin, la entrada será una cadena ( prueba aquí ). La descripción del problema también establece explícitamente que la entrada es una cadena.
primo
12

JavaScript, 46

for(x=prompt(o='');x;x>>>=1)o=(x&1)+o;alert(o)
Copiar
fuente
Lol, ¡ni siquiera sabía que >>>=existía un operador de 4 caracteres ( )! +1 (Además, si lo ejecuta en la consola, puede guardar los últimos 9 caracteres.)
Pomo de la puerta
1
No son 4 caracteres, son dos operadores: el >>> es el desplazamiento a la derecha de relleno de 0, seguido de una asignación. Pruebe: x=8; x>>>=1; x;y x=8; x>>>1; x;- en el primer caso, el valor de x ha cambiado; en el segundo, no lo ha hecho.
Graham Charles
3
@GrahamCharles >>>=es un solo operador .
primo
Bueno, mira eso! Gracias, @primo ... ¡aprendes algo todos los días!
Graham Charles
2
@ComFreek Eso revertiría el orden de los dígitos
copia
4

Brainf * ck, 98 77

Obviamente, esto no tiene el propósito de ganar, pero ¿cuál sería una competencia si no tuviera una solución brainfk?

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

Dado que brainfk solo puede manejar enteros de 8 bits y no negativos, supongo que no cumple completamente con las reglas, pero bueno, nunca estuve allí para ganarlo.

Esto realmente funciona para entradas de 16 bits si su intérprete admite

Incluso lo hice salir en valores ASCII

Aquí está el 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 más corto (77):

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

Este solo puede manejar enteros de 8 bits.

El algoritmo funciona utilizando un contador binario que en realidad es muy corto (un incremento es el >[->]++[-<+]-<-que presenta los bits. El problema es que es difícil imprimir todos los bits

Ese último algoritmo se puede adaptar para adaptarse a cualquier número de bits a expensas de los bytes. Para poder tratar con enteros de N bits, se requieren 53 + 3 * N bytes para codificar.

ejemplos:

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

Respuesta APL obligatoria - 21 22

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

Ejemplos:

      "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
mniip
fuente
Se puede reducir con casi el 50% mediante el uso ⎕IO←0, y devuelve una matriz de bits en lugar de una cadena: 2|⌊⎕÷2*⊖⍳16.
Adám
3

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

Como de costumbre, estoy usando la sintaxis de la tabla de reglas definida aquí. Puede probarlo en ese sitio o, alternativamente, usar esta implementación de Java.

Gran parte del código se copia de mi convertidor de decimal a hexadecimal aquí.

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

Cuenta hacia atrás desde la entrada en la base 10 mientras cuenta hacia atrás desde 0 en la base 2. Al disminuir el cero, borra el bloque de entrada y termina.

SuperJedi224
fuente
2

Javascript 59

o='';i=parseInt(prompt());do{o=(i&1)+o}while(i>>=1)alert(o)
Michael M.
fuente
Puede usar en +xlugar deparseInt(x)
Cyoce
2

Perl, 44

Este es mi primer programa Perl en la historia, así que perdónenme si se puede seguir jugando más fácilmente. Editar: Gracias @primo por quitarme 7 caracteres de mi respuesta.

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

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

La lógica es esencialmente la misma que mi solución C anterior.

Además, utiliza 64 bits.

usuario12205
fuente
1
Puede guardar el reverseconstruyendo el revés de la matriz: @s=($x&1,@s).
primo
1
Ahora que el concurso ha terminado, el mejor que he encontrado fue de 34: $\=$_%2 .$\while$_=$_>>1||<>;print. O, si las opciones de la línea de comando cuentan un byte cada una, 27: 1while$\=$_%2 .$\,$_>>=1}{usando -p.
primo
2

Javascript - 56 48 y 36 28 caracteres

  • No funciona con números negativos.

Gracias a @Blender por afeitar 8 caracteres.

Este formulario toma entrada y muestra salida, 48 caracteres:

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

Si solo se necesita una instrucción que ponga auna variable, xse necesita la forma binaria de una variable (y no se molesta en destruir el xvalor como efecto secundario), aquí tiene 28 caracteres:

for(a="";x;x=~~(x/2))a=x%2+a
Victor Stafusa
fuente
1
Puede reemplazar Math.floorcon ~~, ya que el rango de los números es pequeño.
Licuadora
@Blender Gracias, sabía que existía de alguna manera, simplemente no podía encontrarlo.
Victor Stafusa
@Victor No conozco JavaScript, así que podría estar equivocado, pero al final, cuando dices, ¿ a=x%2+apodría acortarse a+=x%2? Funciona en todos los idiomas que conozco.
Albert Renshaw
@AlbertRenshaw No, esto sería lo mismo que a=a+x%2, pero eso +es para la concatenación de cadenas. Es decir, su sugerencia da como resultado los dígitos en orden inverso.
Victor Stafusa
@Victor Ah! ¡Gracias!
Albert Renshaw
2

Python - 61 60 caracteres

x=input();print"".join("01"[x>>i&1]for i in range(15,-1,-1))
C0deH4cker
fuente
2
Puede deshacerse del espacio entre printy "".
Licuadora
@Blender Estaba a punto de sugerir lo mismo :)
Albert Renshaw
@Blender Ha cierto, ni siquiera me di cuenta. ¡Hecho!
C0deH4cker
si lo llama desde la línea de comandos, puede dejarlo de lado, printya que devuelve automáticamente el resultado
paul.oderso
2

C, 55 caracteres

Imprime un cero inicial adicional (por el bien de 2 bytes).
Recursión dentroprintf invierte el orden de impresión, por lo que el algoritmo extrae bits de derecha a izquierda pero imprime de izquierda a derecha.

EDITAR : guardado un char usando en putcharlugar de printf.

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

Dyalog APL , 11 bytes

2|⌊⎕÷2*⌽⍳16

2|El resto de la división cuando se reduce a
la mitad el valor redondeado hacia abajo de
la entrada
÷dividido por cada uno de los
2*dos a la potencia de cada uno de
⍳16{0, 1, 2, ..., 15}

Requiere ⎕IO←0cuál es el predeterminado en muchos sistemas.

TryAPL en línea!

Adán
fuente
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);}

La salida tiene estrictamente 16 bits (incluidos los ceros de relleno)

usuario12205
fuente
1

Hojas de Apps Script + Google, 147 144 121 bytes

Guión

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

Sábana

=j(b1)

Versión modificada de este script por ZygD.

weatherman115
fuente
¿Puedes eliminar espacios?
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

Llama con b "-1023", agrega main=interact bun programa completo o pruébalo en Ideon.

crealiza la conversión para enteros positivos.
b r=show.c.read$rconvierte una cadena en un número, aplica cy vuelve a convertir en cadena.
b('-':r)='-':b relimina un posible líder -y lo vuelve a agregar al resultado.

Laikoni
fuente
1

PowerShell, 59 87 82 70 bytes

+28 bytes para soportar números negativos.
-12 bytes gracias a @ ASCII-only

param($d)$m=$d-lt0;while($d){$n="01"[$d%2]+$n;$d=($d-$d%2)/2}'-'*$m+$n

Pruébalo en línea!

Adaptado de este código . Toma datos a través de un parámetro de línea de comandos -d.

Gabriel Mills
fuente
¿Qué pasa con los números con signo?
mazzy
73?
Solo ASCII
oh espera 70
solo ASCII
1

APL (NARS), 17 caracteres, 34 bytes

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

Es una copia y modificación de la respuesta de Adam /codegolf//a/90107 en la forma en que se puede agregar el parámetro para la longitud de bits, y ⎕IO para esta función (aquí es ⎕IO = 1) debería no tiene importancia ...

  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 manejar el número de bits de esta manera (compruebo que el último resultado debe ser correcto)

RosLuP
fuente
0

Smalltalk (Smalltalk / X), 63/78

la primera versión crea una cadena intermedia (78):

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

en realidad, no hay necesidad de crear la cadena; solo da salida a los caracteres (63):

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

mhmh: ¿hay una forma más corta de leer un número?

blabla999
fuente
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())))
dan04
fuente
0

Bash, 44

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

Pase un valor de entrada al script a través de la variable de entorno n. La representación decimal del resultado binario no puede exceder LONG_MAX.

Esto también debe ser compatible con ksh93y zshsi by ese inicializan a 0y se utiliza expansión aritmética adecuada.

ormaaj
fuente
1
No creo que esto sea válido, ya que supone que nya está definido, por lo que es un fragmento. Eso podría solucionarse tomando la entrada como un argumento de línea de comandos y configurándola nen su script.
un spaghetto
@quartata Las variables en un contexto matemático en shell son implícitamente cero. Para el golf tiene más sentido hacer n=127 sh -c '...'que sh -c 'n=$1 ...' _ 127. No hay ninguna razón para preferir uno sobre el otro en este caso, ya que ambos son una forma perfectamente típica de pasar 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 convertirá decimal a binario hasta 64bits.

Cuando se ejecuta el método anterior en Linqpad - rr = p (-32768); rr.Dump ();

Salida: 01111111111111111111111111111111111111111111111111000000000000000

Rajesh
fuente
La especificación requiere "una cadena de entrada". Parece que este método acepta un int.
Poke
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 debido a una regla en los comentarios. Las entradas negativas de base 10 pueden devolver el valor positivo / absoluto de base-2 como salida aparentemente.

Explicación:

Pruébalo en línea.

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
Kevin Cruijssen
fuente
0

Pequeño Básico , 133 bytes

Un script que entra y sale de la TextWindowconsola.

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

Pruébelo en SmallBasic.com Requiere Silverlight y, por lo tanto, debe ejecutarse en IE.

La E / S se toma / da desde la consola negra.

-22 bytes gracias a @Neil

Taylor Scott
fuente
¿No puedes usar For i=0To c-1?
Neil
@Neil: absolutamente puedo. Gran captura!
Taylor Scott
0

MATL , 15 17 bytes

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

Pruébalo en MATL Online

TIO

(+2 bytes eliminando el 0 inicial para números negativos, el bit de signo debería ser el primer bit).

La salida en MATL Online debe leerse de abajo hacia arriba (MSB está en la parte inferior).

La parte principal es bastante simple: `2&\t= mientras el valor es mayor que 0, divídalo entre 2 y acumule el resto.

Manejar números negativos y darles la representación del complemento 2 fue la parte difícil. Al final fui con el " restar de2norte"método para obtener el complemento de dos de un número. Dado que solo estamos obligados a manejar valores de hasta -32768, para los números negativos, el código crea 2dieciséis=65536with 16W, agrega la entrada a eso (por ejemplo, 65536 + (-42)), lo que da algo que MATLAB ve como un número positivo pero representa la representación binaria con signo de la entrada en forma de 16 bits.

sundar - Restablece a Monica
fuente