La mayoría de las computadoras almacenan enteros en binario, pero los generan en decimal. Sin embargo, el decimal es solo una representación, resulta que lo encontramos conveniente.
Este desafío es escribir un código para generar un valor entero en shortlex decimal .
¿Que es eso?
http://en.wikipedia.org/wiki/Shortlex_order
Shortlex toma la longitud de la secuencia de dígitos como el significante principal del valor. La secuencia, comenzando desde una cadena vacía que representa cero, es ...
ε,0,1,...,8,9,00,01,...98,99,000,001,...,998,999,0000,...
(Piense en las columnas de Excel, pero usando solo los dígitos decimales).
Escriba un programa o función que acepte un número entero y devuelva una cadena correspondiente a la representación decimal-shortlex de ese número entero como se describió anteriormente.
Valores de prueba:
0 → "" (cadena vacía)
1 → "0"
10 → "9"
11 → "00"
42 → "31"
100 → "89"
800 → "689"
1060 → "949"
10270 → "9159"
100501 → "89390"
19, 20, 21, 22
en decimales se asigna a08, 09, 10, 11
en shortlex. ¡Es por eso que solía confundir eso100 -> 89
!Respuestas:
JavaScript (ES6) 42
74Prueba en la consola FireFox
Salida
¿Cómo pensé en esto?
Dado un número fijo de dígitos, la secuencia de salida es simplemente ascendente, por lo que hay un delta fijo entre entrada y salida. Echar un vistazo:
Pero los 0 iniciales son difíciles de administrar, por lo que tengo un truco estándar, agrego un primer dígito y modulo de trabajo (es decir, corta el primer dígito en la salida). Entonces -1-> +9, -11 -> +89, -111 -> +889 y así sucesivamente.
Último paso: no me importa cuál sea el primer dígito, por lo que no es necesario verificar si el número de entrada es <o> que 111 ... (sinceramente, encontré esto por prueba y error)
Prueba
fuente
n-~(n+'')
lugar de solon-~n
?(n+'').replace(...)
, reemplazar trabajos en cadenas, no números.Marbelous
177173170Funciona solo para valores inferiores a 256 ya que Marbelous es un lenguaje de 8 bits.
Cómo funciona
Marbelous es un lenguaje 2D con valores representados por canicas de 8 bits que caen una celda en cada tic a menos que algún dispositivo evite que se caigan. Este programa maravilloso consta de 3 tableros; Comencemos con el más fácil:
:O
es el nombre de la placa (para ser precisos, O es el nombre y: le dice al interpretado que esta línea es un nombre. Al dar un nombre a las placas, otras placas pueden invocarlas como}0
un dispositivo de entrada, esto puede verse como un argumento de esta función. Esta celda será reemplazada por una canica de entrada (valor) cuando se llama a la función.+Z
Agrega 35 a cualquier canica que la pase y la deje caer.+C
Hace lo mismo pero solo agrega 12.{0
Es una celda de salida , cuando una canica llega a esta celda, la función saldrá y devolverá el valor en este dispositivo de salida.Entonces, todos juntos, este tablero toma un valor y luego le agrega 47. Para nosotros, esto significa que convierte cualquier número de un solo dígito en el código ASCII del dígito -1 (esto, por supuesto, también funcionará para 10).
Este tablero se ve un poco más complicado. Debería poder identificarse
:I
como el nombre de la placa y haber detectado algunos dispositivos de entrada y salida. Notarás que tenemos dos dispositivos de entrada diferentes,}0
y}1
. Esto significa que esta función toma 2 entradas. También notará que hay dos instancias del}1
dispositivo. Al llamar a la función, ambas celdas contendrán el mismo valor. El}0
dispositivo de entrada está directamente encima de un\/
dispositivo, esto actúa como un basurero y elimina cualquier canica que caiga sobre él inmediatamente.Echemos un vistazo a lo que le sucede a una de las canicas colocadas en la placa por los
}1
dispositivos de entrada:Caerá en el primer tic y golpeará el
=9
dispositivo. Esto compara el valor de la canica con 9 y permite que la canica se caiga si el enunciado se=9
evalúa. El mármol se empuja hacia la derecha si no.&0
y&1
son sincronizadores. Se aferran a las canicas que caen sobre ellas hasta que todos los demás&n
sincronizadores se llenen también. Como puede esperar, esto condicionalmente desencadenará un comportamiento diferente en alguna otra parte del tablero.Si te digo que
++
es un incrementador, ya deberías poder decir con qué se llenarán los diferentes sincronizadores. La izquierda&1
contendrá el valor de entrada}1
+ 1, la&0
siguiente contendrá 0 (00
es un lenguaje literal, representado en hexadecimal). El segundo&1
contendrá el valor 1 y el derecho&0
se rellena con unF7
, que resta 9 de un valor ya que la adición en Marbelous es el módulo 256.//
es un dispositivo deflector que empuja cualquier canica hacia la izquierda en lugar de dejarla caer.Poner todo esto junto te da esto: si la canica adentro
}1
es 9, los&0
sincronizadores se llenan. Esto hará que el valor 0 caiga en la{0
salida yF7
(o -9) en la{1
salida. Si}1
no es 9,{0
se rellenará con}1
+ 1 y{0
contendrá 1. También hay un{>
dispositivo, esta es una salida especial que genera una canica junto a una placa en lugar de debajo de ella. Esto se llenará}1
si es igual a 9.Bien, ahora para el grande. Esta placa no tiene un nombre explícito, ya que es la placa principal del archivo. Su nombre implícito es
Mb
. Deberías poder reconocer algunas células. Hay un dispositivo de entrada, algunos literales de lenguaje (00
yFF
). Hay algunos sincronizadores y hay un deflector. pasemos por esto pieza por pieza.Entonces, el valor de entrada (la entrada de la línea de comando ya que esta es la placa principal) comienza en la segunda celda desde la parte superior donde
}0
se encuentra. Se caerá y alcanzará el>0
dispositivo, que es otro dispositivo de comparación. cualquier canica mayor que 0 cae, cualquier otra canica se empuja hacia la derecha. (dado que las variables Marbelous no están firmadas, solo exactamente 0 será empujado hacia la derecha). Este mármol de valor cero golpeará el@6
dispositivo. Este es un portal y transporta la canica a otro portal correspondiente, en este caso justo encima de él. La canica 0 alcanzará el&0
sincronizador y activará algunas cosas en otro lugar.Si la canica no es 0, se cae, se desvía hacia la derecha por
\\
golpes--
que la disminuyen en uno y luego cae sobre/\
un clonador. Este dispositivo toma una canica y genera una copia a la derecha y otra a la izquierda. La izquierda se llevará hacia arriba a la otra,@0
donde la canica volverá a pasar por la misma secuencia. La izquierda será llevada a otra parte. Esto nos da un bucle, que disminuye la entrada de la línea de comando una vez por bucle y desencadena un comportamiento en cada bucle hasta que alcanza 0. Luego, desencadena algún otro comportamiento.Echemos un vistazo a lo que sucede con la canica presionada en
@4
cada bucle.Aquí hay 3 literales de lenguaje (
FF
), que inmediatamente caerán en portales. Estos portales los llevarán a tres de losII
dispositivos.II
se refiere al tablero:I
que definimos más abajo en el archivo. Como:I
tiene 2 dispositivos de entrada distintos, su representación en otra placa debe tener 2 celdas de ancho. Como tenemos 6 celdas que contienenII
, podemos decir que tenemos 3 instancias de esta función en el tablero.Las
FF
canicas (o 256 o -1 si lo desea) se sentarán en las celdas de entrada de la:I
función esperando hasta que haya suficientes canicas de entrada para iniciar la función (una más). Ahí es donde@4
entra el portal. Una copia de la entrada de línea de comando decrementada cae por allí en cada bucle. Esto activará el:I
tablero más a la izquierda . Inicialmente con los valores 256 (o -1) y cualquiera que sea la entrada de la línea de comando fue -1. El mármol izquierdo se colocará en los}0
dispositivos del:I
tablero y el derecho en el}1
. Si recuerda lo que hizo este tablero, podrá saber qué resultado tiene. Producirá una versión incrementada de la entrada derecha en la salida izquierda (y convierte un 9 en 0, no en 10) y generará 1 o -9 a la derecha.El valor incrementado será llevado de vuelta a la celda de entrada derecha por un portal, y el valor de la derecha cae en un sincronizador. Si un sincronizador ya está sosteniendo una canica, las dos canicas chocarán. Las canicas en colisión se suman en el módulo 256. Por lo tanto, los valores en los sincronizadores harán lo siguiente: comienzan vacíos, luego pasan a 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 y luego a 1 de nuevo (ya que se agrega 247 módulo 256).
También es posible que recuerde que una canica sale a la derecha cuando el valor de entrada vuelve a 0. Ya que las
:I
placas están una al lado de la otra, esto activará la placa a la derecha una vez. Esto llenará los tres sincronizadores con valores que son uno más alto de lo que deberían ser para ser una representación de shortlex de la entrada de la línea de comando, para cuando esto haya pasado a 0.También puede recordar que la
:O
función convierte un valor en el valor ascii del dígito que representa el valor -1. La salida de estasOO
celdas se caerá del tablero, que imprime sus caracteres ascii correspondientes en STDOUT.Entonces, ¿qué sucede cuando la canica de entrada de línea de comando llega a 0 y llena los
&0
sincronizadores? bueno, algunas canicas de valor 0 caen y activan los tres sincronizadores que contienen los dígitos (+ 1) del número shortlex en la parte inferior del tablero.&3
se activa primero, ya que contiene el dígito más significativo, luego viene&2
seguido de&1
. Esta canica se teletransporta al otro@5
dispositivo antes de eventualmente golpear la!!
celda, que termina el tablero.fuente
CJam,
1411 bytesPruébalo en línea.
Cómo funciona
Este enfoque se basa en gran medida en la respuesta de edc65 (con su permiso explícito ):
Ejecución de ejemplo
fuente
Pitón 2 (38)
(43)Sin sustitución de caracteres, solo aritmética.
Sin golf:
No tengo una buena razón por la cual la recursión funciona, solo ajusto este patrón a la lista de valores. Si cambiara cada uno
n-1
an
, obtendría la representación de dígitos regular.Para jugar al golf, utilizo
~-n
para calcularn-1
con mayor prioridad que/10
o%10
, ahorrando en parens. Eln*'_'
es solo para producir la cadena vacía cuandon=0
y cualquier otra cadena de lo contrario. El'_'
puede ser cualquier cadena para este propósito.fuente
Ruby,
7068666457 bytesDefine una función para ser llamada como
f[42]
. Aquí está el desglose aproximado del algoritmo:0
separado.¡Los créditos por la idea de usar una cadena de formato van a Falko!
Alternativamente, usando el enfoque de edc65:
Eso es 45 bytes y solo lo incluyo, porque no lo estoy golpeando con él. ;)
fuente
Haskell, 67 bytes
Esta solución básicamente agrega 1 el número dado de veces, en notación shortlex.
uso:
fuente
CJam, 16 bytes
Pruébalo en línea. Requiere al menos O (n) tiempo y memoria, así que deje 100501 para el intérprete fuera de línea ...
Cómo funciona
La idea básica detrás de este enfoque es calcular al menos N decimales shortlex en su orden natural y descartar todos menos el Nth. No muy eficiente, pero corto.
Ejecución de ejemplo
fuente
Bash + coreutils, 27 bytes
El puerto de la respuesta inteligente de @ edc65 , con las mejoras de @ Dennis :
Salida:
Respuesta anterior:
Bash + coreutils,
7154 bytesAquí hay una forma ligeramente diferente de hacerlo:
jot
salidas que aumentan los enteros hexadecimalestr
convierte esto a (0,1, ..., 8,9, b, ... f, 0a, 00,01, ..., 99,9b, ..., ff, 0aa, ..., 000 , ...)grep
simplemente filtra todas las líneas que contienen dígitos para dar (0,1, ..., 8,9,00, ..., 99,000 ....)sed
elimina todos menos la enésima líneased
cuenta los números de línea que comienzan en 1, por lo que los errores si se pasa 0)grep
, necesitamos generar más enteros de base 11 conseq
/dc
que el número de entrada. Repetir los dígitos de n es más que suficiente.Tenga en cuenta que una vez que se imprime el número de shortlex,
seq
continúa generando números hasta$1$1
, lo que disminuye especialmente para números de entrada más grandes: O (n²), creo. Podemos acelerar alseq
salir inmediatamente después de imprimir a un costo de 7 bytes:No hay requisitos de velocidad en la pregunta, así que voy con la versión más corta para mi respuesta principal.
fuente
s='jot -w%x $1$1|tr 0-9a a0-9|grep -P ^\\d+$|sed $1!d 2>-'; echo ${#s}
. Sospecho que podría estar usando Python para medir la longitud de la cadena, que trata el "\\" como un carácter.$a
parece ser innecesaria;cut -b2-<<<$[$1-~${1//?/8}]
debería funcionar bien.Pitón 2 -
84, 7066Enfoque alternativo (misma longitud):
fuente
Python 3, 107 caracteres
Esto no terminó ganando, pero pensé que era inteligente:
Defino un generador para toda la secuencia en 64 caracteres. Desafortunadamente, tengo que pasar por algunas contorsiones para obtener el enésimo elemento del generador ... si tan solo pudiera hacerlo
S=lambda n:G()[n]
.fuente
Pyth , 12
Otro puerto de la respuesta de @ edc65, quién es el claro ganador (IMO):
Paquete de prueba (Gracias a @DigitalTrauama):
Explicación:
fuente
[8, 8, 9] -> 889
). ¿Cómo haces eso?jk
convertirá su lista en una cadena y lav
convertirá en un int. Entoncesvjk[8 8 9]
dará el número 889.[2 -1] -> 19
y[1 11] -> 21
.Java 8, 60 bytes
La sorprendente respuesta JavaScript (ES6) del puerto de @ edc65 , ya que dudo que se pueda hacer más corto de manera aritmética en Java.
Pruébalo aquí.
fuente
Haskell , 57 bytes
Pruébalo en línea!
Construye una lista infinita de números de shortlex e índices para la respuesta.
g n
construye la enésima "generación" de números anteponiendo el siguiente dígito frente a cada uno de los números de la generación anterior.fuente
05AB1E , 7 bytes
Utiliza el reemplazo de edc65 por 8 trucos
Pruébalo en línea!
Explicación
fuente
Excel, 37 bytes
Usando el enfoque de @ edc65:
fuente
Jalea , 5 bytes
Pruébalo en línea!
Soy muy nuevo en Jelly, así que si puedes mejorar esto, ¡por favor comenta!
Explicación:
(Según el comentario de res anterior, el problema es equivalente a convertir el número a la base biyectiva 10)
fuente