Mảng thoát - ra khỏi đó


32

Một ngày bạn thức dậy chỉ để thấy mình bị cuốn vào một mảng. Bạn cố gắng đi ra khỏi đó, lấy một chỉ số vào thời điểm đó, nhưng dường như có các quy tắc khác:

Các mảng hoàn toàn chứa đầy số tự nhiên.

  • Nếu bạn thấy mình trên một chỉ mục n, bạn đi đến chỉ mục array[n], ngoại trừ:
  • Nếu bạn thấy mình trên một chỉ số nlà số nguyên tố, bạn array[n]lùi lại

Ví dụ: Bạn bắt đầu vào chỉ mục 4, trong mảng này (chỉ mục bắt đầu là 0):

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

Vì giá trị của trường bạn đang ở 8, bạn đi đến chỉ mục 8là bước đầu tiên. Lĩnh vực bạn hạ cánh chứa giá trị 2. Sau đó, bạn đi đến chỉ mục 2là bước thứ hai của bạn. Là 2số nguyên tố, bạn lùi lại 5 bước, đây là bước thứ ba. Vì không có chỉ mục -3, bạn đã thoát thành công mảng trong tổng số 3 bước.

Nhiệm vụ của bạn là:

Để viết một chương trình hoặc hàm, chấp nhận một mảng và một chỉ mục bắt đầu làm tham số và xuất ra số lượng các bước để thoát khỏi mảng. Nếu bạn không thể thoát khỏi mảng (ví dụ: [2,0,2]với start-index 2=> bạn liên tục đi từ chỉ mục2 sang 0), hãy đưa ra một giá trị giả. Bạn có thể sử dụng lập chỉ mục một hoặc dựa trên không, nhưng vui lòng chỉ định bạn sử dụng.

Các trường hợp thử nghiệm

Đầu vào: [2,5,6,8,1,2,3], 3

Đầu ra: 1

Đầu vào: [2, 0, 2], 2

Đầu ra: false

Đầu vào: [14,1,2,5,1,3,51,5,12,3,4,41,15,4,12,243,51,2,14,51,12,11], 5 ;

Đầu ra: 6

Câu trả lời ngắn nhất sẽ thắng.


7
Chào mừng đến với PPCG! Đây là một thách thức đầu tiên khá. :) Chúng ta có thể sử dụng lập chỉ mục dựa trên 1 không? Ngoài ra nó có thể là tốt để có thêm một vài trường hợp thử nghiệm. Đối với các thử thách trong tương lai, bạn cũng có thể xem xét sử dụng hộp cát nơi bạn có thể nhận phản hồi từ cộng đồng trước khi thử thách được triển khai.
Martin Ender


1
@Martin Ender nó không liên quan đến câu hỏi ... nhưng tôi là người dùng di động thấy không thể sử dụng hộp cát. Tôi nên làm gì để nhận được phản hồi về câu hỏi của mình trước khi thực sự đăng chúng?
dùng6245072

1
@JerryJeremiah tại sao bạn không thể lùi 3 bước? bạn sẽ đạt được chỉ số 2 nếu bạn bắt đầu từ 5 và lùi lại 3 bước
Michael Kunst

5
@ user902383 sẽ chuyển sang chỉ mục 2, là số nguyên tố, vì vậy chúng tôi thực hiện 2 bước lùi và chuyển đến chỉ mục 0, không phải là số nguyên tố. Giá trị tại chỉ số 0 là 2, vì vậy chúng tôi chuyển đến chỉ mục 2, đó là số nguyên tố ... lặp lại
edc65

Câu trả lời:



9

Con trăn, 161 138 byte

Tín dụng cho giai thừa.

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

Nghĩa là nó!

Làm thế nào nó hoạt động

Định lý Wilson được sử dụng để kiểm tra chính.

Phát hiện vòng lặp bằng cách lưu trữ các chỉ mục nhìn thấy vào một mảng ( l) và kiểm tra xem chỉ mục hiện tại có ở trong không 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

Cách sử dụng: f(list, start)ví dụ:f([2,5,6,8,1,2,3], 3)

Trả về 0các vòng lặp (được phát hiện khi n > len(a))


5

Matlab, 138 byte

Đây là một cách tiếp cận mạnh mẽ, sử dụng các chỉ mục dựa trên 1 vì Matlab sử dụng các chỉ mục dựa trên 1 theo mặc định. Để đếm số bước chúng ta sử dụng một forvòng lặp đếm từ 1 đến vô cùng (!). Đối với trường hợp chúng tôi không thể thoát khỏi mảng, chúng tôi sử dụng một vectơ vđể theo dõi những mục chúng tôi đã truy cập. Nếu chúng ta truy cập một mục hai lần, chúng ta biết rằng chúng ta đang bị mắc kẹt trong một chu kỳ không thể giải quyết. Để xem kiểm tra xem chúng tôi có ở bên ngoài một mảng không, chúng tôi sử dụng try/catchcấu trúc, cũng bắt được các ngoại lệ giới hạn.

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

Giải trình

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

Dùng thử trực tuyến


4

JavaScript (ES6), 100

Chỉ số cơ sở 0. Lưu ý: chức năng này sửa đổi mảng đầu vào

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

Ít chơi gôn

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

Kiểm tra

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

Nhờ Kevin, 11 byte cắn bụi.


Một vài điều để đánh golf thêm một số điều: Stack<Integer>i=new Stack<>();có thể thay đổi Stack i=new Stack();return 1==2;có thể thay đổi thành return 0>1;. Ngoài ra, bạn có thể muốn đề cập đến Java 7 thay vì Java nói chung.
Kevin Cruijssen

@KevinCruijssen Tôi không chắc chắn phải đề cập rằng đó là java 7, vì đặc biệt là giải pháp này tương thích với hầu hết các phiên bản java.
dùng902383

Chà, trong Java 8, bạn có thể sử dụng một lambdas ngắn hơn: a,b->{...}thay vì Object e(int[]a,int b){...}, đó là lý do tại sao tôi đích thân đề cập đến Java 7 để cho mọi người biết tôi cố tình không sử dụng lambdas Java 8, nhưng nó tùy thuộc vào bạn.
Kevin Cruijssen

@KevinCruijssen đủ công bằng, khi tôi sử dụng lamda, tôi chỉ định phiên bản java, nhưng khi giải pháp hoạt động với java 7, nó thường hoạt động với java 8, vì vậy việc thêm phiên bản là vô nghĩa. Nhưng bạn có thể đúng, tôi nên chỉ định phiên bản tối thiểu.
dùng902383

4

CJam, 44 byte

Mong đợi index arrayvào ngăn xếp.

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

Hãy thử trực tuyến!

Câu trả lời đầu tiên của tôi về CJam, tại sao nó quá khủng khiếp và bắt buộc ...

: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

(nó được coi là ổn khi gặp sự cố sau khi đầu ra chính xác như được in, đó là những gì chương trình ở đây làm)


3

C, 121 byte

Hàm fchấp nhận mảng, chỉ mục bắt đầu (dựa trên 0) và số phần tử trong mảng, vì không có cách nào để kiểm tra kết thúc của một mảng trong C (ít nhất là tôi không biết).

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

Hãy thử nó trên ideone!

Lưu ý: function p(n) kiểm tra nếu nlà số nguyên tố hay không. Tín dụng cho điều này được gửi tới @Lynn và câu trả lời của anh ấy cho số này có phải là số nguyên tố không?


1
@raznagul vô nghĩa, bạn không thể xác định độ dài của mảng tham số đầu vào. Xem câu trả lời 2 cho cùng một câu hỏi
edc65

@ edc65: Xin lỗi, tôi nên đọc ngoài câu trả lời đầu tiên.
raznagul

@Jasmes - Trong mã golf, một hàm sẽ có thể được gọi nhiều lần để có cùng một đầu ra. Mã của bạn yêu cầu đặt lại cđể gọi lại chức năng.
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]));
}

chỉnh sửa 1: rất tiếc, đã bỏ lỡ một chút về việc trả về số bước. sửa chữa sớm

chỉnh sửa 2: đã sửa


3

Vợt, 183 156 byte

Có lẽ nhiều byte hơn có thể chơi được với việc chơi gôn hơn, nhưng đó là cho tôi. :)

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

Hoàn thành mô-đun với bộ kiểm tra với chức năng sạch hơn:

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

Chạy nó như raco test e.rkt

Kudos chính cho @cat khám phá prime?chức năng không có giấy tờ .


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)là để thử nghiệm chính, f(a,n)là cho chức năng thoát. Sử dụng:

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

Phiên bản bị đánh cắp:

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

Giải trình:

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

Đây là một chuỗi lười biếng của các chỉ số đi qua theo quy tắc. Nếu cuối cùng chỉ mục vượt quá giới hạn mảng đầu vào ( !(0 <= * < a)điều kiện), chuỗi là hữu hạn; mặt khác, các chỉ số chu kỳ vô hạn.

Trình tự đó được đưa đến chức năng ẩn danh nội bộ:

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

Nếu chuỗi được xác định tại chỉ mục được cho bởi kích thước của mảng đầu vào, thì nó phải đã nhập vào một chu kỳ vô hạn, do đó 0được trả về. Nếu không, kích thước của chuỗi +$_được trả lại.


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

Hãy thử trực tuyến!

Danh sách dựa trên 0. Trả về false (để trống) nếu danh sách không thể truy cập được.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.