Me he encontrado con una pregunta en el sitio de revisión de código que parece interesante. Creo que OP lo está haciendo mal, pero no puedo estar seguro ... ¡Así que vamos a resolverlo por él! (escriba un programa, no una función / procedimiento)
Entrada (stdin o similar):
Un entero x
en notación decimal. Es mayor que 1 y menor que 2 ^ 31.
Salida (stdout o similar):
Un entero y
en notación decimal. El producto x * y
en representación decimal debe contener solo dígitos 0 y 1. Debe ser el número mínimo mayor que 0.
Nota: la salida no está limitada: si el mínimo y
es de alrededor de 10 ^ 100, su programa debe generar todos sus 100 dígitos (no sé si hay un límite razonable, como 2 ^ 64, encendido y
) no lo resolvió )
Su programa debe finalizar en un tiempo razonable (1 segundo? 1 hora? - algo así) para todos x
en el rango.
Prima:
Si su programa no tiene un límite en el tamaño de la entrada (excepto RAM) y tiene una complejidad polinómica, multiplique el conteo de bytes de su programa 0.8
y redondee hacia abajo.
Ejemplo: entrada 2
; salida 5
, porque 2 * 5 = 10
Ejemplo: entrada 21
; salida 481
, porque 21 * 481 = 10101
Descargo de responsabilidad: no soy responsable de la pregunta en el sitio de revisión de código. En caso de cualquier discrepancia, solo la descripción anterior debe considerarse como la especificación adecuada.
Respuestas:
Pyth, 9 bytes
Demostración
Para cada múltiplo, conviértalo en una cadena, reste los dígitos
10
(usando el práctico int de Pyth para emitir cadenas en este caso) y luego niegue lógicamente el resultado, terminando la búsqueda solo cuando se encuentre el múltiplo correcto.Solución extra, 10 bytes:
Esta solución realmente comprueba si la representación de cadena del número puede tratarse como un número binario (
i ... 2
) y termina cuando no se produce un error en este intento.fuente
Python 2, solución eficiente, 99
Gracias Sp3000 por algunos consejos de golf.
Reto a todos los demás a publicar (en sus propias respuestas) cuánto tiempo lleva obtener el resultado para la entrada
72
o99
:) Si son realmente rápidos, intente algo como el79992
siguiente (todavía <1 segundo aquí).Explicación:
Pensé que esto no era necesario (ya que el código es bastante legible), pero recibí una solicitud, así que aquí va:
La primera idea es que un número de aspecto binario es una suma de 1 o más potencias diferentes de 10. Por lo tanto, podemos intentar agregar varias potencias de 10 de diferentes maneras hasta obtener el resto 0.
Si lo hacemos ingenuamente, es lo mismo que generar todos los números de aspecto binario y probarlos. Pero muchos restos serán lo mismo. Una mejor manera es registrar solo el número más pequeño que dio un cierto resto, y sucesivamente agregar mayores potencias de 10 a los números que registramos. Eso es lo que hace el programa.
d
es un diccionario / mapa donde las claves son residuos y los valores son números de aspecto binario con ese resto. La inicialn:0
es un caso especial: se supone que es0:0
para que podamos comenzar a agregarle poderes, pero el algoritmo se detiene al encontrar la clave 0, por lo que utilicé en sun
lugar, lo que garantiza que tendrá el mismo efecto y no interferirá con los otros valores.Luego comenzamos a agregar potencias de 10 (almacenadas
k
) a todos los números existentes y registramos los restantes. Agregamosk
al resto:(x+k)%n
y al número:,d[x]+k
y lo registramos solo si es un resto nuevod.setdefault(…)
, luego pasa a la siguiente potencia:k*=10
y repite hasta obtener la clave 0:while min(d)
Al final,
d[0]
da el número de aspecto binario que tiene el resto 0 modn
, por lo que lo dividimos porn
para obtener la solución.Nota: el programa se puede hacer más eficiente evitando grandes números (registrando exponentes en lugar de potencias de 10 y calculando los restos de potencias de valores anteriores), pero es código golf, así que ...
De hecho, aquí, escribí una versión más rápida:
fuente
Python 2, 47 bytes
Rastrea el número de entrada
n
y el múltiplo actuala
. Cuandoa
parece binario, genera la relacióna/n
. Para verificar que un número esté compuesto por0
'sy1
', comparamos el carácter máximo en su representación de cadena con'1'
.Utiliza en
str(a)
lugar de`a`
evitar largos que terminan enL
. Lamentablemente,'L'
es más grande que'1'
.fuente
Perl, 27 bytes
Contando el shebang como uno, la entrada se toma de stdin.
Uso de muestra
Perl, 25 bytes
Una mejora de dos bytes por @skmrx .
En lugar de verificar con una expresión regular, esto intenta evaluar el producto como un literal binario. Al fallar, pasa al siguiente. Por lo general, la
oct
función se usaría para este propósito, pero recorta silenciosamente dígitos no válidos, lo que no es útil en este desafío.Perl, 40 bytes
Una solución mucho más eficiente. Repetimos las representaciones binarias, las interpretamos como base 10 y luego verificamos la divisibilidad. Los tiempos de ejecución para todos los valores por debajo de 100 son insignificantes.
Uso de muestra
fuente
eval"0b".$_*++$\||redo}{
use bigint
para admitir los grandes números que OP ha ordenado que seoct'0b'.++$\*$_
, pero recorta silenciosamente dígitos no válidos. No pensé en usareval
en su lugar.Javascript, 43 bytes
Esto terminó mucho más corto de lo que pensaba. Básicamente aumenta
y
hasta 1 hastay * (input number) = (binary-looking number)
. Obviamente bastante ineficiente.Javascript (solución más eficiente), 53 bytes
Este se incrementa
y
en binario hastay / (input number) = (number without a remainder)
. Entonces sale(number without a remainder)
.Javascript (solución aún más eficiente), 76 bytes
Este combina los dos métodos anteriores descritos anteriormente. Comprueba los incrementos
y
hasta quey * (input number) = (binary-looking number)
(lo que significa que la salida esy
) Oy / (input number) = (number without a remainder)
(lo que significa que la salida es(number without a remainder)
).fuente
Haskell,
7270646058 bytesEditar: @ Jan Dvorak me ayudó a ahorrar 4 bytes.
Editar: @BlackCap guardó 2 bytes cambiando a
do
notación. ¡Gracias!fuente
main=print.f=<<readLn
main=readLn>>= \x->print$[y|y<-[1..],all(<'2')$show$x*y]!!0
main=do x<-readLn;print$[y|y<-[1..],all(<'2')$show$x*y]!!0
Python 2,
67656360 bytes¡Gracias a Status por 2 bytes y Shebang por 5 bytes!
fuente
b=1
any(c in`a*b`for c in'23456789')
not c in`a*b`for c in'10'
funcionaría?set('a*b')&set('23456789')
.`
produce unL
por largos y'L'>'1'
.JavaScript (ES6) 222
250Usando matemática de precisión arbitraria (operando en cadenas de dígitos decimales)
Esto se puede jugar un poco más(hecho), pero me gusta el hecho de que no se limita a los números estándar JS (17 dígitos decimales de precisión) y que es rápido.Pruebe a ejecutar el fragmento a continuación en un navegador compatible con EcmaScript 6. El tiempo es aceptable hasta 9998: no intente con 9999 y sea paciente con 999.
Más legible
Esta es la primera versión, con módulo y división larga como funciones separadas.
fuente
Perl, 45 bytes
fuente
Pyth, 10 bytes
Ejecuta el código.
Un puerto de mi respuesta de Python , tomando de Maltysen el uso de
f
para encontrar el primer número positivo que cumple una condición.fuente
PHP, 50 bytes
Algunos casos de prueba
fuente
CJam,
191716 bytesPruébalo en línea
Solución de fuerza bruta, probando valores secuencialmente hasta encontrar uno que cumpla la condición.
La última versión ahorra 2 bytes gracias al uso en
As
lugar de"01"
crear una cadena que contenga0
y1
, como lo sugiere @aditsu. La solución completa propuesta en el comentario guarda otro byte, pero se ve bastante diferente de la mía, por lo que no quería publicarlo a mi nombre.Y 1 byte más guardado por @Dennis.
Explicación:
fuente
li0{1$+_sAs-}g\/
As
para construir la cadena, ya que es un cambio muy local, que en retrospectiva (que siempre es mucho más fácil ...) debería haber pensado.li:V!{)_V*sAs-}g
Además,0{)_easi*sAs-}g
(15 bytes) funciona con el intérprete de Java y los argumentos de la línea de comandos.Python
32,10176 Bytes-25 bytes gracias a @aditsu
casi tan eficiente como la solución de @ aditsu
En lugar de intentar recorrer los múltiplos en orden creciente, estoy tratando de recorrer los productos, que estoy generando en forma 'binaria'.
fuente
n=input()
),while b%n:
(inicializarb
a 1), sin sangríabin(m)[2:]
debe ser más corto que la cadena de formato. La doble asignación tambiénb=m=1
debería ahorrar algunos.Java, 213 bytes
Utiliza
BigInteger
sy, como tal, tiene (para todos los propósitos y propósitos razonables) un tamaño de entrada ilimitado. Sin embargo, no estoy seguro de la complejidad, eso depende de la tasa de crecimiento de nuestra función aquí.Gracias a geobits e ypnypn por guardar un puñado de bytes.
fuente
static
modificador al método.b.ONE
y!(b.multiply(c)+"")
(en lugar detoString()
).C, 3675 bytes
Adiós a Code Golf ...
Ejecutar sin parámetros de línea de comandos - se pone
n
destdin
y envía el resultado astdout
. Ejecutar con un nombre de archivo: escribe los resultadosn = 1...10000
en ese archivo y mide el tiempo.Rendimiento durante 1 ... 10000: 140 ms
Este código utiliza el algoritmo propuesto por aditsu , implementado en C para la velocidad. No hice ningún esfuerzo para jugar golf, por lo que el código sería más fácil de leer.
Lo implementé primero en C ++ usando
std::map
para registrar los resultados de la búsqueda, y fue bastante lento. Sin embargo, las teclas de losmap
son enteros consecutivos (los llamomod
s, porque representan números de módulon
), por lo que es natural usar una matriz, por lo que lo reescribí en C.Una optimización adicional se refiere a los valores de la asignación: para evitar almacenar un número entero grande para cada uno
mod
, almaceno solo la potencia más grande de 10 allí; es solo información suficiente para ir a la anteriormod
. Entonces, la matriz es realmente un árbol / gráfico de búsqueda. Cuando llega la búsquedamod = 0
, el rastreo de los nodos del árbol hasta la raíz proporciona los poderes de 10 en orden descendente.Dado que la búsqueda generalmente se detiene bastante rápido, con solo una pequeña fracción de nodos visitados, necesito una lista de nodos activos. Se implementa como una matriz
mod_list
con longitudmod_list_length
.Algunas estadísticas de tiempo de ejecución (en una máquina con 16 GB de RAM, lo que parece ser importante para grandes
n
, porque el programa asigna5n
bytes de memoria):99999999
- 2 segundos999999999
- 27 segundos (el resultado es111111111222222222333333333444444444555555555666666666777777777888888889
- probablemente el mayor resultado posible para enteros de 32 bits)2147483647
- 26 segundos (el resultado es4661316525084584315813
)1999999998
: 52 segundos (probablemente el mayor tiempo de ejecución posible para enteros de 32 bits)fuente
C ++ 11, muchos bytes, muy rápido, wow (1.5 s en 1999999998, 0.2 s en 1… 10000)
(Versión de Python Golfed a continuación).
Comenzamos con un concepto similar a la solución de aditsu, donde creamos inductivamente una colección de residuos modulares accesibles en n pasos. Pero en lugar de esperar hasta encontrar el resto 0, verificamos dos restos encontrados a y b de modo que a · 10 ^ n + b = 0. Este enfoque de encuentro en el medio reduce a la mitad la profundidad del árbol de búsqueda, por lo que es mucho más rápido en entradas grandes y usa mucha menos memoria.
Algunos puntos de referencia:
Código:
Python, 280 bytes (8.6 segundos en 1999999998 con PyPy)
fuente
Mathematica 115 bytes
fuente
Java 156 bytes
Enormes gracias a aditsu :)
fuente
[]
,y
puede serlong
demasiado, olvidó elx*y+""
truco en el segundo programa, use enisEmpty
lugar de verificar la longitud, use en;
lugar de{}
long
no acortaría el códigolong x=…,y;
y
debe comenzar desde 1, puede inicializarlo en la declaración, su clase no necesita ser pública y puede pasary++
a lax*y
parte (x*y++
)Pyth -
1211 bytesUtiliza un filtro con arg numérico para obtener el primer número natural que cumple el predicado, el valor predeterminado es 1, que es lo que queremos. Setwise diff para verificar si solo ceros y unos.
Test Suite .
fuente
"01
. Guarda un personaje.R, 45 bytes
Uso:
fuente
Java,
198193181 bytes¡Gracias a @aditsu por reducir 5 bytes Y aumentar el rango de números comprobables!
Tenga en cuenta que algunos valores se repiten negativamente debido a cómo Java analiza los enteros. BigInteger podría eludir esto, pero la bonificación era simplemente menos valiosa.
Sé que no voy a ganar, pero espero que esto inspire otras respuestas más cortas.
Sin relieve:
fuente
Long
sea más corto queInteger
:)C,
107101 bytes (10599 bytes para 32 bits)Hay una clara falta de respuestas en C en el código de golf. De hecho, C no es la mejor opción para escribir el programa más pequeño posible, pero no es tan malo:
Puede prescindir de los #incluidos, pero todas las definiciones de funciones serán implícitas. El principal inconveniente es que esto supone que todas las funciones devuelven ints. Este es un problema en máquinas de 64 bits para funciones que realmente devuelven un puntero. Si está en una máquina de 32 bits, se pueden eliminar 2 bytes de la solución anterior:
Versión algo más legible:
fuente
Tiempo de C # cerca de 5 segundos (1 a 10000)
Según lo solicitado, aquí hay un programa de golf C # que responde al desafío original. Entrada como argumento de línea de comando, salida a la consola.
Luego, en cuanto a la recompensa: la recompensa debería ir a aditsu, ya que creo que su algoritmo no puede ser vencido en términos de rendimiento. Pero la respuesta automática de Anatolyg también es sorprendente.
Aquí está mi implementación rápida en C #. Supongo que en C ++ podría ser más rápido (tal vez 2x). Compilado y probado con Visual Studio 2010, .NET framework 4, 64 bits, redirigiendo la salida a nul. Hora: 00: 00: 05.2604315
fuente
Keys.Reverse
? ¿Es importante el orden? Si es solo para evitar problemas de concurrencia,ToList
es más corto.C con GMP (621 bytes, rápido)
Intenté ser rápido y corto, pero me favoreció rápido. Esta implementación utiliza una versión ligeramente mejorada de la aceleración teórica de números que mencioné en un comentario sobre la respuesta de aditsu .
Guardar como
pseudobinary.c
y compilar congcc pseudobinary.c -lgmp -o pseudobinary
. Tenga en cuenta que esto asigna tanta memoria para entradas grandes que necesitará compilarla para una plataforma de 64 bits.Versión de bucle para temporización (751 bytes)
Versión de bucle sin golf
fuente
C + GMP, 669
Esto es realmente rápido para números pequeños; comienza a ahogarse cuando el resultado tiene más de 64 dígitos.
Versión que se repite en 10000 (671 bytes):
Aquí hay algunos comandos para probar mi código, así como el de mis competidores, y los resultados en mi computadora portátil:
fuente
T-SQL,
164156155154159 bytes(-1 byte. ¡Gracias Jonathan!)
(-1 más porque ¿por qué tengo espacios finales en las líneas? SMH)
(+5 se dio cuenta de que mi golf rompió cosas)
No sé por qué sigo volviendo a estas preguntas donde se supone que debo convertir a Binary ... T-SQL no sabe cómo hacerlo bien.
En cualquier caso, aquí hay un SQLFiddle .
Sin golf:
La mayoría de estas cosas son necesarias para escribir una función en T-SQL, que yo sepa.
Cree una cadena en blanco que vamos a almacenar como nuestro número binario.
Guarde el valor de entrada para usar al final. Parece que debería haber una manera de usar la entrada original incluso si cambiamos el valor, pero no puedo encontrar una.
Entonces tomamos nuestra entrada original, MOD con 2 para encontrar el resto, y ese será nuestro próximo dígito más pequeño. Por ejemplo, 5% 2 = 1
Luego tomamos nuestro número y lo dividimos por la mitad. Debido a que es un
int
tipo, lo redondea al número entero más cercano, por lo que 5/2 = 2. FIN Luego lo recorremos hasta que el valor sea 0. Entonces terminamos con 5% 2 = 1 5/2 = 2 2 % 2 = 0 2/2 = 1 1% 2 = 1 1/2 = 0 que nos da nuestro valor de cadena binaria de 101.Tomamos nuestra cadena binaria y la convertimos de nuevo en una
int
.Devolvemos nuestra cadena binaria
int
dividida por nuestro valor original, según el origen de la pregunta.fuente
@>0 SELECT
no es omitible?Ruby, 46 bytes
Realmente debería eliminar el ciclo while con un ciclo alternativo.
Editar: ¡Gracias @manatwork por recortar 1 byte!
Edit2: ¡Gracias @histocraft por los locos 9 bytes!
Editar: ¡Gracias @manatwork nuevamente por recortar 7 bytes!
fuente
z!=z[/[01]+/]
Es más corto.z[/[^01]/]
Es aún más corto.z="#{n.to_i*k+=1}"while z[/[^01]/]
Scala, 114 bytes
Versión legible
fuente
Gawk4 fuerza bruta, 28 + 2 = 30 bytes
Necesita ser llamado con la
-M
opción de usar números grandes. Por supuesto, esto es ridículamente lento, el uso de grandes números lo ralentiza aún más, pero en teoría la entrada no está limitada y el uso de RAM es insignificante.Ejemplo de uso (si tiene tiempo que perder
;)
)gawk4 optimizado, 69 + 2 = 71 bytes
Bueno, esto terminó siendo un clon de la respuesta de aditsu. Después de mirar esta pregunta , todavía estaba descubriendo cómo codificar la parte de la suma de subconjuntos, cuando no pude resistirme a mirar las otras respuestas aquí.
En awk, los elementos de matriz tienen el comportamiento (¿extraño?) De que si compara un elemento no existente con algo, de alguna manera se inicializa como vacío antes de ser comparado (admito que no estoy muy seguro de lo que está sucediendo allí). Así que después de comprobar
!a[0]
lasfor(i in a)
salidas de bucle incluso sin inicializara[$0]
a0
como lo hizo aditsu.Por supuesto, la
-M
opción también debe usarse para esto.Aunque es bastante rápido, sigue siendo notablemente más lento que Python. Para
79992
esto toma alrededor de 14 segundos en mi 2GHz Core2Duo. Y no diría que funciona para entradas de hasta 2 ^ 31, porque en el peor de los casos tiene que construir una matriz de números grandes (gawk4 usa GMP para esto), que tiene el tamaño del número de entrada. Como 'bono', las matrices grandes son muy, muy lentas en awk ...fuente
Dyalog APL , 25
Esto define un programa adecuado "P" (no solo una función sin nombre):
2∘
comience con 2 como argumento izquierdo0::
si hay algún error ...⍵∇⍨1+⍺
llámese a sí mismo con un argumento izquierdo incrementado,⍺×⍵
multiplique los argumentos izquierdo y derecho,⍕
haga que la cadena⍎¨
haga que cada carácter sea un~
intento de número lógico NO (si falla, vaya al manejo de errores anterior, de lo contrario ...)⍺⊣
devuelve el argumento izquierdo actual.fuente