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
Очень тесно связаны
Питер Тейлор
1
@Martin Ender, это не связано с вопросом ... но я, как мобильный пользователь, считаю невозможным использование песочницы. Что я должен сделать, чтобы получить обратную связь по моим вопросам перед тем, как отправлять их?
user6245072
1
@JerryJeremiah, почему ты не можешь сделать 3 шага назад? Вы попадете в индекс 2, если начнете с 5 и сделаете 3 шага назад
Майкл Кунст,
5
@ user902383 идет к индексу 2, который является простым, поэтому мы делаем 2 шага назад и идем к индексу 0, который не является простым. Значение по индексу 0 равно 2, поэтому мы переходим к индексу 2, который является простым ... повторить
edc65

Ответы:

4

Pyth, 31 байт

KlQ%tl-.u?}NUK?P_N-N@QN@QNKQEKK

Тестовые случаи

Для указания ложного значения используется ноль, в противном случае количество прыжков.

Кэмерон МакКласки
источник
9

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

Идео это!

Как это работает

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

Обнаружение цикла путем сохранения видимых индексов в array ( l) и проверки наличия текущего индекса l.

Дрянная Монахиня
источник
6

Python, 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))

RootTwo
источник
5

Matlab, 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
flawr
источник
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

Попробуйте онлайн

Emigna
источник
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)
  
})  

edc65
источник
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 байтов кусает пыль.

user902383
источник
Несколько вещей для игры в гольф еще немного: 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, но решать вам.
Кевин Круйссен
@ 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является ли простое число или нет. Кредит на это идет к @ Линн и его ответу Для этого числа простое число?

Jasmes
источник
1
@raznagul ерунда, вы не можете определить длину массива входных параметров. Смотрите ответ 2 на тот же вопрос
edc65
@ edc65: Извините, я должен был прочитать после первого ответа.
Разнагул
@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: исправлено

Yay295
источник
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?функции .

Winny
источник
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)для функции escape. Использование:

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 на основе списка. Возвращает false (пусто), если список неизбежен.

Xcali
источник