Jump the Array!


19

Jouons à un jeu à un joueur appelé sauter le tableau . Pour jouer, vous n'avez besoin que d'un tableau d'entiers, par exemple a. Vous commencez à une certaine position iet à chaque tour, vous sautez à une nouvelle position. À son tour n,

  • si nc'est pair, vous sautez en position absolue a[i] mod length(a),
  • si nest impair, vous sautez à la position relative (i + a[i]) mod length(a).

L'indexation du tableau commence à zéro. Vous pouvez compter le premier saut comme un tour 0ou un tour 1, ce qui donne un jeu différent. Puisque l'espace d'état du jeu est fini (votre coup est déterminé par votre position et la parité du nombre de tours), vous finirez bien sûr par entrer dans une boucle de longueur égale. Indique loop(a, i, b)la longueur de cette boucle, lorsque le premier saut est compté comme un tour b.

Contribution

Un tableau non vide ad'entiers avec lesquels jouer.

Production

Le nombre maximum ptel que, lorsque vous commencez sur une position iet comptez le premier tour comme l'un 0ou l' autre 1, vous entrez finalement une boucle de longueur 2 * p. En d'autres termes, votre sortie est le nombre

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

Règles

Vous pouvez donner une fonction ou un programme complet. Le plus petit nombre d'octets gagne et les failles standard sont interdites.

Cas de test

[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

@ kukac67 Oui, c'est la dernière option, comme l'a dit Martin.
Zgarb

Je suppose que cela modest défini comme toujours positif ( -1 mod 5 == 4) contrairement à C. Est-ce le cas?
nutki

@nutki Oui, j'utilise un style Haskell mod, qui donne toujours des résultats non négatifs.
Zgarb

Si les tours d'indexation zéro donnent un résultat différent de l'indexation unique, devrions-nous produire l'un ou l'autre résultat, ou celui qui est inférieur?
KSFT

@ MartinBüttner Non, je posais des questions sur l'indexation des virages , pas sur les tableaux.
KSFT

Réponses:


6

Pyth : 28 caractères (Python 2: 116 caractères)

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

Usage:

Essayez-le ici: Pyth Compiler / Executor

Il attend une liste d'entiers en entrée [0,2,5,4,-9,0,-1,1,-1,1,-6]

Explication:

J'ai remarqué une propriété importante de la fonction loop: pour chacun iil y a un j, de sorte que loop(a,i,0) == loop(a,j,1)et vice versa. Par conséquent, nous devons seulement calculer les valeurs loop(a,i,b)de b=0.

Preuve: Si le est un cycle i -> j -> k -> ... -> z -> iavec b = 0, alors il existe le cycle j -> k -> ... -> z -> i -> javec b = 1.

Par conséquent, un script simple peut fonctionner de la manière suivante. Itérer sur tout iet essayer d'atteindre ipar le calcul itératif i = a[(i + a[i]) mod len(a)] mod len(a). Comme ce calcul peut se dérouler dans un cycle sans i, nous annulons le calcul après les len(a)étapes. Ensuite, nous imprimons le cycle maximum.

Une implémentation Python 2 ressemble à ceci ( 125 caractères }:

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)

Pour l'implémentation de pyth, j'ai utilisé une approche légèrement différente. Pour chacun, ije calcule la liste des postes et cherche idans cette liste.

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)  

édition: Python 2: 116 caractères

La solution de @proud haskeller était de quelques caractères plus courte que ma solution Python, j'ai donc dû la raccourcir un peu.

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 différence est que je calcule le nombre de manière récursive plutôt qu'itérative.


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

1
Si vous insérez len(a)une variable et remplacez tous les len(a)s par le nom de cette variable, vous pouvez enregistrer certains caractères.
ProgramFOX

1
Quelques idées: t+=1;t%=2-> t^=1et if t: j=(j+a[j])%z else: j=a[j]%z->j=(t*j+a[j])%z
Vectorisé le

1
Utilisez un seul espace pour mettre en retrait. Enregistre 9 caractères ici.
PurkkaKoodari

1
Une autre idée: while c not in s[:-1]:pourrait l'être while(c in s[:-1])-1:.
PurkkaKoodari

1
Et un de plus. Vous n'êtes pas obligé de l'utiliser j, car cette boucle affecte le contenu de range(z)à iau lieu de l'incrémenter. Remplacez simplement jpar ipour enregistrer 4 caractères.
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

cela génère une liste infinie pour chaque point de départ (pour des raisons de golf, nous itérons sur toutes les valeurs au lieu de tous les index, qui sont équivalents). puis il calcule le cycle de chaque liste (la durée du cycle xsest xs % []).

il utilise les observations de @ jakubes sur les cycles. parce qu'il fait 2 pas à la fois, nous n'avons pas besoin de diviser par 2 à la fin.

Edit : utilise maintenant l'astuce de @ MthViewMark pour supprimer les premiers néléments afin de garantir un cycle avec le premier élément. au fait, j'ai réussi à jouer son algorithme aux 112personnages:

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]

2

Haskell - 139 caractères

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

Exemples:

λ: 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

Cela utilise l'observation de @ jakube selon laquelle il suffit de vérifier la moitié des valeurs de départ, tout en effectuant 2 étapes par itération.


Vous pouvez écraser wherele précédent ]. Avez-vous également essayé d'utiliser cycle l!!iau lieu de l!!mod n(length l)?
fier haskeller

En outre, vous pouvez aligner bet utiliser un protecteur de motif |n<-l apour éliminer le where.
fier 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 fonction de réponse est j.
La fonction récursive lrenvoie la longueur de boucle pour un tableau donné, le début et le premier tour, et la fonction jtrouve le max.


Je pense que vous pouvez enregistrer certains caractères en définissant j avec a lambda.
KSFT

1

Mathematica, 189 162 161 octets

Si les fonctions anonymes sont autorisées - 161 octets:

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]&

Sinon - 163 octets:

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]&

Exécuter ceci sur tous les cas de test:

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}
}

Résulte en:

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

Python 2, 202 octets

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

DEMO

C'est presque un portage de ma réponse Mathematica.


Cela ressemble beaucoup au mien. La mienne a été coupée d'un (avant de diviser par deux) au début. Je ne sais toujours pas pourquoi, mais j'en ai juste soustrait un avant de diviser.
KSFT du

Je ne connais pas Mathematica, donc je ne peux pas vraiment aider davantage.
KSFT

@Zgarb Oh! Eh bien, cela explique tout. Je n'y ai même pas pensé. Merci!
kukac67

Foravec 3 arguments est généralement plus court que While(puisque vous pouvez enregistrer sur un point-virgule devant le For).
Martin Ender

1

Mathematica, 113 112 caractères

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

Exemple:

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}


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'

Le premier argument ne compte pas dans la longueur (initialisation du tableau dans $1et binitialisation dans $2- sélectionnez le "jeu").

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.