Convertidor binario a decimal
Hasta donde puedo ver, no tenemos un desafío simple de conversión de binario a decimal.
Escriba un programa o función que tome un entero binario positivo y genere su valor decimal.
No está permitido utilizar ninguna función de conversión de base integrada. Las funciones de entero a decimal (por ejemplo, una función que se convierte 101010
en [1, 0, 1, 0, 1, 0]
o "101010"
) están exentas de esta regla y, por lo tanto, están permitidas.
Reglas:
- El código debe admitir números binarios hasta el valor numérico más alto que admite su idioma (de forma predeterminada)
- Puede elegir tener ceros a la izquierda en la representación binaria
- La salida decimal puede no tener ceros a la izquierda.
- Los formatos de entrada y salida son opcionales, pero no puede haber separadores entre los dígitos.
(1,0,1,0,1,0,1,0)
no es un formato de entrada válido, pero ambos10101010
y(["10101010"])
son.- Debe tomar la entrada en la dirección "normal".
1110
es14
no7
.
- Debe tomar la entrada en la dirección "normal".
Casos de prueba:
1
1
10
2
101010
42
1101111111010101100101110111001110001000110100110011100000111
2016120520371234567
Este reto se relaciona con algunos otros retos, por ejemplo, este , este y este .
code-golf
base-conversion
binary
Stewie Griffin
fuente
fuente
-1
(32 1's
y64 1's
)round(x)==x
estés bien :)2.000
se acepta la salida para10
.Respuestas:
Jalea , 5 bytes
Pruébalo en línea!
Explicación
El elenco
D
es una mónada (función de argumento único): dígitos, convirtiéndose1234
en[1, 2, 3, 4]
.Ḥ
es una mónada que duplica su argumento único.+
es una diada (función de dos argumentos) que agrega sus argumentos izquierdo y derecho.A partir de ahí, se pone un poco complicado.
Esto es lo que sucede en el momento del análisis
D
,Ḥ
y+
son leídos. La cadena se parece[D, Ḥ, +]
.Los siguientes dos caracteres son rápidos , que actúan como operadores de postfix en tiempo de análisis en los enlaces (funciones) que hemos leído hasta ahora.
Cuando
¥
se lee, los dos últimos enlaces aparecen y se reemplazan por un enlace que actúa como la diada formada al componerlos. Así que ahora se ve la cadena[D, dyad(Ḥ+)]
.Cuando
/
se lee, el último enlace (que debería ser una díada) aparece y se reemplaza por una mónada que se pliega usando esta díada (intuitivamente:f/
toma una lista, reemplaza las comasf
y evalúa el resultado).La cadena final se parece a
[D, fold(dyad(Ḥ+))]
dos mónadas.Esto es lo que sucede en el tiempo de ejecución.
La entrada (un número) se lee implícitamente en el valor de trabajo (por ejemplo,
101010
).D
se ejecuta, reemplazando el valor de trabajo con sus dígitos ([1,0,1,0,1,0]
).fold(dyad(Ḥ+))
se ejecuta, reemplazando el valor de trabajo con1∗0∗1∗0∗1∗0
, donde∗
está la diadaḤ+
.Entonces, ¿qué
x∗y
evalúa?En una definición diádica, el valor de trabajo es inicialmente la izquierda argumento
x
.Ḥ
, la mónada doble , duplica este valor. El valor de trabajo es ahora2x
.+
, la díada más , carece de un argumento correcto, por lo que este es un gancho : un patrón sintáctico especial donde se inyecta el argumento correcto de esta díada+
. Esto rinde2x + y
como el valor de trabajo final, que se devuelve.Entonces toda la expresión se evalúa como:
fuente
Pitón 2,
49373130 BytesAhora, esto tomará un número binario en una representación decimal, ya que Python puede manejar enteros arbitrariamente grandes.
gracias a xnor por guardar un byte :)
La forma más fácil de ver cómo funciona esto es ver una fórmula básica para convertir binario a decimal:
Esta es una forma 'estándar' de conversión. Puede expandir la tercera línea así:
Y esto es esencialmente lo que está haciendo el método recursivo que he hecho.
Soluciones alternativas que tenía:
fuente
n%5
o enn%2
lugar den%10
.05AB1E , 6 bytes
Código:
Para la explicación, tomemos el ejemplo 101010 . Comenzamos con el número 1 (que está representado por el primer dígito). Después de eso, tenemos dos casos:
Entonces, para el caso 101010 , se calcula lo siguiente:
Explicación del código:
Utiliza la codificación CP-1252 . Pruébalo en línea!
fuente
Haskell,
16111 + 57 = 168 bytes+57 bytes para los indicadores de compilación
-XOverloadedStrings
,-XOverlappingInstances
y-XFlexibleInstances
.El desafío tiene un formato de E / S engorroso , porque depende en gran medida de cómo se expresan los tipos de datos en el código fuente. Mi primera versión (16 bytes), a saber
toma una lista de enteros, por ejemplo,
[1,0,1,0,1,0]
y se declaró no válida porque las listas literales de Haskell tienen,
entre los elementos. Las listas per se no están prohibidas. En mi nueva versión utilizo la misma función, ahora nombradaf
, pero sobrecargo "Citar secuencias de caracteres incluidas". La función todavía toma una lista de enteros como puede ver en la anotación de tipo[Int] -> Int
, pero las listas con enteros de un solo dígito ahora se pueden escribir como"1234"
, por ejemploque será evaluado
42
. Haskell desafortunado, porque el formato de lista nativa no se ajusta a las reglas de desafío. Por cierto,f [1,0,1,0,1,0]
todavía funciona.fuente
(1,0,1,0,1,0,1,0)
no es un formato de entrada válido, pero ambos10101010
y lo(["10101010"])
son". además, un comentario sugiere que la matriz de caracteres es aceptable si así es como se interpreta una entrada de cadena.10101010
,"10101010"
o algo similar y hacer que funcione, entonces el envío es válido. Puede llamarlo cadena, lista, número entero o lo que sea. Ingresando[1][0][1][0]
o[1,0,1,0]
no está bien. Básicamente, debería ser posible golpear un montón de unos y ceros en una fila en alguna parte. ¿Está esto claro?Retina, 15 bytes
Convierte de binario a unario, luego unario a decimal.
Pruébalo en línea
fuente
PHP, 44 bytes
Podría haber jurado que había visto esa pregunta antes. Pero bueno.
Lee el número de izquierda a derecha, se desplaza a la izquierda y agrega el bit actual.
fuente
JavaScript (ES6),
3331 bytesEditar: más corto pero menos dulce: 2 bytes guardados gracias a @ETHproductions.
fuente
.map
es más corto:s=>[...s].map(c=>+c+r+r,r=0)|r
s=>[...s].map(c=>r+=+c+r,r=0)|r
Laberinto ,
1715 bytesPruébalo en línea!
Labyrinth es un lenguaje bidimensional basado en la pila. En el laberinto, la ejecución del código sigue la ruta del código como un laberinto con espacios que actúan como muros y comienzan en el carácter no espacial más a la izquierda. El flujo del código está determinado por el signo de la parte superior de la pila. Como la pila tiene ceros implícitos en la parte inferior, las primeras cuatro instrucciones (
-+:+
) no tienen efecto.Loop que comienza en el
,
,
Presione el valor del código ASCII del siguiente carácter de entrada hasta el tope de la pila, o presione -1 si EOF._48
empuja 48 a la cima de la pila-
Pop y, pop x, empujarx-y
. Las instrucciones anteriores tienen el efecto de restar 48 de la entrada produciendo 0 para "0" y 1 para "1".+
Pop y, pop x, empujarx+y
.:
Duplicar la parte superior de la pila.+
Esta y la instrucción anterior tienen el efecto de multiplicar el valor actual por 2Entonces, la parte circular del código, en efecto, multiplica el número actual por 2 y agrega 1 o 0 dependiendo de si se ingresó el carácter 1 o 0.
Cola
Si la parte superior de la pila es negativa (lo que significa que se encontró EOF), el código girará a la izquierda en el cruce (hacia el punto y coma).
)
Icrement la parte superior de la pila para obtener 2/
Pop y, pop x, push x / y (división entera). Esto tiene el efecto de deshacer el último*2
del bucle.!
Salida de la representación entera de la parte superior de la pila. En este punto, el programa se da vuelta porque llegó a un callejón sin salida y luego sale con un error porque intenta dividir por cero.Gracias a @Martin Ender por guardarme 2 bytes (y enseñarme a pensar mejor en Labyrinth).
fuente
_48-
usted, simplemente puede hacerlo,#%
pero desafortunadamente no veo cómo podría ayudar con el recuento de bytes.`)
en lugar de;_2
embargo.#%
. ¿Puede explicar cómo funciona eso como un reemplazo para_48-
convertir de ascii a int. Gracias por el)
dato. Haré ese cambio.#
es la abreviatura de_2
. Si bien_2%
no es un método de conversión general para ASCII a entero, funciona aquí porque solo le interesan los dos primeros dígitos como entrada posible. Una alternativa sería_1&
(ya que el módulo 2 simplemente extrae el bit menos significativo).#%
) para acortar el código en general.Brain-Flak ,
46, 28 bytesPruébalo en línea!
¡Muchos, muchos bytes guardados gracias a @Riley!
Dado que brain-flak no puede tomar entradas binarias, la entrada es una lista de '0' y '1'.
Explicación:
fuente
([]){({}[()]<({}<>({}){})><>)}<>
([]){{}({}<>({}){})<>([])}<>
Java,
84794648 bytesCambiado a
long
/ 48 bytes:Hice algo de golf / 46 bytes:
Gracias a @Geobits! / 79 bytes:
84 bytes:
fuente
s
debería serchar[]
. Espero que eso esté permitido ...Befunge-98, 12 bytes
Pruébalo en línea!
Lee un carácter a la vez desde la entrada, lo convierte a 0 o 1 tomando su valor módulo 2 (0 es carácter (48), 1 es carácter (49)), luego utiliza el algoritmo habitual para duplicar el valor actual y agregar el nuevo dígito cada vez.
Bonificación: esto funciona con cualquier tipo de cadena de entrada, he estado intentando por un tiempo encontrar alguna combinación divertida de entrada-> salida, pero no pude producir nada (lamentablemente, "respuesta" = 46). ¿Puedes?
fuente
Javascript (ES7)
414036 bytestoma una cadena como entrada
Afeitado un byte gracias a ETHproductions
fuente
**
es extraña, pero es un buen trabajo usarla aquí.1<<b.length
haría lo mismo, pero requeriría paréntesis para evitar ser analizado como(c*1)<<(b.length+...)
. Creo que puede guardar un byte reemplazándolob[0]
conb+b
( ver aquí ).C # 6,
853736 bytesfuente
05AB1E , 7 bytes
Pruébalo en línea!
Explicación
fuente
C, 53
Igual que mi respuesta de JavaScript
Prueba de ideona
fuente
v
yc
como variables globales (aunque necesita cambiar el nombre dev
, ya que ya es el nombre de la función) de esta manera:w=0;c;v(char*s){while(c=*s++)w+=w+c-48;return w;}
w,c;
pero no quiero usar globals cuando la respuesta es una función (incluso en code-golf)=0
.Perl, 25 bytes
-3 bytes gracias a @Dom Hastings.
24 bytes de código + 1 byte para
-p
bandera.Para ejecutarlo:
Explicaciones:
fuente
Pushy , 10 bytes
Toma la entrada como una lista de 0/1 en la línea de comando:
$ pushy binary.pshy 1,0,1,0,1,0
.El algoritmo realmente muestra la belleza de tener una segunda pila:
Este método funciona porque la pila se duplicará
stack length - n
antes de alcanzar el númeron
, que luego se volcará en la segunda pila para más adelante. Así es como se ve el proceso para la entrada101010
:fuente
Matlab, 30 bytes
El último caso de prueba tiene errores de redondeo (debido a
double
), por lo que si necesita precisión completa:con 47 bytes.
fuente
@(x)sum(2.^(find(flip(x)-48)-1))
que dará el resultado correcto para todos los casos para 32 bytes.flip
funciona comofliplr
six
es unidimensional.f=@(x)..; f('1111001010')
.Retina , 12 bytes
El recuento de bytes asume la codificación ISO 8859-1.
Pruébalo en línea!
Solución alternativa:
Explicación
Probablemente será más fácil de explicar según mi versión anterior, menos golfizada, y luego mostrar cómo la acorté. Solía convertir binario a decimal así:
La única forma sensata de construir un número decimal en Retina es contando cosas (porque Retina tiene un par de características que le permiten imprimir un número decimal que representa una cantidad). Entonces, realmente, el único enfoque posible es convertir el binario en unario, y luego contar el número de dígitos unarios. La última línea cuenta, por lo que los primeros cuatro convierten el binario en unario.
¿Como hacemos eso? En general, para convertir de una lista de bits a un entero, inicializamos el resultado
0
y luego pasamos por los bits del más significativo al menos significativo, duplicamos el valor que ya tenemos y sumamos el bit actual. Por ejemplo, si el número binario es1011
, realmente calcularíamos:Donde he marcado los bits individuales para mayor claridad.
El truco para hacer esto en unario es a) que duplicar simplemente significa repetir el número yb) ya que estamos contando la
1
s al final, ni siquiera necesitamos distinguir entre0
sy1
s en el proceso. Esto se aclarará en un segundo.Lo que hace el programa es que primero agrega una coma al principio como marcador de la cantidad de información que ya hemos procesado:
A la izquierda del marcador, tendremos el valor que estamos acumulando (que se inicializa correctamente en la representación unaria de cero), y la derecha del valor será el siguiente bit a procesar. Ahora aplicamos la siguiente sustitución en un bucle:
Solo mirando
,(.)
y$1,
, esto mueve el marcador un poco hacia la derecha cada vez. Pero también insertamos$`
, que está todo delante del marcador, es decir, el valor actual, que estamos duplicando. Estos son los pasos individuales al procesar la entrada1011
, donde he marcado el resultado de insertar$`
encima de cada línea (está vacío para el primer paso):Verá que hemos retenido y duplicado el cero junto con todo lo demás, pero como los estamos ignorando al final, no importa con qué frecuencia los hayamos duplicado, siempre que el número de
1
s sea correcto. Si los cuenta, hay algunos11
de ellos, justo lo que necesitamos.Eso deja la cuestión de cómo jugar golf a 12 bytes. La parte más cara de la versión de 18 bytes es tener que usar el marcador. El objetivo es deshacerse de eso. Realmente queremos duplicar el prefijo de cada bit, por lo que una primera idea podría ser esta:
El problema es que estas sustituciones ocurren simultáneamente, por lo que el primer bit no se duplica para cada bit, sino que solo se copia una vez cada vez. Para la entrada
1011
obtendríamos (marcando el insertado$`
):Todavía necesitamos procesar la entrada de forma recursiva para que el primer prefijo duplicado se duplique nuevamente por el segundo y así sucesivamente. Una idea es insertar marcadores en todas partes y reemplazarlos repetidamente con el prefijo:
Después de reemplazar cada marcador con el prefijo por primera vez, debemos recordar dónde estaba el comienzo de la entrada, por lo que también insertamos saltos de línea y usamos la
%
opción para asegurarnos de que el siguiente$`
solo recoja los elementos del salto de línea más cercano.Esto funciona, pero aún es demasiado largo (16 bytes al contar
1
s al final). ¿Qué tal si cambiamos las cosas? Los lugares donde queremos insertar marcadores se identifican por\B
(una posición entre dos dígitos). ¿Por qué no simplemente insertamos prefijos en esas posiciones? Esto casi funciona, pero la diferencia es que en la solución anterior, en realidad eliminamos un marcador en cada sustitución, y eso es importante para que el proceso finalice. Sin embargo,\B
no son personajes sino solo posiciones, por lo que no se elimina nada. Nosotros podemos sin embargo detener la\B
de la coincidencia insertando en su lugar un carácter sin dígitos en este lugar. Eso convierte el límite sin palabras en un límite de palabras, que es el equivalente a eliminar el carácter marcador anterior. Y eso es lo que hace la solución de 12 bytes:Solo para completar, aquí están los pasos individuales de procesamiento
1011
, con una línea vacía después de cada paso:Nuevamente, encontrará que el último resultado contiene exactamente 11
1
s.Como ejercicio para el lector, ¿puede ver cómo esto se generaliza fácilmente a otras bases (por unos pocos bytes adicionales por incremento en la base)?
fuente
T-SQL, 202 bytes
fuente
PHP, 64 bytes
Invertimos nuestro número binario, lo dividimos en sus dígitos componentes y los sumamos según la posición.
fuente
Bash + utilidades GNU, 29 bytes
E / S a través de stdin / stdout.
La
sed
expresión divide el binario en cada dígito y crea una expresión RPN paradc
evaluar.fuente
PowerShell v2 +, 55 bytes
Se siente demasiado tiempo ...Parece que no puedo jugar golf, consejos apreciados.Explicación
fuente
JavaScript (ES6), 32 bytes
¡La recursión salva el día otra vez! Aunque la parametrización parece un poco larga ...
fuente
[...n]
necesita estar entre paréntesis?Mathematica,
271311 bytesAcepta a
List
de bits como entrada (p{1, 0, 1, 1, 0}
. Ej . , La representación binaria de Mathematica del número22
)fuente
Characters
función.IntegerDigits
en primer lugar.D
, que hace lo mismo queIntegerDigits
Clojure,
1141056341 bytesV4: 41 bytes
-22 bytes gracias a @cliffroot. Dado que
digit
es un carácter, se puede convertir a su código a través deint
, luego se puede restar 48 para obtener el número real. El mapa también fue factorizado. No sé por qué parecía necesario.V3: 63 bytes
-42 bytes (!) Mirando otras respuestas. Mi "zipper" fue evidentemente muy ingenuo. En lugar de aumentar 2 al poder del lugar actual, luego multiplicarlo por el dígito actual y agregar el resultado al acumulador, simplemente multiplica el acumulador por 2, agrega el dígito actual y luego lo agrega al acumulador. También convirtió la función de reducción a una macro para reducir un poco.
¡Gracias a @nimi y @Adnan!
Sin golf:
V2: 105 bytes
-9 bytes invirtiendo la cadena para que no necesite crear un rango descendente incómodo.
V1: 114 bytes
Bueno, ciertamente no estoy ganando! En mi defensa, este es el primer programa que he escrito que convierte entre bases, así que tuve que aprender cómo hacerlo. Tampoco ayuda que
Math/pow
devuelva un doble que requiera la conversión yInteger/parseInt
no acepte un carácter, por lo que el dígito debe ajustarse antes de pasar.Comprime la cadena con un índice descendente que representa el número de lugar. Reduce sobre la lista resultante.
Sin golf:
fuente
#(reduce(fn[a b](+(* a 2)(-(int b)48)))0 %)
versión mejorada. Moviómap
parte del código directamente areduce
, cambió el método de análisis de enteros, realizó una función externa con sintaxis lambda abreviada.int
se puede usar para analizar? Eso eliminará como 10 bytes en cada desafío que he hecho aquí jajaja.Perl,
211916 + 4 = 20 bytes-4 bytes gracias a @Dada
Ejecutar con
-F -p
(incluido el espacio extra después deF
). Canalizar valores a la función usandoecho -n
Correr como
echo -n "101010" | perl -F -pE '$\+=$_+$\for@F}{'
Siento que esto es lo suficientemente diferente de la respuesta de @ Dada que merece su propia entrada.
Explicación:
Esto utiliza mi algoritmo personal de elección para la conversión de binario a decimal. Dado un número binario, inicie su acumulador en 0 y recorra sus bits uno por uno. Duplique el acumulador cada bit, luego agregue el bit en sí mismo a su acumulador, y terminará con el valor decimal. Funciona porque cada bit termina siendo duplicado el número apropiado de veces para su posición en función de cuántos bits más quedan en el número binario original.
fuente
perl -F -pE '$\+=$_+$\for@F}{'
R (32 bits), 64 bytes
La entrada para la función debe darse como carácter. Las funciones básicas de R admiten enteros de 32 bits.
Entrada:
Salida:
R (64 bits), 74 bytes
La entrada para la función debe darse como carácter. El paquete
bit64
debe usarse para enteros de 64 bits.Entrada:
Salida:
fuente
el(strsplit(x,""))
lugar destrsplit(x,split="")[[1]]
guardar un par de bytes.el
función, no lo sabía.Dyalog APL , 12 bytes
⍞
obtener entrada de cadena⍎¨
convierte cada caracter a numero⌽
marcha atrás(
...)/
inserte la siguiente función entre los números++⊢
la suma de los argumentos más el argumento correctongn afeitado 2 bytes.
fuente
k, 8 bytes
El mismo método que la respuesta anterior de Haskell.
Ejemplo:
fuente