Jump the Array!

19

Juguemos un juego para un jugador llamado Jump the array . Para jugar, solo necesitas una variedad de enteros, por ejemplo a. Comienzas en alguna posición i, y en cada turno, saltas a una nueva posición. A su vez n,

  • si nes par, saltas a la posición absoluta a[i] mod length(a),
  • si nes extraño, saltas a la posición relativa (i + a[i]) mod length(a).

La indexación de la matriz comienza en cero. Puedes contar el primer salto como turno 0o turno 1, lo que da un juego diferente. Dado que el espacio de estado del juego es finito (su movimiento está determinado por su posición y la paridad del número de turno), por supuesto, eventualmente entrará en un bucle de longitud uniforme. Denote por loop(a, i, b)la longitud de este bucle, cuando el primer salto se cuenta como giro b.

Entrada

Un conjunto no entero ade enteros para jugar.

Salida

El número máximo ptal que, cuando comience en alguna posición iy cuente el primer turno como 0o 1, eventualmente ingrese un bucle de longitud 2 * p. En otras palabras, su salida es el número

max { loop(a, i, b)/2 : i in [0 .. length(a)-1], b in [0,1] }

Reglas

Puedes dar una función o un programa completo. El recuento de bytes más pequeño gana, y las lagunas estándar no se permiten.

Casos de prueba

[0] -> 1
[-213] -> 1
[1,3,12,-1,7] -> 1
[2,3,5,7,9,11,13,17,19] -> 2
[-2,3,-5,7,-9,11,-13,17,-19,23,-27] -> 3
[0,2,5,4,-9,0,-1,1,-1,1,-6] -> 4
Zgarb
fuente
@ kukac67 Sí, es la última opción, como dijo Martin.
Zgarb
Supongo que modse define como siempre positivo ( -1 mod 5 == 4) a diferencia de C. ¿Es ese el caso?
nutki
@nutki Sí, uso un estilo Haskell mod, que siempre da resultados no negativos.
Zgarb
Si las vueltas de indexación cero dan un resultado diferente de la indexación única, ¿deberíamos emitir cualquiera de los resultados o el que sea menor?
KSFT
@ MartinBüttner No, estaba preguntando sobre indexar los giros , no los arreglos.
KSFT

Respuestas:

6

Pyth : 28 caracteres (Python 2: 116 caracteres)

eSmhxtu+G%@Q+eG@QeGlQUQ]ddUQ

Uso:

Pruébelo aquí: Pyth Compiler / Executor

Espera una lista de enteros como entrada [0,2,5,4,-9,0,-1,1,-1,1,-6]

Explicación:

Noté una propiedad importante de la función loop: para cada ihay un j, así que loop(a,i,0) == loop(a,j,1)y viceversa. Por lo tanto, solo necesitamos calcular los valores loop(a,i,b)para b=0.

Prueba: si el es un ciclo i -> j -> k -> ... -> z -> icon b = 0, entonces existe el ciclo j -> k -> ... -> z -> i -> jcon b = 1.

Por lo tanto, un script simple puede funcionar de la siguiente manera. Iterar sobre todo iy tratar de llegar imediante la computación iterativa i = a[(i + a[i]) mod len(a)] mod len(a). Dado que este cálculo puede encontrarse en un ciclo sin i, cancelamos el cálculo después de los len(a)pasos. Luego imprimimos el ciclo máximo.

Una implementación de Python 2 se ve así ( 125 caracteres }:

a=input();A=len(a);m=[]
for i in range(A):
 j=i
 for c in range(A):
  j=a[(j+a[j])%A]%A
  if i==j:m+=[c+1];break
print max(m)

Para la implementación de Pyth, utilicé un enfoque un poco diferente. Para cada uno icalculo la lista de posiciones, y busco ien esta lista.

eSmhxtu+G%@Q+eG@QeGlQUQ]ddUQ  
  m                       UQ    for each d in [0, ..., len(input)-1] compute a
      u                ]d         list G (using reduce), 
                                  which is first initialized with G = [d]
                     UQ           for each H in [0, ..., len(input)-1]:
       +G                            append to G the value
         %@Q+eG@QeGlQ                   input[G[-1] +input[G[-1]] % len(input)
                                        (notice that list lookups in pyth work with modular wrapping)
     t                            remove the first value (which is d)
    x                    d        and find the index of d in this shortend list
                                  (it's -1, if d is not in the list)
   h                              add 1
eS                              print the maximum (end of sorted list)  

editar: Python 2: 116 caracteres

La solución de @proud haskeller tenía unos pocos caracteres menos que mi solución de Python, por lo tanto, tuve que acortarla un poco.

a=input();A=len(a);l=lambda j,i,c:c<=A and(c*(i==j)or l(a[(j+a[j])%A]%A,i,c+1));print max(l(i,i,0)for i in range(A))

La diferencia es que calculo el número de forma recursiva en lugar de iterativa.

Jakube
fuente
8

Python - 157

a=input()
z=len(a)
b=[]
for i in range(z):
    s,c,t=[],"",0
    while(c in s[:-1])-1:j=(i*t+a[i])%z;c=`t`+`i`;s+=[c];t^=1
    b+=[len(s)-s.index(c)-1]
print max(b)/2
KSFT
fuente
1
Si coloca len(a)una variable y reemplaza todos los len(a)s con el nombre de esa variable, puede guardar algunos caracteres.
ProgramFOX
1
Algunas ideas: t+=1;t%=2-> t^=1y if t: j=(j+a[j])%z else: j=a[j]%z->j=(t*j+a[j])%z
Vectorizado el
1
Use solo un espacio para sangrar. Guarda 9 caracteres aquí.
PurkkaKoodari
1
Otra idea: while c not in s[:-1]:podría ser while(c in s[:-1])-1:.
PurkkaKoodari
1
Y uno mas. No tiene que usar j, ya que este bucle asigna el contenido de range(z)a en ilugar de incrementarlo. Simplemente reemplace jcon ipara guardar 4 caracteres.
PurkkaKoodari
5

Haskell, 120 105

f s|t<-l s=maximum[g$drop t$iterate(\i->s!!mod(i+s!!mod i t)t)i|i<-s]
g(x:s)=l$0:fst(span(/=x)o)
l=length

esto genera una lista infinita para cada punto de partida (por razones de golf iteramos sobre todos los valores en lugar de todos los índices, que son equivalentes). luego calcula el ciclo de cada lista (la duración del ciclo de xses xs % []).

utiliza las observaciones de @ jakubes sobre los ciclos. Debido a que avanza 2 pasos a la vez, no necesitamos dividir entre 2 al final.

Editar : ahora usa el truco de @ MthViewMark de soltar los primeros nelementos para garantizar tener un ciclo con el primer elemento. por cierto, logré desarrollar su algoritmo para 112personajes:

l=length
o(x:y)=1+l(takeWhile(/=x)y)
j a|n<-l a=maximum$map(o.drop n.iterate(\i->mod(a!!mod(i+a!!i)n)n))[0..n-1]
orgulloso Haskeller
fuente
2

Haskell - 139 caracteres

l=length
o(x:y)=1+l(takeWhile(/=x)y)
j a=maximum$map(o.drop n.iterate(b!!))[0..n-1]
 where b=zipWith(\x y->mod(a!!mod(x+y)n)n)a[0..];n=l a

Ejemplos:

λ: j [0]
1

λ: j [-213]
1

λ: j [1,3,12,-1,7]
1

λ: j [2,3,5,7,9,11,13,17,19]
2

λ: j [-2,3,-5,7,-9,11,-13,17,-19,23,-27]
3

λ: j [0,2,5,4,-9,0,-1,1,-1,1,-6]
4

Esto hace uso de la observación de @ jakube de que solo necesita verificar la mitad de los valores iniciales, mientras realiza 2 pasos por iteración.

MtnViewMark
fuente
Podrías aplastar whereel anterior ]. Además, ¿intentaste usar en cycle l!!ilugar de l!!mod n(length l)?
orgulloso Haskeller
Además, puede alinear by usar un protector de patrón |n<-l apara eliminar el where.
orgulloso Haskeller
2

Python, 160

l=lambda a,b,c,d:(b,c)in d and len(d)-d.index((b,c))or l(a,(a[b]+[0,b][c])%len(a),~c,d+[(b,c)])
j=lambda a:max(l(a,b,c,[])for b in range(len(a))for c in(0,1))/2

La función para la respuesta es j.
La función recursiva ldevuelve la longitud del bucle para una matriz dada, inicio y primer turno, y la función jencuentra el máximo.

faubi
fuente
Creo que puedes guardar algunos caracteres definiendo j con a lambda.
KSFT
1

Mathematica, 189162161 bytes

Si se permiten funciones anónimas - 161 bytes:

Max[l=Length;Table[b={};n=p;i=s-1;e:={i,n~Mod~2};While[b~Count~e<2,b~AppendTo~e;h=#[[i+1]];i=If[EvenQ@n++,h,i+h]~Mod~l@#];l@b-b~Position~e+1,{s,l@#},{p,0,1}]/4]&

De lo contrario, 163 bytes:

f=Max[l=Length;Table[b={};n=p;i=s-1;e:={i,n~Mod~2};While[b~Count~e<2,b~AppendTo~e;h=#[[i+1]];i=If[EvenQ@n++,h,i+h]~Mod~l@#];l@b-b~Position~e+1,{s,l@#},{p,0,1}]/4]&

Ejecutando esto en todos los casos de prueba:

f /@ {
  {0},
  {-213},
  {1, 3, 12, -1, 7},
  {2, 3, 5, 7, 9, 11, 13, 17, 19},
  {-2, 3, -5, 7, -9, 11, -13, 17, -19, 23, -27},
  {0, 2, 5, 4, -9, 0, -1, 1, -1, 1, -6}
}

Resultados en:

{1, 1, 1, 2, 3, 4}

Python 2, 202 bytes

def l(a,n,i):
 b=[]
 while not[i,n]in b:b.append([i,n]);i=(a[i]if n<1 else i+a[i])%len(a);n+=1;n%=2
 return len(b)-b.index([i,n])
def f(a):print max([l(a,n,i) for n in[0,1]for i in range(len(a))])/2

MANIFESTACIÓN

Este es casi un puerto de mi respuesta de Mathematica.

kukac67
fuente
Esto se ve muy similar al mío. La mía estaba apagada por una (antes de dividir por dos) al principio. Todavía no estoy seguro de por qué, pero acabo de restar uno antes de dividir.
KSFT
No conozco Mathematica, así que realmente no puedo ayudar más.
KSFT
@Zgarb ¡Oh! Bueno, eso lo explica todo. Ni siquiera pensé en eso. ¡Gracias!
kukac67
Forcon 3 argumentos suele ser más corto que While(ya que puede guardar en un punto y coma delante de For).
Martin Ender
1

Mathematica, 113 112 caracteres

l=Length;m=MapIndexed;f=Max[l/@ConnectedComponents@Graph@m[Tr@#2->#&,Part@@Thread@Mod[#+{Tr@#2,1}&~m~#,l@#,1]]]&

Ejemplo:

f /@ {
  {0},
  {-213},
  {1, 3, 12, -1, 7},
  {2, 3, 5, 7, 9, 11, 13, 17, 19},
  {-2, 3, -5, 7, -9, 11, -13, 17, -19, 23, -27},
  {0, 2, 5, 4, -9, 0, -1, 1, -1, 1, -6}
}

{1, 1, 1, 2, 3, 4}

alephalpha
fuente
1

ised 82

ised '@1{0,2,5,4,-9,0,-1,1,-1,1,-6};@2{1};' '@{4 5}{(@3{:$1_x++x*@2{1-$2}:}2*#$1)::[#$1]};{1+?{:@5{$3::$5}=$4:}@::[2*#$1]_0}/2'

El primer argumento no cuenta en longitud (inicialización de matriz $1e binicialización en $2- seleccione el "juego").

Orión
fuente