Array Escape - sortez de là

32

Un jour, vous ne vous réveillez que pour vous retrouver pris dans un tableau. Vous essayez de sortir de là, en prenant un index à la fois, mais il semble qu'il existe d'autres règles:

Le tableau est entièrement rempli de nombres naturels.

  • Si vous vous retrouvez sur un index n, vous accédez à l'index array[n], sauf:
  • Si vous vous retrouvez sur un indice nqui est un nombre premier, vous array[n]reculez

Exemple: vous commencez sur l'index 4, dans ce tableau (l'index de départ est 0):

array = [1,4,5,6,8,10,14,15,2,2,4,5,7];
-----------------^ you are here

Comme la valeur du champ sur lequel vous vous trouvez est 8, vous accédez à l'index 8comme première étape. Le champ sur lequel vous atterrissez contient la valeur 2. Vous allez ensuite à l'index 2comme deuxième étape. Comme 2c'est un nombre premier, vous reculez de 5 pas, ce qui est votre troisième pas. Comme il n'y a pas d'index -3, vous avez réussi à échapper au tableau en 3 étapes au total.

Votre tâche est:

Pour écrire un programme ou une fonction, qui accepte un tableau et un index de démarrage comme paramètre, et génère le nombre d'étapes pour échapper au tableau. Si vous ne pouvez pas échapper au tableau (par exemple [2,0,2]avec start-index 2=> vous passez constamment de l'index 2à 0), affichez une valeur falsifiée. Vous pouvez utiliser une indexation à base unique ou une indexation à base zéro, mais veuillez spécifier celle que vous utilisez.

Cas de test

Contribution: [2,5,6,8,1,2,3], 3

Sortie: 1

Contribution: [2, 0, 2], 2

Sortie: false

Entrée: [14,1,2,5,1,3,51,5,12,3,4,41,15,4,12,243,51,2,14,51,12,11], 5;

Sortie: 6

La réponse la plus courte l'emporte.

Michael Kunst
la source
7
Bienvenue chez PPCG! C'est un premier défi décent. :) Pouvons-nous également utiliser l'indexation basée sur 1? Il pourrait également être utile d'avoir quelques cas de test supplémentaires. Pour les défis futurs, vous pouvez également envisager d' utiliser le bac à sable où vous pouvez obtenir des commentaires de la communauté avant qu'un défi ne soit mis en ligne.
Martin Ender
1
Très étroitement lié
Peter Taylor
1
@Martin Ender ce n'est pas lié à la question ... mais moi, en tant qu'utilisateur mobile, il est impossible d'utiliser le bac à sable. Que dois-je faire pour obtenir un retour sur mes questions avant de les publier?
user6245072
1
@JerryJeremiah pourquoi ne pouvez-vous pas reculer de 3 pas? vous atterrirez sur l'index 2 si vous commencez à 5 et reculez de 3 pas
Michael Kunst
5
@ user902383 va à l' index 2, qui est premier, donc nous faisons 2 pas en arrière et passons à l' index 0, qui n'est pas premier. La valeur à l' index 0 est 2, nous allons donc à l' index 2, qui est premier ... répétez
edc65

Réponses:

4

Pyth, 31 octets

KlQ%tl-.u?}NUK?P_N-N@QN@QNKQEKK

Les cas de test

Il utilise zéro pour indiquer une valeur fausse, le nombre de sauts sinon.

Cameron McCluskie
la source
9

Python, 161 138 octets

Crédits pour factorielle.

g=lambda x:0**x or x*g(x-1)
f=lambda a,i,n=0,l=[]:(i<0)+(i>=len(a))and n or(0 if i in l else f(a,[a[i],i-a[i]][i and-g(i-1)%i],n+1,l+[i]))

Ideone ça!

Comment ça marche

Le théorème de Wilson est utilisé pour la vérification principale.

Détection de boucle en stockant les indices vus dans un tableau ( l) et en vérifiant si l'index actuel est dedans l.

Fuite, nonne
la source
6

Python, 107 octets

import sympy
f=lambda a,i,n=0:0if n>len(a)else f(a,[a[i],i-a[i]][sympy.isprime(i)],n+1)if 0<=i<len(a)else n

Utilisation: f(list, start)ex:f([2,5,6,8,1,2,3], 3)

Renvoie les 0boucles (détecté quand n > len(a))

RootTwo
la source
5

Matlab, 138 octets

Il s'agit d'une approche directe, utilisant des indices basés sur 1 car Matlab utilise des indices basés sur 1 par défaut. Pour compter le nombre de pas, nous utilisons une forboucle comptant de 1 à l'infini (!). Dans le cas où nous ne pouvons pas échapper au tableau, nous utilisons un vecteur vpour garder une trace des entrées que nous avons déjà visitées. Si nous visitons une entrée deux fois, nous savons que nous sommes coincés dans un cycle inéluctable. Pour voir si nous sommes en dehors d'un tableau, nous utilisons la try/catchstructure, qui intercepte également les exceptions hors limites.

function r=f(a,i);v=a*0;v(i)=1;for k=1:Inf;if isprime(i);i=i-a(i);else;i=a(i);end;try;if v(i);r=0;break;end;v(i)=1;catch;r=k;break;end;end
flawr
la source
5

05AB1E, 32 octets

ï[U¯Xåi0,q}²gL<Xå_#X²XèXDˆpi-]¯g

Explication

ï                                 # explicitly convert input to int
 [                            ]   # infinite loop
  U                               # store current index in X
   ¯Xåi0,q}                       # if we've already been at this index, print 0 and exit
           ²gL<Xå_#               # if we've escaped, break out of infinite loop
                   X²XèXDˆpi-     # else calculate new index
                               ¯g # print nr of indices traversed

Essayez-le en ligne

Emigna
la source
4

JavaScript (ES6), 100

Index base 0. Remarque: cette fonction modifie le tableau d'entrée

(a,p)=>eval("for(s=0;1/(q=a[p]);++s,p=p>1&&p%i||p==2?p-q:q)for(a[p]=NaN,i=1;p%++i&&i*i<p;);q==q&&s")

Moins golfé

(a,p)=>
{
  for(s = 0; 
      1/ (q = a[p]); 
      ++s)
  {
    a[p] = NaN; // mark visited position with NaN to detect loops
    for(i = 1; p % ++i && i*i < p;); // prime check
    p = p > 1 && p % i || p == 2 ? p-q : q;
  }
  return q==q && s // return false if landed on NaN as NaN != NaN
}

Tester

F=
(a,p)=>eval("for(s=0;1/(q=a[p]);++s,p=p>1&&p%i||p==2?p-q:q)for(a[p]=NaN,i=1;p%++i&&i*i<p;);q==q&&s")

;[
 [[2,5,6,8,1,2,3], 3, 1]
,[[2, 0, 2], 2, false]
,[[14,1,2,5,1,3,51,5,12,3,4,41,15,4,12,243,51,2,14,51,12,11], 5, 6]
].forEach(t=>{
  var [a,b,k]=t, i=a+' '+b,r=F(a,b)
  console.log(r==k?'OK':'KO',i+' -> '+r)
  
})  

edc65
la source
4

JAVA, 229 218 octets

Object e(int[]a,int b){Stack i=new Stack();int s=0;for(;!(a.length<b|b<0);s++){if(i.contains(b))return 1>2;i.add(b);b=p(b)>0?b-a[b]:a[b];}return s;}int p(int i){for(int j=2;j<i/2;j++)if(i%j<1)return 0;return i<2?0:1;}

Merci à Kevin, 11 octets mord la poussière.

user902383
la source
Quelques choses pour Stack<Integer>i=new Stack<>();jouer au golf un peu plus: peut être changé en Stack i=new Stack();et return 1==2;peut être changé en return 0>1;. En outre, vous voudrez peut-être mentionner que c'est Java 7 au lieu de Java en général.
Kevin Cruijssen
@KevinCruijssen Je ne suis pas sûr qu'il soit utile de mentionner qu'il s'agit de java 7, car cette solution est particulièrement compatible avec la plupart des versions java.
user902383
Eh bien, dans Java 8, vous pouvez utiliser un lambdas qui est plus court: a,b->{...}au lieu de Object e(int[]a,int b){...}, c'est pourquoi je mentionne personnellement Java 7 pour faire savoir aux gens que je n'ai pas délibérément utilisé de lambdas Java 8, mais c'est à vous de décider.
Kevin Cruijssen
@KevinCruijssen assez juste, lorsque j'utilise lamda, je spécifie la version java, mais lorsque la solution fonctionne avec java 7, cela fonctionne généralement aussi avec java 8, il était donc inutile d'ajouter une version. Mais vous avez peut-être raison, je devrais spécifier la version minimale.
user902383
4

CJam, 44 octets

Attend index arraysur la pile.

:G\{_G,,&{G=_L#)0{_L+:L;_mp3T?-F}?}L,?}:F~o@

Essayez-le en ligne!

Ma première réponse CJam, donc pourquoi c'est si terrible et impératif ...

:G\{_G,,&{G=_L#)0{_L+:L;_mp3T?-F}?}L,?}:F~o@
:G                                              Store the array as G
  \                                             Put the index first
   {                                  }:F~      The recursive F function
     G,,                                        Generate a 0..length(G) sequence
    _   &                            ?          Check that the index is contained
         {                        }             If so, then...
          G=                                    Get the value at the index
            _L#)                 ?              If the value is in L (`-1)` gives `0` which is falsy)
                0                               Return 0 (infinite loop)
                 {              }               Otherwise...
                  _L+:L;                        Store the value we're accessing in L (infinite loop check)
                        _mp3T?-                 Remove 3 if the number is prime
                               F                Then recursively call F
                                   L,           We escaped! Return the size of "L" (number of steps)
                                          o     Print the top value of the stack
                                           @    Tries to swap 3 elements, which will error out

(il est considéré comme correct de planter après la sortie correcte telle qu'imprimée, ce que fait le programme ici)

Ven
la source
3

C, 121 octets

La fonction faccepte le tableau, l'index de départ (basé sur 0) et le nombre d'éléments dans le tableau, car il n'y a aucun moyen de tester la fin d'un tableau en C (au moins je n'en connais pas).

p(n,i,z){return--i?p(n,i,z*i*i%n):z%n;}c;f(a,i,n)int*a;{return i<0||i/n?c:c++>n?0:i&&p(i,i,1)?f(a,i-a[i],n):f(a,a[i],n);}

Essayez-le sur ideone!

Remarque: function p(n) teste si nest premier ou non. Le mérite en revient à @Lynn et sa réponse pour Ce numéro est-il un nombre premier?

Jasmes
la source
1
@raznagul nonsense, vous ne pouvez pas déterminer la longueur d'un tableau de paramètres d'entrée. Voir la réponse 2 à la même question
edc65
@ edc65: Désolé, j'aurais dû lire au-delà de la première réponse.
raznagul
@Jasmes - Dans le code golf, une fonction doit pouvoir être appelée plusieurs fois pour obtenir la même sortie. Votre code nécessite une réinitialisation cpour appeler à nouveau la fonction.
owacoder
3

JavaScript, 121 132 octets

p=n=>t=i=>n%i&&n>i?t(i+1):(0<n&&n<=i?1:0),c=-1,a=>r=s=>(++c,0<=s&&s<a.length?(p(s)(2)?r(s-a[s]):0||([a[s],s]=[0,a[s]])[1]?r(s):0):c)

f=(p=n=>t=i=>n%i&&n>i?t(i+1):(0<n&&n<=i?1:0),c=-1,a=>r=s=>(++c,0<=s&&s<a.length?(p(s)(2)?r(s-a[s]):0||([a[s],s]=[0,a[s]])[1]?r(s):0):c));

let test_data = [[[1,4,5,6,8,10,14,15,2,2,4,5,7],4],
                 [[2,5,6,8,1,2,3],3],
                 [[2,0,2],2],
                 [[14,1,2,5,1,3,51,5,12,3,4,41,15,4,12,243,51,2,14,51,12,11],5]];
for (test of test_data) {
    c = -1;
    console.log(f(test[0])(test[1]));
}

modifier 1: oups, manqué le bit sur le retour du nombre d'étapes. correction à venir bientôt.

modifier 2: fixe

Yay295
la source
3

Raquette, 183156 octets

Probablement plus d'octets enregistrables avec le golf, mais c'est tout pour moi. :)

(require math)(define(e l i[v'()][g length])(cond[(memq i v)#f][(not(< -1 i(g l)))(g v)][else(e l((λ(a)(if(prime? i)(- i a)a))(list-ref l i))(cons i v))]))

Module complet avec suite de tests avec fonction de nettoyage:

#lang racket

(require math)

(define (e l i [v'()] [g length])
  (cond
    [(memq i v) #f]
    [(not (< -1 i (g l))) (g v)]
    [else (e l
             ((λ (a) (if (prime? i)
                         (- i a)
                         a))
              (list-ref l i))
             (cons i v))]))

(module+ test
  (require rackunit)
  (define escape-tests
    '((((2 5 6 8 1 2 3) 3) . 1)
      (((2 0 2) 2) . #f)
      (((14 1 2 5 1 3 51 5 12 3 4 41 15 4 12 243 51 2 14 51 12 11) 5) . 6)))
  (for ([t escape-tests])
    (check-equal? (apply e (car t)) (cdr t) (~a t))))

Exécutez-le comme raco test e.rkt

Félicitations majeures pour @cat découvrir la prime?fonction non documentée .

Winny
la source
2

Java, 163 160 octets

boolean p(int n){for(int i=2;i<n;)if(n%i++==0)return 0>1;return 1>0;}
int f(int[]a,int n){return n<0||n>=a.length?1:p(n)?n<a[n]?1:1+f(a,a[n-a[n]]):1+f(a,a[n]);}

p(n)est pour le test principal, f(a,n)est pour la fonction d'échappement. Usage:

public static void main(String[] args) {
    int[] array = {14,1,2,5,1,3,51,5,12,3,4,41,15,4,12,243,51,2,14,51,12,11};
    System.out.println(f(array, 5));
}

Version non-golfée:

static boolean isPrime(int n) {
    for (int i = 2; i < n; i++) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

static int escape(int[] array, int n) {
    if (n < 0 || n >= array.length) {
        return 1;
    } else if (isPrime(n)) {
        if (n < array[n]) {
            return 1;
        } else {
            return 1 + escape(array, array[n - array[n]]);
        }
    } else {
        return 1 + escape(array, array[n]);
    }
}
Justin
la source
1

Perl 6 , 85 octets

->\n,\a{{.[+a].defined??0!!+$_}(lazy n,{.is-prime??$_- a[$_]!!a[$_]}...^!(0 <=* <a))}

Explication:

lazy n, { .is-prime ?? $_ - a[$_] !! a[$_] } ...^ !(0 <= * < a)

Il s'agit d'une séquence paresseuse des indices parcourus selon la règle. Si l'index dépasse finalement les limites du tableau d'entrée (la !(0 <= * < a)condition), la séquence est finie; sinon, les indices tournent à l'infini.

Cette séquence est envoyée à la fonction anonyme interne:

{ .[+a].defined ?? 0 !! +$_ }

Si la séquence est définie à l'index donné par la taille du tableau d'entrée, elle doit être entrée dans un cycle infini, elle 0est donc renvoyée. Sinon, la taille de la séquence +$_est renvoyée.

Sean
la source
1

Perl 5 , 107 + 1 ( -a) = 108 octets

for($i=<>;!$k{$i}++&&$i>=0&&$i<@F;$s++){$f=0|sqrt$i||2;1while$i%$f--;$i=$f?$F[$i]:$i-$F[$i]}say$k{$i}<2&&$s

Essayez-le en ligne!

Liste basée sur 0. Renvoie false (vide) si la liste est incontournable.

Xcali
la source