Los números unarios generalmente solo representan enteros no negativos, pero podemos extenderlos para representar todos los enteros de la siguiente manera:
- Un entero positivo N se representa como N
1
's:5 -> 11111
- Un entero negativo -N se representa como
0
seguido por N1
's:-5 -> 011111
- Cero se representa como
0
Entonces podemos representar una lista de estos números sin ambigüedades si usamos 0
como separador:
3,-2,0,1
111,011,0,1
111 0 011 0 0 0 1
11100110001
Su tarea: tomar una cadena que represente dicha lista de números unarios con signo y traducirla en una lista de números decimales.
Detalles
Puede suponer que la entrada es una lista completa de números unarios con signo. En particular, su programa no tendrá que manejar 1) entrada vacía o 2) entrada que termina con un separador.
Puede suponer que la magnitud de cada número no excederá 127. Para los idiomas con tamaños máximos de cadenas o listas, puede suponer que la entrada y la salida encajarán en las estructuras de datos de su idioma, pero su algoritmo debería funcionar teóricamente para una lista de cualquier tamaño.
Su programa o función puede realizar E / S de cualquiera de las formas estándar . La entrada puede ser una cadena o una lista de caracteres, cadenas de un solo carácter, enteros o booleanos. Puede usar cualquiera de los dos caracteres para representar 1
y 0
; si no usa 1
y 0
, especifique qué caracteres está usando.
La salida debe ser números decimales en cualquier formato de lista razonable (en particular, debe haber algún tipo de separador entre números). Los números negativos deben indicarse con un signo menos, aunque si su idioma tiene un formato diferente para enteros negativos, también lo aceptaré. Cero puede representarse en la salida como 0
o -0
.
Casos de prueba
1 -> 1
0 -> 0 (or -0, and similarly for the other test cases)
011 -> -2
1101 -> 2,1
1100 -> 2,0
11001 -> 2,-1
110001 -> 2,0,1
11100110001 -> 3,-2,0,1
00000001 -> 0,0,0,-1
01111011111111001111111111111110111111111111111100111111111111111111111110111111111111111111111111111111111111111111 -> -4,8,-15,16,-23,42
01111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 -> -127
'0's
, no es técnicamente unario. Buen desafío sin embargo!0
) y el prefijo de signo negativo (0
) son iguales, aunque todavía no es ambiguo, ya que no puede tener signos negativos en el medio de un número (¿es182--693-1
un número? No, y tampoco lo es1111011000101111
exactamente por la misma razón).Respuestas:
Python 2 ,
7370 bytesUna función que toma una cadena como entrada y devuelve una representación de cadena de una lista de Python. Cero puede representarse tanto por
0
y-0
(cuando llega el último):Explicación
split
la cadena de entradas
en ceros.map
).Eso nos lleva un largo camino. Los ceros eran separadores después de todo. Y los números eran unarios, por lo que
len
convenientemente los convierte a decimales. Pero ahora hemos estropeado todos los usos sin separador de0
. Afortunadamente, todos los usos sin separador fueron ceros iniciales, por lo que vinieron después de un separador cero y nos dieron cadenas de longitud cero ('00'.split('0') == ['', '', '']
). Esas cadenas de longitud cero también se convirtieron0
por ellen
.replace
cada cero que precede a otro número por un signo negativo en ese número en su lugar. Eso corrige el uso de0
como un signo pero rompe los ceros literales. Los ceros literales también fueron precedidos por un separador, por lo que ahora se han convertido en pares de guiones adicionales en el siguiente número.replace
cada uno de--
nuevo en un0
elemento en la "lista".fuente
Retina ,
2321 bytesPruébalo en línea!
La primera etapa
(.)0<newline>$1<space>
coincide con cualquier personaje seguido de a0
. El partido se reemplaza por el primer personaje seguido de un espacio. Esto divide la cadena en los números individuales.La segunda etapa
01<newline>-1
reemplaza0
's antes de un bloque de1
' s al-
letrero.La última etapa
1+<newline>$.&
coincide con todos los bloques de1
's y los reemplaza con la longitud del grupo.Aquí hay un ejemplo con la salida de las etapas individuales.
fuente
Vim, 56 bytes
Pruébalo en línea!
No he publicado en vim en mucho tiempo. Principalmente estoy usando vim porque V es un dolor a veces. Porque el
count
comando, que es perfecto para obtener el número de '1 en la línea, sobrescribirá cualquier' 0 en la línea, por lo que no podemos negarlo después.Explicación:
Este es un byte más corto que la forma directa:
debido al encadenamiento de comandos. Como ese separa los comandos, lo usaré para la explicación.
Ahora, cada número unario firmado está en una línea individual. Usando '11100110001' como ejemplo, en este punto tendremos:
Como agregamos nuevas líneas al final de cada partido, teníamos una línea vacía antes de ejecutarla. Después de ejecutar eso, tendremos un '0' (porque coincidió con una ejecución de 0 '1's). Entonces llamamos
D
para eliminar esta línea, dejándola en blancofuente
:%s/1+$/
le daría un byte más corto si no fuera por la necesidad de+
-
lugar de0
o-0
Haskell ,
6866 bytesPruébalo en línea! Toma datos como una lista de ceros y unos. Ejemplo de uso:
f [0,0,0,1,1]
rendimientos[0,-2]
.Explicación:
La coincidencia de patrones se
f(x:r)|(a,b)<-span(>0)r
unex
al primer elemento de la entrada,a
a una lista (potencialmente vacía) de los siguientes1
s, yb
al resto de la entrada. Dada una entrada[0,1,1,1,0,0,1]
, obtenemosx=0
,a=[1,1,1]
yb=[0,0,1]
.El número actual es entonces la suma de
a
negado ifx=0
o la suma dea
más uno ifx=1
. Esto se logra indexando conx
una lista que contiene una función de negación e incremento, y aplicando la función resultante a la suma dea
:[(0-),(1+)]!!x$sum a
.La lista de descanso
b
está vacía o contiene un cero de separación y el siguiente número. La comprensión de la lista[z|_:t<-[b],z<-f t]
intenta coincidirb
con el patrón_:t
, es decir, olvidar el elemento principal y vincular el resto de la listat
. Sib
está vacío, esta coincidencia falla y la comprensión de la lista se evalúa como[]
, que es el caso base para la recursividad. De lo contrario, la funciónf
se aplica de forma recursivat
y la comprensión de la lista se evalúa en todos los elementos az
partir del resultado def t
.fuente
Wolfram Language (Mathematica) , 80 bytes
Pruébalo en línea!
Abusa de la mecánica de
StringCases
, ya que no comprueba patrones superpuestos. Como buscamos de izquierda a derecha, sin superposiciones, siempre obtenemos solo los enteros que necesitamos.Explicación
Añadir un cero al final
Encuentra todos los siguientes patrones ...
Un solo carácter (llámelo
x
), seguido de la cadena más corta posible de longitud cero o más larga (llámeloy
), seguido de un cero.Aplicar al patrón correspondiente: tome la longitud de
y
. Six
es cero, entonces niega el valor. De lo contrario, incremente uno.Esto también cubre
00
, yay
que sería una cadena vacía, y calcularíamos-0
(== 0
).fuente
Brain-Flak , 94 (70?) Bytes
Pruébalo en línea!
En realidad, esto es sorprendentemente breve para el ataque cerebral.
Aquí hay una versión comentada / legible:
Si la salida puede ser inversa, podemos hacer esto para 70 en su lugar:
Este consejo mío es casi perfecto para esta situación. Pero no funciona del todo, ya que tenemos que presionar un 0 antes de realizar la operación (contando los '1'), y la operación ocurre en un bucle. Lo más corto que se me ocurre utilizar este consejo es:
que también es de 94 bytes.
fuente
Perl 5 , 40 + 1 (
-n
) = 41 bytesPruébalo en línea!
fuente
Casco ,
20 18 17 1514 bytesPruébalo en línea!
Explicación
La división funciona así.
ġ/
divide su argumento entre cada par de elementosa,b
para los cuales/a b
es falso./a b
es una división con argumentos invertidos,b
dividida pora
. Los valores relevantes en este programa son estos:/1 1
da1
(verdad)/1 0
da0
(falso)./0 1
daInf
(infinito positivo, verdad)./0 0
daAny
(un valor especial similar a NaN, falsedad).fuente
Acc !! ,
252237 bytesUsos
-0
. Produce números separados por tabuladores, con una tabulación final.Pruébalo en línea!Cantidad de tiempo que escribe el algoritmo real: 20 minutos. Cantidad de tiempo de depuración de mi código de salida decimal: 45 minutos. : ^ P
Con comentarios
No sé si estos comentarios explican muy bien el código: se basan en mis notas para mí mientras lo escribía, por lo que asumen cierta comprensión de cómo Acc !! trabajos. Si algo necesita más explicación, hágamelo saber y trataré de aclararlo.
fuente
Python 2 ,
9692 bytesPruébalo en línea!
Thx a ovs y DLosc para 2 bytes cada uno.
fuente
R , 119 bytes
Pruébalo en línea!
El código usa esta solución de stackoverflow para un problema relacionado (Gracias a jeales por la idea). La salida es una cadena separada por espacios impresa en stdout.
fuente
Jalea ,
1918 bytesTiene que haber una mejor manera...
Un programa completo que imprime cada número seguido de un salto de línea.
Pruébalo en línea!
¿Cómo?
fuente
QBasic,
8886 bytesEsto fue divertido. Múltiples revisiones a partir de una versión de 107 bytes resultaron en uno de los bits más ofuscados de QBasic que creo que jamás haya escrito.(Editar: Curiosamente, pude jugar al golf 2 bytes al aclarar el código).
Nota: este programa lee la entrada del usuario de un carácter a la vez sin hacer eco en la pantalla (como resultado de usar en
INPUT$(1)
lugar de laINPUT
declaración habitual ). Entonces, mientras escribe, no verá los 1 y los 0, pero los números decimales aparecerán a medida que se calculan. Asegúrese de presionar Enteral final de la entrada para ver el último número y finalizar el programa.Versión sin golf
Explicación
(AKA "¿Qué? ¡Eso todavía no tiene sentido!")
La estrategia base es ejecutar un bucle que tome un personaje de
INPUT$(1)
cada vez, haga cosas con él y siga haciendo bucles siempre que el personaje tenga un valor ASCII mayor que el de!
(es decir, no era una nueva línea).Hacemos un seguimiento de los números en progreso utilizando dos variables.
num
es el número de caracteres en el número unario actual firmado (incluido cualquier cero inicial).sign
es1
si el número tenía un cero a la izquierda,0
si no. Ambos deben inicializarse0
, lo cual es excelente para la versión de golf porque las variables numéricas en QBasic se inicializan automáticamente0
.Cada vez que leemos un personaje, lo primero es determinar si es
1
o0
. Usaremos este resultado dos veces, por lo que lo almacenaremosisZero
. Técnicamente, ese nombre es engañoso, ya que el valor también será verdadero si el personaje es una nueva línea. Tenga en cuenta que la verdad en QBasic es-1
y falsey es0
.Ahora, si estamos en el medio de leer un número (
num > 0
) y llegamos a cero o al final de la entrada (isZero
), necesitamos calcular qué número hemos terminado de leer.sign
almacena0
para positivo,1
para negativo. Para obtener1
positivo y-1
negativo, necesitamos1-2*sign
.num
almacena la magnitud correcta para los positivos pero una más que la magnitud para los negativos (ya que incluye el marcador de signo). Entonces podemos usarnum-sign
para la magnitud.Multiplique estos juntos e imprima; luego reiniciar
sign
ynum
que0
en la preparación para la lectura del siguiente número.De lo contrario (si no hemos alcanzado un cero, o si hemos alcanzado un cero al comienzo de un número), actualizamos
sign
y de lanum
siguiente manera:sign
se convierte1
si estamos viendo un cero a la izquierda; de lo contrario, si estamos viendo uno, se queda en lo que ya era. El código de golf ess=s-z
, lo que equivale a lo mismo:z
es-1
. Comos
se garantiza que es0
(porque este es el comienzo de un nuevo número),s-z
será1
.z
es0
. Luego ses-z
queda en cualquier valor ques
tenía previamente.num
se incrementa¡Eso es!
fuente
JavaScript (ES6), 60 bytes
Devuelve una lista de enteros separados por espacios.
Casos de prueba
Mostrar fragmento de código
fuente
Lua , 58 bytes
Pruébalo en línea!
Programa completo, toma la entrada de la línea de comando e imprime los números en stdout separados por nuevas líneas.
fuente