Array Escape - saia daí


32

Um dia você acorda apenas para se ver preso em uma série. Você tenta sair de lá, pegando um índice de cada vez, mas parece que existem outras regras:

A matriz é completamente preenchida com números naturais.

  • Se você se encontrar em um índice n, você acessa o índice array[n], exceto:
  • Se você se encontrar em um índice nque é um número primo, você array[n]recua

Exemplo: você inicia no índice 4, nesta matriz (o índice inicial é 0):

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

Como o valor do campo em que você está é 8, você vai para o índice 8como a primeira etapa. O campo em que você pousa contém o valor 2. Você então vai para o índice 2como seu segundo passo. Como 2é um número primo, você recua 5 passos, que é seu terceiro passo. Como não há índice -3, você escapou da matriz com sucesso em um total de 3 etapas.

Sua tarefa é:

Para escrever um programa ou função, que aceita uma matriz e um índice inicial como parâmetro, e gera a quantidade de etapas para escapar da matriz. Se você não conseguir escapar da matriz (por exemplo, [2,0,2]com start-index 2=> você passa constantemente do índice 2para 0), insira um valor falso. Você pode usar a indexação com base em um ou a indexação com base em zero, mas especifique qual você usa.

Casos de teste

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

Saída: 1

Entrada: [2, 0, 2], 2

Saída: false

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

Saída: 6

A resposta mais curta vence.


7
Bem-vindo ao PPCG! Este é um primeiro desafio decente. :) Também podemos usar a indexação baseada em 1? Também pode ser bom ter mais alguns casos de teste. Para desafios futuros, você também pode usar a sandbox, para obter feedback da comunidade antes que um desafio seja lançado.
Martin Ender


11
@ Martin Ender não está relacionado à questão ... mas eu, como usuário móvel, acho impossível usar a sandbox. O que devo fazer para obter um feedback sobre minhas perguntas antes de realmente postá-las?
user6245072

11
@JerryJeremiah, por que você não pode dar três passos para trás? você chegará ao índice 2 se começar às 5 e recuar 3 passos
Michael Kunst

5
@ user902383 indo para o índice 2, que é primo, então damos dois passos para trás e vamos para o índice 0, que não é primo. O valor de índice de 0 a 2, então vamos para o índice 2, que é primo ... repita
edc65

Respostas:



9

Python, 161 138 bytes

Créditos para fatorial.

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

Como funciona

O teorema de Wilson é usado para verificação primária.

Detecção de ciclo através do armazenamento de índices visto para uma matriz ( l) e verificando se o índice corrente é em l.


6

Python, 107 bytes

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

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

Retorna 0para loops (detectados quando n > len(a))


5

Matlab, 138 bytes

Essa é uma abordagem direta, usando índices baseados em 1 porque o Matlab usa índices baseados em 1 por padrão. Para contar o número de etapas, usamos um forloop contando de 1 a infinito (!). Para o caso em que não podemos escapar da matriz, usamos um vetor vpara acompanhar quais entradas já visitamos. Se visitarmos uma entrada duas vezes, sabemos que estamos presos a um ciclo inevitável. Para verificar se estamos fora de uma matriz, usamos a try/catchestrutura, que também captura exceções fora dos 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

5

05AB1E, 32 bytes

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

Explicação

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

Experimente online


4

JavaScript (ES6), 100

Índice base 0. Nota: esta função modifica a matriz de entrada

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

Menos golfe

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

Teste

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 bytes

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

Graças a Kevin, 11 bytes morde o pó.


Algumas coisas para jogar um pouco mais: Stack<Integer>i=new Stack<>();podem ser alteradas para Stack i=new Stack();e return 1==2;podem ser alteradas para return 0>1;. Além disso, você pode mencionar o Java 7 em vez do Java em geral.
Kevin Cruijssen

@KevinCruijssen Não tenho certeza se é importante mencionar que é o java 7, já que agora essa solução é compatível com a maioria das versões java.
user902383

Bem, no Java 8, você pode usar lambdas mais curtas: em a,b->{...}vez de Object e(int[]a,int b){...}, é por isso que mencionei pessoalmente o Java 7 para informar às pessoas que propositalmente não usei o Java 8 lambdas, mas depende de você.
Kevin Cruijssen

@KevinCruijssen justo o suficiente, quando estou usando o lamda, estou especificando a versão java, mas quando a solução funciona com o java 7, geralmente também funciona com o java 8, por isso não fazia sentido adicionar a versão. Mas você pode estar certo, devo especificar a versão mínima.
user902383

4

CJam, 44 bytes

Espera index arrayna pilha.

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

Experimente online!

Minha primeira resposta CJam, por isso é tão terrível e imperativa ...

: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

(é considerado bom travar após a saída correta impressa, que é o que o programa faz aqui)


3

C, 121 bytes

A função faceita matriz, índice inicial (baseado em 0) e número de elementos na matriz, já que não há como testar o final de uma matriz em C (pelo menos eu não conheço nenhum).

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

Experimente em ideone!

Nota: function p(n) testa se né primo ou não. O crédito é atribuído a @Lynn e sua resposta para Este número é primo?


11
@raznagul absurdo, você não pode determinar o comprimento de uma matriz de parâmetros de entrada. Ver resposta 2 sobre a mesma questão
edc65

@ edc65: Desculpe, eu deveria ter lido além da primeira resposta.
raznagul

@ Jasmes - No código golf, uma função deve poder ser chamada várias vezes para obter a mesma saída. Seu código requer redefinição cpara chamar a função novamente.
26416 owacoder

3

JavaScript, 121 132 bytes

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

edit 1: oops, não entendi o retorno do número de etapas. correção em breve.

editar 2: fixo


3

Raquete, 183 156 bytes

Provavelmente mais bytes economizáveis ​​com mais golfe, mas é isso para mim. :)

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

Módulo completo com suíte de testes com função de limpeza:

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

Execute como raco test e.rkt

Muitos elogios para o @cat descobrindo a prime?função não documentada .


2

Java, 163 160 bytes

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)é para teste principal, f(a,n)é para a função de 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));
}

Versão não destruída:

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 bytes

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

Explicação:

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

Esta é uma sequência lenta dos índices percorridos de acordo com a regra. Se o índice eventualmente exceder os limites da matriz de entrada (o!(0 <= * < a) condição), a sequência será finita; caso contrário, os índices mudam infinitamente.

Essa sequência é alimentada para a função anônima interna:

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

Se a sequência é definida no índice fornecido pelo tamanho da matriz de entrada, ela deve ter entrado em um ciclo infinito e, portanto, 0é retornada. Caso contrário, o tamanho da sequência +$_é retornado.


1

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

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

Experimente online!

Lista baseada em 0. Retorna false (em branco) se a lista for inevitável.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.