Cada número se puede representar usando una secuencia de resto infinitamente larga. Por ejemplo, si tomamos el número 7 y realizamos 7mod2
, entonces 7mod3
, luego 7mod4
, y así sucesivamente, obtenemos 1,1,3,2,1,0,7,7,7,7,....
.
Sin embargo, necesitamos la subsecuencia remanente más corta posible que aún pueda usarse para distinguirla de todos los números más bajos. Usar 7 nuevamente, [1,1,3]
es la subsecuencia más corta, porque todas las subsecuencias anteriores no comienzan con [1,1,3]
:
0: 0,0,0,0...
1: 1,1,1,1...
2: 0,2,2,2...
3: 1,0,3,3...
4: 0,1,0,4...
5: 1,2,1,0...
6: 0,0,2,1...
Tenga en cuenta que [1,1]
no funciona para representar 7, porque también se puede usar para representar 1. Sin embargo, debe generar [1]
una entrada de 1.
De entrada y salida
Su entrada es un entero no negativo. Debe generar una secuencia o lista de la secuencia de restos de longitud mínima como se definió anteriormente.
Casos de prueba:
0: 0
1: 1
2: 0,2
3: 1,0
4: 0,1
5: 1,2
6: 0,0,2
7: 1,1,3
8: 0,2,0
9: 1,0,1
10: 0,1,2
11: 1,2,3
12: 0,0,0,2
30: 0,0,2,0
42: 0,0,2,2
59: 1,2,3,4
60: 0,0,0,0,0,4
257: 1,2,1,2,5,5
566: 0,2,2,1,2,6,6
1000: 0,1,0,0,4,6,0,1
9998: 0,2,2,3,2,2,6,8,8,10
9999: 1,0,3,4,3,3,7,0,9,0
Aquí están las primeras 10,000 secuencias , en caso de que esté interesado (los números de línea están apagados en 1).
Este es un código de golf , así que hágalo lo más corto posible en su idioma favorito. ¡Puntos de bonificación falsos por cualquier respuesta que sea rápida!
fuente
Respuestas:
Mathematica,
6053 bytesAlgo rápido (maneja 10000 en ~ 0.1 segundos, pero probablemente se quedará sin memoria para 100000).
El código arroja un error pero calcula el resultado correctamente.
Explicación
Hemos descubierto anteriormente en el chat que los divisores necesarios siempre se pueden determinar como la lista más corta
{1, 2, ..., n}
cuyo múltiplo menos común excede la entrada. Un breve argumento de por qué es eso: si el LCM es menor que la entrada, restar el LCM de la entrada dejaría todos los divisores sin cambios, por lo que la representación no es única. Sin embargo, para todas las entradas menores que el MCM, los restos serán únicos, de lo contrario la diferencia entre dos números con restos iguales sería un múltiplo más pequeño de todos los divisores.En cuanto al código ... como siempre, el orden de lectura de Mathematica es un poco divertido.
Esto nos da una lista
[1, 2, 3, ..., n+2]
de entradan
. El+2
es para asegurarse de que funciona correctamente para0
y1
.Mapa
2~Range~#
(azúcar sintáctico paraRange[2,#]
) sobre esta lista, así obtenemosEstas son listas de divisores candidatos (por supuesto, en general, eso es mucho más de lo que necesitaremos). Ahora encontramos el primero de ellos cuyo LCM excede la entrada con:
Más sintaxis:
x_
es un patrón que coincide con cualquiera de las listas y lo llamax
. El/;
adjunta una condición a ese patrón. Esta condición esLCM@@x>#
donde@@
aplica la función a la lista, es decir,LCM@@{1,2,3}
significaLCM[1,2,3]
.Finalmente, simplemente obtenemos todos los restos, haciendo uso del hecho de que
Mod
esListable
, es decir, se asigna automáticamente sobre una lista si uno de los argumentos es una lista (o si ambos son listas de la misma longitud):fuente
Jalea , 14 bytes
Esto utiliza el hecho de que la solución (si la hay) de un sistema de congruencias lineales es un módulo único del MCM de los módulos. Pruébalo en línea! o verificar todos los casos de prueba .
Cómo funciona
fuente
MATL , 24 bytes
Gracias a @nimi por señalar un error en una versión anterior de esta respuesta (ahora corregida)
Esto se queda sin memoria en el compilador en línea para los dos casos de prueba más grandes (pero funciona en una computadora con 4 GB de RAM).
Pruébalo en línea!
Explicación
Esto aplica la definición de manera directa. Para la entrada
n
se calcula una matriz 2D que contienemod(p,q)
conp
de0
an
yq
desde1
an+1
. Cadap
una es una columna y cadaq
una es una fila. Por ejemplo, con entradan=7
esta matriz esAhora la última columna, que contiene los restos de
n
, es un elemento comparado con cada columna de esta matriz. Esto producedonde
1
indica igualdad. La última columna es obviamente igual a sí misma y, por lo tanto, contiene todas. Necesitamos encontrar la columna que tenga el mayor número de iniciales , que no sea la última columna, y tomar nota de ese número de inicialesm
. (En este caso, es la segunda columna, que contiene lasm=3
iniciales). Para este fin, calculamos el producto acumulativo de cada columna:entonces la suma de cada columna
y luego ordenar de manera no creciente y tomar el segundo valor, que es
3
. Este es el deseadom
, que indica cuántos residuos tenemos que recoger.fuente
Jalea ,
1311 bytesEsto no ganará puntos de velocidad de brownie ... ¡ Pruébelo en línea! o verificar los casos de prueba más pequeños .
Cómo funciona
fuente
Python 3.5,
1179578 bytesRequiere Python 3.5 y sympy (
python3 -m pip install --user sympy
). Gracias a @Dennis para notificarme que Python 3.5 permite el*l
truco con argumentos predeterminados.fuente
M>n and l
al*(M>n)
.Python 2,
73706965 bytesUn programa completo @Dennis ahorró 4 bytes al mejorar la forma en que se maneja el cero.
fuente
Haskell,
66605150 bytesEjemplo de uso:
f 42
->[0,0,2,2]
. Es el algoritmo descrito en la respuesta de @Martin Büttner .Conservaré la versión anterior como referencia, porque es bastante rápida:
Haskell, 51 bytes
Se necesitan 0.03s
f (10^100)
en mi laptop de cinco años.Editar: @xnor encontró un byte para guardar. ¡Gracias!
fuente
h i=mod i<$>[2..2+sum[1|l<-scanl1 lcm[2..i],l<=i]]
Pyth,
51 bytes66 bytes¡Pruébalo!
Mucho una versión más alta velocidad de bytes 39 (no funciona para 0-2):
Parece funcionar para números absurdamente grandes como 10 10 3
Nota: esta respuesta no funciona para 0, 1 y 2.¡Solucionado!fuente
JavaScript (ES6),
8177 bytesEsto acumula recursivamente la respuesta hasta que el LCM excede el número original. El GCD también se calcula de forma recursiva, por supuesto.
Editar: Guardado 4 bytes gracias a @ user81655.
fuente
Ruby, 52 bytes
Esta solución verifica cada posible a
m
partir de 2, que es el resto que hace que la secuencia sea única. Lo que hace que el último seam
único no es el resto en sí, sino quem
es el último miembro del rango más pequeño(2..m)
donde el mínimo común múltiplo (LCM) de ese rango es mayor quen
. Esto se debe al Teorema del resto chino, donde para determinar de forma única qué númeron
es con un número de restos, el MCM de esos restos debe ser mayor quen
(si seleccionan
de(1..n)
; si seleccionan
dea..b
, el LCM solo necesita ser mayor queb-a
)Nota: pongo
a<<n%m
al final del código porqueuntil n<t=t.lcm(m+=1)
los cortocircuitos antesa
han recibido el último elemento para hacerlo único.Si alguien tiene alguna sugerencia de golf, hágamelo saber en los comentarios o en el chat PPCG .
No golfista:
fuente
Julia,
3633 bytesPruébalo en línea!
fuente
Python 3.5,
194181169152149146 bytes:(¡ Gracias a @ Sherlock9 por 2 bytes! )
Funciona perfectamente y también es bastante rápido. Calculando para la secuencia mínima restante de
100000
salidas[0, 1, 0, 0, 4, 5, 0, 1, 0, 10, 4, 4]
y tomó solo unos 3 segundos. Incluso fue capaz de calcular la secuencia para la entrada1000000
(1 millón), la salida[0, 1, 0, 0, 4, 1, 0, 1, 0, 1, 4, 1, 8, 10, 0, 9]
y tardó unos 60 segundos.Explicación
Básicamente, lo que hace esta función es, en primer lugar, crear una lista,
y
con todosj mod i
dondej
está cada número entero en el rango0=>7
(incluyendo 7) yi
es cada número entero en el rango0=>100
. Luego, el programa entra en unwhile
bucle infinito y compara la misma cantidad de contenido de cada sublista dentro de las sublistas primera a última dey
(y[:-1:]
) con la misma cantidad de elementos en la última sublista (y[-1]
) de la listay
. Cuando la sublistay[-1]
es diferente a cualquier otra sublista, el bucle se separa y se devuelve la secuencia mínima restante correcta.Por ejemplo, si la entrada es 3,
y
sería:Luego, cuando entra en el ciclo while, compara cada sublista en la lista
y[:-1:]
con el mismo número de elementos en la sublistay[-1]
. Por ejemplo, primero compararía[[0],[1],[0]]
y[1]
. Como la última sublista está en el resto dey
, continuaría y luego compararía[[0,0],[0,1],[0,2]]
y[1,0]
. Dado[1,0]
que ahora NO está en el resto dey
ese orden específico , esa es la secuencia mínima de recordatorio y, por[1,0]
lo tanto, se devolverá correctamente.fuente
y[:c:]
es lo mismo quey[:c]
C89, 105 bytes
Compila (con advertencias) usando
gcc -std=c89
. Toma un solo número en stdin y genera la secuencia de residuos separados por espacios en stdout.fuente
C, 89 bytes
Compilar con gcc. Pruébelo en línea: n = 59 , n = 0 .
fuente