Array Escape - піти звідти


32

Одного разу ти прокинешся лише для того, щоб потрапити в масив. Ви намагаєтеся просто піти звідти, беручи один індекс на час, але, схоже, є й інші правила:

Масив повністю заповнений натуральними числами.

  • Якщо ви опинитесь на індексі n, переходите до індексу array[n], крім:
  • Якщо ви опинитесь на індексі, nякий є простим числом, ви робите array[n]кроки назад

Приклад: Ви починаєте з індексу 4в цьому масиві (індекс запуску 0):

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

Оскільки значення поля, на якому ви знаходитесь 8, переходить до індексу 8як перший крок. Поле, на яке ви приземляєтеся, містить значення 2. Потім ви переходите до індексу 2як свого другого кроку. Як 2просте число, ви робите 5 кроків назад, це ваш третій крок. Оскільки немає індексу -3, ви успішно вийшли з масиву загалом за 3 кроки.

Ваше завдання:

Написати програму або функцію, яка приймає масив та індекс запуску як параметр і виводить кількість кроків для виходу з масиву. Якщо ви не можете уникнути масиву (наприклад, [2,0,2]з start-index 2=> ви постійно переходите від індексу 2до 0), виведіть помилкове значення. Ви можете використовувати індексацію на основі однієї чи нульової індексації, але, будь ласка, вкажіть, яку ви використовуєте.

Тестові справи

Вхід: [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

Найкоротша відповідь виграє.


7
Ласкаво просимо до PPCG! Це гідний перший виклик. :) Чи можемо ми також використовувати індексацію на основі 1? Також може бути корисним ще кілька тестових випадків. Для майбутніх проблем ви також можете скористатися пісочницею, де ви можете отримати зворотній зв'язок від громади, перш ніж виклик буде розповсюджений.
Мартін Ендер


1
@Martin Ender це не пов'язано з питанням ... але мені як мобільному користувачеві неможливо використовувати пісочницю. Що мені робити, щоб отримати зворотній зв'язок на свої запитання, перш ніж їх публікувати?
користувач6245072

1
@JerryJeremiah, чому ти не можеш зробити 3 кроки назад? ви приземлитеся на індекс 2, якщо почнете о 5 і зробите 3 кроки назад
Майкл Кунст

5
@ user902383 переходить до індексу 2, що є простим, тому ми робимо 2 кроки назад і переходимо до індексу 0, що не є простим. Значення в індексі 0 дорівнює 2, тому ми переходимо до індексу 2, який є простим ... повторити
edc65

Відповіді:



9

Пітон, 161 138 байт

Кредити для фабрикантів.

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

Ідей це!

Як це працює

Теорема Вілсона використовується для простої перевірки.

Виявлення циклу, зберігаючи бачені індекси до масиву ( l) та перевіряючи, чи знаходиться поточний індекс l.


6

Пітон, 107 байт

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

Використання: f(list, start)ex:f([2,5,6,8,1,2,3], 3)

Повернення 0для циклів (виявляється, коли n > len(a))


5

Матлаб, 138 байт

Це прямий підхід із використанням індексів на основі 1, оскільки Matlab використовує 1-базисні індекси за замовчуванням. Для підрахунку кількості кроків використовуємо forцикл, що рахує від 1 до нескінченності (!). У випадку, якщо нам не вдалося уникнути масиву, ми використовуємо вектор, vщоб відстежувати, які записи ми вже відвідали. Якщо ми відвідуємо запис двічі, ми знаємо, що ми зациклювались на невикористовуваному циклі. Щоб перевірити, чи ми знаходимось поза масивом, ми використовуємо try/catchструктуру, яка також виловлює винятки з меж.

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 байти

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

Пояснення

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

Спробуйте в Інтернеті


4

JavaScript (ES6), 100

База індексу 0. Примітка. Ця функція змінює вхідний масив

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

Менше гольфу

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

Тест

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 байт

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

Завдяки Кевіну 11 байт кусає пил.


Кілька речей, щоб пограти ще трохи: Stack<Integer>i=new Stack<>();можна змінити Stack i=new Stack();і return 1==2;змінити на return 0>1;. Також ви можете згадати, що це Java 7 замість Java взагалі.
Кевін Круїссен

@KevinCruijssen Я не впевнений, чи має сенс згадати, що це java 7, тому що особливо зараз це рішення сумісне з більшістю версій Java.
user902383

Що ж, у Java 8 ви можете використовувати лямбдас, який коротше: a,b->{...}замість цього Object e(int[]a,int b){...}, саме тому я особисто згадую Java 7, щоб люди могли знати, що я навмисно не використовував лямбди Java 8, але це залежить від вас.
Kevin Cruijssen

@KevinCruijssen досить справедливо, коли я використовую lamda, я вказую версію java, але коли рішення працює з java 7, зазвичай це також працює з java 8, тому додавати версію було безглуздо. Але ви можете мати рацію, я повинен вказати мінімальну версію.
user902383

4

CJam, 44 байти

Очікує index arrayна стек.

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

Спробуйте в Інтернеті!

Моя перша відповідь CJam, отже, чому це так страшно і імперативно ...

: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

(вважається нормальним збої після правильного виводу як надрукованого, що і робить тут програма)


3

C, 121 байт

Функція fприймає масив, стартовий індекс (на основі 0) та кількість елементів у масиві, оскільки немає можливості перевірити кінець масиву в C (принаймні, я не знаю жодного).

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

Спробуйте на ideone!

Примітка: function p(n) тестуйте, чи nє основним чи ні. Подяка за це належить @Lynn, і його відповідь за: Чи це число прем'єр?


1
@raznagul дурниця, ви не можете визначити довжину масиву вхідних параметрів. Дивіться відповідь 2 на те саме питання
edc65

@ edc65: Вибачте, я мав би прочитати після першої відповіді.
raznagul

@Jasmes - У коді гольфу функцію слід мати можливість викликати кілька разів, щоб отримати однаковий вихід. Для повторного cвиклику функції ваш код потребує скидання .
owacoder

3

JavaScript, 121 132 байт

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

редагувати 1: ой, пропустив біт про повернення кількості кроків. виправити скоро.

редагувати 2: виправлено


3

Ракетка, 183 156 байт

Можливо, більше байтів можна зберегти з подальшим гольфом, але це все для мене. :)

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

Комплектний модуль з тестовим набором з функцією очищення:

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

Виконайте це як raco test e.rkt

Основні кудо для @cat виявляють недокументовану prime?функцію .


2

Java, 163 160 байт

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)призначений для основного тестування, f(a,n)для функції втечі. Використання:

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

Безгольова версія:

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 байт

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

Пояснення:

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

Це лінива послідовність індексів, які проходять за правилом. Якщо індекс зрештою перевищує межі вхідного масиву ( !(0 <= * < a)умова), послідовність є кінцевою; в іншому випадку індекси кружляють нескінченно.

Ця послідовність подається до внутрішньої анонімної функції:

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

Якщо послідовність визначена в індексі, заданому розміром вхідного масиву, вона повинна була ввести нескінченний цикл, тому 0повертається. В іншому випадку розмір послідовності +$_повертається.


1

Perl 5 , 107 + 1 ( -a) = 108 байт

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

Спробуйте в Інтернеті!

Список на основі 0. Повертає помилку (порожнє), якщо список неможливо змінити.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.