Introducción
A229037 tiene una trama bastante intrigante (al menos para los primeros términos):
Existe la conjetura de que podría tener algún tipo de propiedad fractal.
¿Cómo se construye esta secuencia?
Definir a(1) = 1, a(2) = 1
entonces para cada n>2
encontrar un positivo mínimo número entero a(n)
tal que para cada secuencia aritmética 3 plazo n,n+k,n+2k
de índices, los valores correspondientes de la secuencia a(n),a(n+k),a(n+2k)
es no una secuencia aritmética.
Reto
Dado un entero positivo n
como entrada, genera los primeros n
términos a(1), ... , a(n)
de esta secuencia. (Con cualquier formato razonable. Los posibles caracteres / cadenas iniciales / formativos son irrelevantes).
Hay fragmentos disponibles para generar esta secuencia, pero creo que otros enfoques podrían ser más fáciles de encontrar / más adecuados para ciertos idiomas.
Por favor, háganos saber cómo funciona su programa. Si se cruza con un algoritmo particularmente eficiente, es posible que desee mencionarlo también, ya que permitiría trazar más términos de la secuencia en un tiempo más corto.
Primeros casos de prueba:
1, 1, 2, 1, 1, 2, 2, 4, 4, 1, 1, 2, 1, 1, 2, 2, 4, 4, 2, 4, 4, 5, 5, 8, 5, 5, 9, 1, 1, 2, 1, 1, 2, 2, 4, 4, 1, 1, 2, 1, 1, 2, 2, 4, 4, 2, 4, 4, 5, 5, 8, 5, 5, 9, 9, 4, 4, 5, 5, 10, 5, 5, 10, 2, 10, 13, 11, 10, 8, 11, 13, 10, 12, 10, 10, 12, 10, 11, 14, 20, 13
Más casos de prueba:
a(100) = 4
a(500) = 5
a(1000) = 55
a(5000) = 15
a(10000) = 585
Todos los términos n=100000
disponibles están disponibles aquí: https://oeis.org/A229037/b229037.txt
Gracias @ MartinBüttner por la ayuda y el aliento.
Respuestas:
Python 2, 95 bytes
El truco principal está en generar los números que el nuevo valor debe evitar. Manteniendo la secuencia invertida hasta ahora
l
, veamos qué elementos podrían formar una progresión aritmética de tres términos con el valor que estamos a punto de agregar.Los otros números son los miembros emparejados de
l
y cada segundo elemento del
, entonceszip(l,l[1::2])
. Si este par es,(b,c)
entonces(a,b,c)
ocurre la progresión aritméticaa=2*b-c
. Después de generar el conjunto dea
's para evitar, el código toma el mínimo del complemento, lo imprime y lo antepone a la lista. (En realidad, el cálculo se realiza con números disminuidos en 1 e impresos 1 más alto, para permitir querange(n)
sirva como un universo de candidatos).fuente
Mathematica, 95 bytes
Ciertamente no es el enfoque más golfista, pero en realidad es bastante eficiente, en comparación con los algoritmos que probé en la página OEIS.
En lugar de verificar todos los valores prohibidos para cada s (n) cuando llegamos allí, estoy usando un enfoque basado en tamiz. Cuando encontramos un nuevo valor s (n) verificamos inmediatamente qué valores prohíbe para m> n . Luego, solo resolvemos la s (n + 1) buscando el primer valor que no estaba prohibido.
Esto puede hacerse aún más eficiente cambiando el condicional
--i>0
a2n-#<=--i>0
. En ese caso, evitamos verificar los valores prohibidos para n mayor que la entrada.Para una versión algo más legible, comencé con este código, que almacena los resultados hasta
max
en una funciónf
, y luego lo llevé a la función pura de una línea anterior:fuente
Haskell,
90,89,84, 83 bytesProbablemente se pueda jugar más al golf, pero este sigue siendo un
primerintento decente :Sin golf:
Esta es una implementación simple que devuelve '0' para fuera de los límites. Luego, para cada valor posible, comprueba que para todos k <= n y en los límites, [x, a (xk), a (x-2k)] no es una secuencia aritmética.
Límite superior en la complejidad del tiempo (utilizando el hecho de la página OEIS de que a (n) <= (n + 1) / 2:
No estoy seguro de cuán bueno es este límite porque calcular los primeros valores 1k de 't' y usar un modelo lineal en los registros de los valores dio appx. O (22 ^ n), con valor p <10 ^ (- 1291), en caso de que sea importante.
En un nivel de implementación, compilando con '-O2', tardó ~ 35 minutos en calcular los primeros 20 valores.
fuente
Brachylog ,
3331 bytesPruébalo en línea!
En caso de que sea importante: el golf de 2 bytes fue posible gracias a una función que solicité después de trabajar en este desafío.
Explicación
Generamos iterativamente la secuencia como una lista en orden inverso, por ejemplo
[2,2,1,1,2,1,1]
, y la invertimos al final.Hay un par de predicados anidados aquí. Miremos de adentro hacia afuera. El primero
ġh₃hᵐs₂ᶠ-ᵐ=
, toma una subsecuencia candidataa(n),a(n-1),...,a(0)
y determina sia(n),a(n-k),a(n-2k)
es una secuencia aritmética para algunosk
.Por ejemplo, con entrada de
[1,2,1,1,2,1,1]
:El siguiente predicado hacia afuera,
~b.hℕ₁≜∧.¬{...}∧
ingresa una subsecuenciaa(n-1),a(n-2),...,a(0)
y genera la siguiente subsecuencia más grandea(n),a(n-1),a(n-2),...,a(0)
.Finalmente, el predicado principal
;Ė{...}ⁱ⁽↔
toma un número de entrada y genera muchos términos de la secuencia.fuente
Ruby , 71 bytes
Pruébalo en línea!
Genera todos los valores prohibidos, luego toma el complemento de esa matriz en (1..n) y toma el primer valor del resultado. Eso significa que estoy asumiendo que
a[n] <= n
para todo n, lo cual se prueba fácilmente usando inducción (si los primeros términos n / 2 son todos menores que n / 2, entonces no puede haber una progresión aritmética que conduzca a n).El truco sintáctico aquí también es ligeramente interesante:
*a
se utiliza para inicializar una matriz de argumentos adicionales (que se ignorarían si pasáramos alguno), y luegoa.fill
muta la matriz de argumentos y la devuelve implícitamente.fuente
a[s-o]
ya[s-2*o]
, puede usara[s-=1]
ya[s-o]
APL (Dyalog Extended) , SBCS de 37 bytes
Muchas gracias a Adám por su ayuda para escribir y jugar golf en esta respuesta en The APL Orchard , un excelente lugar para aprender el idioma APL. Pruébalo en línea!
Editar: -6 bytes gracias a Adám
Explicación
APL (Dyalog Unicode) ,
433938 bytes SBCSAquí hay una solución más rápida pero menos deportiva que puede calcularse
⍺(10000)
en unos segundos.Pruébalo en línea!
fuente
MATLAB,
156147 bytesFinalmente llegué a jugar golf un poco:
Sin golf:
La entrada se lee desde STDIN, y la impresión se realiza automáticamente con
ans=
y cosas adjuntas. Espero que esto califique como salida "razonable".Esto también es una solución basada en tamiz: la variable
s(i,:)
mantiene un registro de los valores de secuencia que están prohibidas paraa(i)
. Eltry-catch
bloque es necesario para tratar el caso de unas
matriz vacía (que significa cero completo) : en este caso, el valor más bajo de1
ya está permitido.Sin embargo, la necesidad de memoria (¿o tiempo de ejecución?) Se vuelve bastante desordenada arriba
N=2000
. Así que aquí hay una solución no competitiva y más eficiente:En esta implementación, la
s
matriz nuevamente contiene valores prohibidos, pero de manera ordenada, sin ningún bloque cero (que están presentes en la versión de la competencia). El vector índicei
realiza un seguimiento de la cantidad de vectores prohibidoss
. A primera vista, las celdas serían excelentes para realizar un seguimiento de la información almacenadas
, pero serían lentas y no podríamos indexar un montón de ellas al mismo tiempo.Una característica desagradable de MATLAB es que si bien puede decir
M(1,end+1)=3;
y expandir automáticamente una matriz, no puede hacer lo mismo con la indexación lineal. Tiene sentido (¿cómo debería MATLAB conocer el tamaño de matriz resultante, en cuyo marco debería interpretar los índices lineales?), Pero aún así me sorprendió. Esta es la razón de la línea superfluas(N,max(i(j))) = 0;
: esto ampliará las
matriz para nosotros cuando sea necesario. La suposición de tamaño inicialN*0.07+20
proviene de un ajuste lineal a los primeros elementos, por cierto.Para probar el tiempo de ejecución, también verifiqué una versión ligeramente modificada del código, donde inicialicé la
s
matriz para que tuviera tamañoN/2
. Para los primeros1e5
elementos, esto parece ser una suposición muy generosa, por lo que eliminé el paso de expansións
mencionado en el párrafo anterior. Todo esto implica que el código será más rápido, pero también menos robusto a muy altoN
(ya que no sé cómo se ve la serie allí).Así que aquí hay algunos tiempos de ejecución, comparando
Medí esto en R2012b, tomando la mejor de 5 ejecuciones dentro de una definición de función con nombre
tic/toc
.N=100
:0.011342 s
0.015218 s
0.015076 s
N=500
:0.101647 s
0.085277 s
0.081606 s
N=1000
:0.641910 s
0.187911 s
0.183565 s
N=2000
:5.010327 s
0.452892 s
0.430547 s
N=5000
:2.021213 s
1.572958 s
N=10000
:6.248483 s
5.812838 s
Parece que la
v3
versión es significativamente, pero no abrumadoramente más rápida. No sé si un elemento de incertidumbre (para muy grandeN
) vale el aumento menor en el tiempo de ejecución.fuente
M=1;M(end+1)=2;
funciona perfectamente bien para mi?M=rand(2); M(end+1)=2
lugar :)Jalea ,
2419 bytesEsta es mi primera respuesta de Jelly en bastante tiempo. Contento de estar de vuelta.
Este es un puerto de mi respuesta APL que es una adaptación de muchos de los algoritmos utilizados aquí. La principal diferencia es que esto está indexado en 0.
Editar: -5 bytes gracias a Jonathan Allan.
Pruébalo en línea!
Explicación
fuente
ḟ
funcionará tan bien comoœ-
guardar un byte“”
con la1
salida de una representación Jelly de una lista de un programa completo, ahorrando uno más.Œœị@2
se puede jugar golf paraḊm2
salvar dos.L‘R
se puede jugar golf paraŻJ
salvar uno.ES6, 114 bytes
Devuelve una matriz de los primeros n elementos de la secuencia, por lo que los índices están a 1 de la versión no reflejada a continuación. Usé el enfoque de tamiz. Esta versión se ralentiza después de aproximadamente n = 2000; una versión anterior evitaba leer el comienzo de la matriz, lo que significaba que no se ralentizaba hasta aproximadamente n = 2500. Una versión anterior utilizaba la matriz de tamices como una lista de valores prohibidos en lugar de una matriz booleana cuyos valores estaban prohibidos; esto podría llegar a aproximadamente n = 5000 sin romper el sudor. Mi versión original trató de usar máscaras de bits, pero resultó ser inútil (y también fue demasiado larga con 198 bytes).
La versión no tan lenta sin golfista:
fuente