Array Escape - vattene da lì


32

Un giorno ti svegli solo per ritrovarti intrappolato in un array. Cerchi di uscire da lì, prendendo un indice alla volta, ma sembra che ci siano altre regole:

L'array è completamente pieno di numeri naturali.

  • Se ti trovi in ​​un indice n, vai all'indice array[n], tranne:
  • Se ti trovi su un indice nche è un numero primo, fai dei array[n]passi indietro

Esempio: si avvia su indice 4, in questo array (l'indice di inizio è 0):

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

Poiché il valore del campo in cui ti trovi è 8, vai all'indice 8come primo passo. Il campo su cui atterri contiene il valore 2. Quindi vai all'indice 2come secondo passaggio. Essendo 2un numero primo, fai 5 passi indietro, che è il tuo terzo passo. Poiché non esiste alcun indice -3, è stato eseguito correttamente l'escape dell'array in un totale di 3 passaggi.

Il tuo compito è:

Scrivere un programma o una funzione, che accetta un array e un indice iniziale come parametro e genera la quantità di passaggi per uscire dall'array. Se non riesci a sfuggire all'array (ad esempio [2,0,2]con start-index 2=> vai costantemente dall'indice 2a 0), genera un valore errato. È possibile utilizzare l'indicizzazione su base singola o su base zero, ma si prega di specificare quale utilizzare.

Casi test

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

Produzione: 1

Ingresso: [2, 0, 2], 2

Produzione: false

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

Produzione: 6

Vince la risposta più breve.


7
Benvenuti in PPCG! Questa è una prima sfida decente. :) Possiamo usare anche l'indicizzazione basata su 1? Inoltre, potrebbe essere utile avere altri casi di test. Per le sfide future puoi anche prendere in considerazione l' uso della sandbox in cui puoi ottenere feedback dalla community prima che una sfida diventi attiva.
Martin Ender,


1
@Martin Ender non è collegato alla domanda ... ma io come utente mobile trovo impossibile usare la sandbox. Cosa devo fare per ottenere un feedback sulle mie domande prima di pubblicarle?
user6245072,

1
@JerryJeremiah perché non puoi fare 3 passi indietro? atterrerai sull'indice 2 se inizi alle 5 e fai 3 passi indietro
Michael Kunst,

5
@ user902383 andando all'indice 2, che è primo, quindi facciamo 2 passi indietro e andiamo all'indice 0, che non è primo. Il valore all'indice 0 è 2, quindi andiamo all'indice 2, che è primo ... ripeti
edc65

Risposte:



9

Python, 161 138 byte

Crediti per fattoriale.

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 esso!

Come funziona

Il teorema di Wilson è usato per il controllo primario.

Rilevamento di loop memorizzando gli indici visti in un array ( l) e controllando se è presente l'indice corrente l.


6

Python, 107 byte

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

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

Restituisce 0per i loop (rilevati quando n > len(a))


5

Matlab, 138 byte

Questo è un approccio diretto, usando indici basati su 1 perché Matlab usa indici basati su 1 per impostazione predefinita. Per contare il numero di passaggi utilizziamo un forconteggio loop da 1 a infinito (!). Nel caso in cui non potessimo sfuggire all'array, utilizziamo un vettore vper tenere traccia delle voci che abbiamo già visitato. Se visitiamo una voce due volte, sappiamo di essere bloccati in un ciclo inevitabile. Per verificare se siamo al di fuori di un array, utilizziamo la try/catchstruttura, che rileva anche le eccezioni ai limiti.

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

5

05AB1E, 32 byte

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

Spiegazione

ï                                 # 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

Provalo online


4

JavaScript (ES6), 100

Index base 0. Nota: questa funzione modifica l'array di input

(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")

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

Test

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


4

JAVA, 229 218 byte

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

Grazie a Kevin, 11 byte morde la polvere.


Alcune cose per giocarci ancora un po ': Stack<Integer>i=new Stack<>();può essere cambiato Stack i=new Stack();e return 1==2;può essere cambiato in return 0>1;. Inoltre, potresti voler menzionare che è Java 7 anziché Java in generale.
Kevin Cruijssen,

@KevinCruijssen Non sono sicuro che sia opportuno menzionare che è Java 7, poiché soprattutto ora questa soluzione è compatibile con la maggior parte delle versioni Java.
user902383,

Bene, in Java 8 puoi usare un lambdas che è più corto: a,b->{...}invece di Object e(int[]a,int b){...}, è per questo che menziono personalmente Java 7 per far sapere alla gente che non ho usato volutamente Java 8 lambdas, ma dipende da te.
Kevin Cruijssen,

@KevinCruijssen è abbastanza giusto, quando sto usando lamda, sto specificando la versione java, ma quando la soluzione funziona con java 7, di solito funziona anche con java 8, quindi è stato inutile aggiungere la versione. Ma potresti avere ragione, dovrei specificare la versione minima.
user902383,

4

CJam, 44 byte

Si aspetta index arrayin pila.

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

Provalo online!

La mia prima risposta di CJam, quindi perché è così terribile e imperativo ...

: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

(si ritiene che vada in crash dopo l'output corretto come stampato, che è quello che fa il programma qui)


3

C, 121 byte

La funzione faccetta array, indice iniziale (basato su 0) e numero di elementi nell'array, poiché non esiste alcun modo per testare la fine di un array in C (almeno non ne conosco nessuno).

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

Provalo su ideone!

Nota: function p(n) verifica se nè primo o no. Il merito di ciò va a @Lynn e la sua risposta per Questo numero è un numero primo?


1
@raznagul senza senso, non è possibile determinare la lunghezza di un array di parametri di input. Vedi la risposta 2 sulla stessa domanda
edc65,

@ edc65: mi dispiace, avrei dovuto leggere oltre la prima risposta.
raznagul,

@Jasmes - Nel code golf, una funzione dovrebbe poter essere chiamata più volte per ottenere lo stesso output. Il codice richiede il ripristino cper richiamare nuovamente la funzione.
owacoder,

3

JavaScript, 121 132 byte

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]));
}

modifica 1: oops, ho perso un po 'di tempo per restituire il numero di passaggi. risolverai presto.

modifica 2: risolto


3

Racchetta, 183 156 byte

Probabilmente più byte salvabili con ulteriore golf, ma questo è tutto per me. :)

(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))]))

Modulo completo con suite di test con funzione di pulizia:

#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))))

Eseguilo come raco test e.rkt

Principali complimenti per @cat alla scoperta della prime?funzione non documentata .


2

Java, 163 160 byte

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)è per il test principale, f(a,n)è per la funzione di escape. Uso:

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

Versione non golfata:

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]);
    }
}

1

Perl 6 , 85 byte

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

Spiegazione:

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

Questa è una sequenza pigra degli indici attraversati secondo la regola. Se l'indice alla fine supera i limiti dell'array di input ( !(0 <= * < a)condizione), la sequenza è finita; in caso contrario, gli indici si alternano all'infinito.

Quella sequenza è alimentata dalla funzione anonima interna:

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

Se la sequenza è definita nell'indice dato dalla dimensione dell'array di input, deve essere inserita in un ciclo infinito, quindi 0viene restituita. Altrimenti, +$_viene restituita la dimensione della sequenza .


1

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

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

Provalo online!

Elenco basato su 0. Restituisce false (vuoto) se l'elenco è inevitabile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.