Dizi kaçış - oradan çık


32

Bir gün sadece kendini dizide yakalanmış bulmak için uyanırsın. O zaman tek bir indeks alarak oradan çıkmaya çalışıyorsunuz, ama başka kurallar varmış gibi görünüyor:

Dizi tamamen doğal sayılarla doldurulur.

  • Kendinizi bir dizinde bulursanız , aşağıdakiler dışında ndizine gidersiniz array[n]:
  • Kendinizi nana sayı olan bir dizinde bulursanız , array[n]geri adım atarsınız.

Örnek: Bu dizinde 4, dizinde başlıyorsunuz (başlangıç ​​dizini 0'dır):

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

Bulunduğunuz alanın değeri olduğu gibi, ilk adım olarak 8dizine gidersiniz 8. İndiğiniz alan değeri içerir 2. Daha sonra 2ikinci adımı olarak dizine gidin . Gibi 2bir asal sayıdır, üçüncü aşama olan geri 5 adımlar atmak. Dizin olmadığı -3için diziyi toplam 3 adımda başarıyla çıkardınız.

Görevin:

Bir diziyi ve bir başlangıç ​​dizinini parametre olarak kabul eden bir program veya işlev yazmak ve diziden kaçmak için gereken adımları gösterir. Eğer dizi çıkamazsa (örneğin [2,0,2]başlangıç indeksi ile 2=> sürekli dizinden gitmek 2için 0, çıkış bir falsy değer). Tek tabanlı bir dizinleme veya sıfır tabanlı bir dizinleme kullanabilirsiniz, ancak hangisini kullandığınızı belirtin.

Test durumları

Giriş: [2,5,6,8,1,2,3], 3

Çıktı: 1

Giriş: [2, 0, 2], 2

Çıktı: false

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

Çıktı: 6

En kısa cevap kazanır.


7
PPCG'ye Hoşgeldiniz! Bu iyi bir ilk sorundur. :) 1 tabanlı indekslemeyi de kullanabilir miyiz? Ayrıca birkaç test vakası daha olması iyi olabilir. Gelecekteki zorluklar için, bir mücadele başlamadan önce topluluktan geri bildirim alabileceğiniz sanal alanı kullanmayı da düşünebilirsiniz .
Martin Ender


1
@Martin Ender bununla ilgili değil ... ama ben mobil bir kullanıcı olarak sanal alanı kullanmanın imkansız olduğunu düşünüyorum. Sorularımı gerçekten yayınlamadan önce geri bildirim almak için ne yapmalıyım?
user6245072

1
@JerryJeremiah neden 3 adım geri alamıyorsunuz? 5'ten başlar ve 3 adım geri alırsanız endeks 2'ye
Michael Kunst

5
@ user902383 , asal olan indeks 2'ye gidiyor , bu yüzden 2 adım geriye gidiyoruz ve asal olmayan indeks 0'a gidiyoruz . En değer endeksi Biz gitmek böylece 0, 2, endeks asal ... tekrardır 2,
edc65

Yanıtlar:



9

Python, 161 138 bayt

Faktoring için krediler .

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!

Nasıl çalışır

Wilson teoremi primer kontrol için kullanılır.

Görüntülenen dizinleri bir diziye ( l) kaydederek ve geçerli dizinin içeride olup olmadığını kontrol ederek döngü algılama l.


6

Python, 107 bayt

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

Kullanım: f(list, start)eski:f([2,5,6,8,1,2,3], 3)

0Döngüler için döndürür (ne zaman algılanırsa n > len(a))


5

Matlab, 138 bayt

Bu, 1 tabanlı endeksleri kullanan, ileriye dönük bir yaklaşım çünkü Matlab, varsayılan olarak 1 tabanlı endeksleri kullanıyor. Adım sayısını forsaymak için 1'den sonsuza (!) Kadar sayılan bir döngü kullanırız . Çünkü diziden kaçamayız, vhangi girişleri ziyaret ettiğimizi takip etmek için bir vektör kullanıyoruz . Bir girişi iki kez ziyaret edersek, kaçınılmaz bir döngü içinde sıkışıp kaldığımızı biliyoruz. Bir dizinin dışında olup olmadığımızı kontrol etmek için try/catch, sınır istisnalarını da yakalayan yapıyı kullanırız .

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 bayt

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

açıklama

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

Çevrimiçi deneyin


4

JavaScript (ES6), 100

Dizin tabanı 0 Not: bu işlev giriş dizisini değiştirir

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

Daha az golf oynadı

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

Ölçek

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 Bayt

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

Kevin sayesinde, 11 bayt tozu ısırıyor.


Biraz daha golf oynamak için birkaç şey: Stack<Integer>i=new Stack<>();olarak değiştirilebilir Stack i=new Stack();ve return 1==2;değiştirilebilir return 0>1;. Ayrıca, genel olarak Java yerine Java 7'den bahsetmek isteyebilirsiniz .
Kevin Cruijssen

@KevinCruijssen Emin değilim, özellikle şu anda bu çözüm çoğu java sürümüyle uyumlu olduğundan, java 7 olduğunu belirtmek ister.
user902383

Peki, Java 8'de, daha kısa olan bir lambda kullanabilirsiniz: a,b->{...}bunun yerine, Object e(int[]a,int b){...}kişisel olarak Java 7'den kastettiğimden emin olmak için Java 7'den söz ediyorum;
Kevin Cruijssen

@KevinCruijssen yeterince adil, lamda kullandığımda, java sürümünü belirtiyorum, ancak çözüm java 7 ile çalıştığında, genellikle java 8 ile de çalışır, bu yüzden sürüm eklemek anlamsızdı. Fakat haklı olabilirsin, minimum versiyon belirtmeliyim.
user902383

4

CJam, 44 bayt

Bekler index arrayyığında.

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

Çevrimiçi deneyin!

İlk CJam cevabım, bu yüzden neden bu kadar korkunç ve zorunlu?

: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

(Çıktı olarak doğru çıktıdan sonra çökmesi tamam kabul edilir, buradaki programın yaptığı şeydir)


3

C, 121 bayt

İşlev fdiziyi, başlangıç ​​dizinini (0 tabanlı) ve dizideki öğelerin sayısını kabul eder, çünkü bir dizinin sonunu C olarak test etmenin bir yolu yoktur (en azından ben bilmiyorum).

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

İdeone üzerinde deneyin!

Not: asal function p(n)olup olmadığını test eder n. Bunun için kredi @ Lynn için gider ve onun cevabı Bu sayı bir asal mı?


1
@raznagul saçma, bir giriş parametresi dizisinin uzunluğunu belirleyemezsiniz. Aynı soruya 2. cevabı gör
edc65

@ edc65: Üzgünüm, ilk cevabın ötesini okumalıydım.
raznagul

@Jasmes - Golf kodunda, aynı çıktıyı elde etmek için bir işlev birden çok kez çağrılabilmelidir. Kodunuz c, işlevi tekrar aramak için sıfırlama gerektiriyor .
owacoder

3

JavaScript, 121 132 bayt

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

düzenleme 1: ayy, adım sayısını döndürme konusunda biti kaçırdı. Yakında düzeltme düzeltildi.

düzenleme 2: sabit


3

Raket, 183 156 bayt

Muhtemelen daha fazla golf ile tasarruf edilebilir daha fazla bayt, ama bu benim için. :)

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

Daha temiz işlevli test paketi ile komple modül:

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

Gibi koş raco test e.rkt

@Cat belgesiz prime?işlevini keşfetmek için büyük övgüler .


2

Java, 163 160 bayt

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)Asal test f(a,n)için, kaçış işlevi içindir. Kullanımı:

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

Ungolfed versiyonu:

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 bayt

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

Açıklama:

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

Bu, kurala göre ölçülen endekslerin tembel bir dizisidir. Eğer endeks sonunda giriş dizisi sınırlarını ( !(0 <= * < a)koşul) aşarsa, dizi sonludur; Aksi takdirde, endeksler sonsuz bir şekilde değişir.

Bu sıra, dahili anonim işlevine beslenir:

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

Dizi, giriş dizisinin büyüklüğü tarafından verilen dizinde tanımlanmışsa, sonsuz bir döngüye girmiş olması gerekir, bu 0nedenle döndürülür. Aksi takdirde, dizinin boyutu +$_döndürülür.


1

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

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

Çevrimiçi deneyin!

0 tabanlı liste. Liste çıkmazsa false değerini (boş) döndürür.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.