Secuencias de Skolem
Una secuencia de Skolem es una secuencia de 2n
números donde cada número i
entre 1
y n
ocurre exactamente dos veces, y la distancia entre las dos ocurrencias i
es exactamente i
pasos. Aquí hay algunos ejemplos de secuencias de Skolem:
1 1
1 1 4 2 3 2 4 3
16 13 15 12 14 4 7 3 11 4 3 9 10 7 13 12 16 15 14 11 9 8 10 2 6 2 5 1 1 8 6 5
Las siguientes secuencias no son secuencias de Skolem:
1 2 1 2 (The distance between the 1's is 2, not 1)
3 1 1 3 (The number 2 is missing)
1 1 2 1 1 2 (There are four 1's)
Objetivo
Escriba un programa, función o expresión para contar el número de todas las secuencias de Skolem de una longitud determinada. Más explícitamente, su entrada es un número entero n
, y su salida es el número de secuencias de longitud de Skolem 2n
. Esta secuencia tiene una entrada OEIS . Para n = 0
, puede regresar cualquiera 0
o 1
. Los primeros valores, a partir de 0
, son
0, 1, 0, 0, 6, 10, 0, 0, 504, 2656, 0, 0, 455936, 3040560, 0, 0, 1400156768
Reglas y puntaje
Este es el código de golf. El formato de salida es laxo dentro de lo razonable.
0, 1, 0, 0, 6...
en su pregunta? ¿Es ese el fragmento de código, si es así, qué idioma es ese?0
? Si vas a admitir0
como una entrada válida, entonces la salida debería ser1
.Respuestas:
GolfScript,
4846 caracteresLa versión más rápida ( prueba en línea ): se ejecuta bastante rápido, por ejemplo,
n=8
demora aproximadamente dos segundos. Y el enfoque elegido toma muy pocos personajes.Esta versión también funciona con máscaras de bits. Construye la posible matriz de resultados de 1 en adelante, es decir, para
n=3
:Mientras que algunos resultados (como 000011) tienen dos posibles continuaciones, otros (es decir, 001100) no tienen ninguno y se eliminan de la matriz de resultados.
Explicación del código:
fuente
Expresión J, 47 caracteres
Ejemplo:
Toma alrededor de 30 segundos
y=:5
en mi máquina.El algoritmo es tan lento como puede ser:
~.(i.!+:y)A.,~>:i.y
genera cada permutación de1 2 .. y 1 2 .. y
y elimina entradas duplicadas((=&{:+.2-#@])#;.2)\"1
calcula:(...)\"1
para cada prefijo de cada fila:#;.2
cuenta los elementos antes de cada aparición del último elemento#@]
cuenta la cantidad de cuentas (es decir, la cantidad de ocurrencias del último elemento)=&{:
determina la "igualdad" "del" "último elemento" s de la lista de conteo y de la lista original.+.
es un OR lógico.=&{:+.2-#@]
lee "o los últimos elementos [de la lista de conteo y la lista original] son iguales, o solo hay un elemento [en la lista de conteo] en lugar de dos".*/"1
se multiplica (AND lógico) sobre las filas de la tabla de condiciones, determinando qué permutaciones son secuencias de Skolem.+/
suma los unos y los ceros juntos.fuente
GolfScript (46 caracteres)
Esta es una expresión que toma datos en la pila. Para convertirlo en un programa completo que reciba información sobre stdin, anteponer
~
Es bastante ineficiente: la mayoría de los ahorros que obtuve al jugar golf de 56 caracteres sin golf fueron expandiendo el rango de bucles de formas que no introducen resultados incorrectos pero hacen un cálculo de desperdicio.
El enfoque es el enmascaramiento bit a bit de los productos cartesianos. Por ejemplo (el uso de binario para las máscaras) para
n=4
el código no protegido calcularía el xor de cada elemento en el producto cartesiano[00000011 00000110 ... 11000000] x [00000101 00001010 ... 10100000] x ... x [00010001 ... 10001000]
. Cualquier resultado con 8 bits solo se puede lograr con máscaras no superpuestas.Para optimizar el tamaño en lugar de la velocidad, el código acumula productos parciales (
S1 u S1xS2 u S1xS2xS3 ...
) y hace que cada producto sea de2n
elementos en lugar de solo los2n-1-i
que realmente pueden contribuir a una secuencia válida.Velocidad
La versión de golf funciona
n=5
en 10 segundos en mi computadora y más de 5 minutosn=6
. La versión original sin golf se calculan=5
en menos de un segundo yn=6
en aproximadamente 1 minuto. Con un filtro simple en resultados intermedios, puede calcularn=8
en 30 segundos. Lo he jugado a 66 caracteres (como programa - 65 caracteres como expresión) manteniendo los bucles lo más restringidos posible y filtrando colisiones intermedias:fuente
GolfScript, 49 caracteres
Espera el número
n
en STDIN. Este es el código de golf: no intente el código conn
más de 5.fuente
Sabio, 70
Esto es un poco más corto que mi original.
Cómo funciona:
Dada una matriz 0/1, el problema de cobertura exacta para esa matriz es encontrar un subconjunto de las filas que sumen (como enteros) al vector de todos. Por ejemplo,
tiene una solución
Mi enfoque favorito para los problemas es lanzarlos a un problema de cobertura exacto. Las secuencias de Skolem facilitan esto de manera eficiente. Hago un problema de cobertura exacto donde las soluciones están en biyección con secuencias de longitud de Skolem
2n
. Por ejemplo, una fila del problema paran=6
esdonde un 1 en posición
a < n
significa quea
se usa ese símbolo . Las posiciones restantes corresponden a ubicaciones reales en la secuencia. Una cubierta exacta corresponde a cada símbolo que se usa exactamente una vez, y cada ubicación se llena exactamente una vez. Por construcción, cualquier símbolok
en una ubicación está ak
espacios de distancia de su compañero.En Sage,
DLXCPP
es una implementación de "enlaces de baile": resuelve el problema exacto de la cubierta de una manera excepcionalmente elegante. Es uno de mis algoritmos favoritos, y estar en la superficie en Sage hace que la enumeración combinatoria sea una alegría.fuente
len(list(...))
ahorrará 4 caracteres.len(list(...))
para n = 16. Y mataría por completo el tiempo de ejecución.