Прыгать массив!


19

Давайте поиграем в однопользовательскую игру под названием Jump the array . Чтобы играть, вам нужен только массив целых чисел, скажем a. Вы начинаете с какой-то позиции i, и на каждом ходу вы переходите на новую позицию. На очереди n,

  • если nчёт, вы переходите в абсолютную позицию a[i] mod length(a),
  • если nнечетно, вы переходите в относительную позицию (i + a[i]) mod length(a).

Индексация массива начинается с нуля. Вы можете посчитать первый прыжок как ход 0или поворот 1, что дает другую игру. Поскольку пространство состояний игры является конечным (ваш ход определяется вашей позицией и соотношением числа ходов), вы, конечно, в конечном итоге войдете в цикл равной длины. Обозначим loop(a, i, b)длину этого цикла, когда первый прыжок считается поворотом b.

вход

Непустой массив aцелых чисел для игры.

Выход

Максимальное число pтаких , что при запуске на некотором положение iи подсчет первого поворота или как 0или 1, в конечном итоге вы ввести петлю длины 2 * p. Другими словами, ваш вывод это число

max { loop(a, i, b)/2 : i in [0 .. length(a)-1], b in [0,1] }

правила

Вы можете дать функцию или полную программу. Наименьшее количество байтов выигрывает, и стандартные лазейки запрещены.

Контрольные примеры

[0] -> 1
[-213] -> 1
[1,3,12,-1,7] -> 1
[2,3,5,7,9,11,13,17,19] -> 2
[-2,3,-5,7,-9,11,-13,17,-19,23,-27] -> 3
[0,2,5,4,-9,0,-1,1,-1,1,-6] -> 4

@ kukac67 Да, это последний вариант, как сказал Мартин.
Згарб

Я предполагаю, что modопределяется как всегда положительный ( -1 mod 5 == 4) в отличие от C. Это так?
Nutki

@nutki Да, я использую стиль Haskell mod, который всегда дает неотрицательные результаты.
Згарб

Если повороты с нулевым индексированием дают результат, отличный от одного индекса, мы должны вывести либо результат, либо тот, который меньше?
KSFT

@ MartinBüttner Нет, я спрашивал об индексировании поворотов , а не массивов.
KSFT

Ответы:


6

Pyth : 28 символов (Python 2: 116 символов)

eSmhxtu+G%@Q+eG@QeGlQUQ]ddUQ

Использование:

Попробуйте это здесь: Pyth Compiler / Executor

Ожидается список целых чисел в качестве входных данных [0,2,5,4,-9,0,-1,1,-1,1,-6]

Объяснение:

Я заметил одно важное свойство функции loop: для каждого iесть j, так что loop(a,i,0) == loop(a,j,1)и наоборот. Поэтому нам нужно только вычислить значения loop(a,i,b)для b=0.

Доказательство: если есть цикл i -> j -> k -> ... -> z -> iс b = 0, то существует цикл j -> k -> ... -> z -> i -> jс b = 1.

Поэтому простой скрипт может работать следующим образом. Перебирайте все iи пытайтесь достичь с iпомощью итеративных вычислений i = a[(i + a[i]) mod len(a)] mod len(a). Поскольку это вычисление может выполняться без цикла i, мы отменяем вычисление после len(a)шагов. Затем мы печатаем максимальный цикл.

Python 2 реализация выглядит следующим образом ( 125 символа }:

a=input();A=len(a);m=[]
for i in range(A):
 j=i
 for c in range(A):
  j=a[(j+a[j])%A]%A
  if i==j:m+=[c+1];break
print max(m)

Для реализации Pyth я использовал немного другой подход. Для каждого iя вычисляю список позиций и ищу iв этом списке.

eSmhxtu+G%@Q+eG@QeGlQUQ]ddUQ  
  m                       UQ    for each d in [0, ..., len(input)-1] compute a
      u                ]d         list G (using reduce), 
                                  which is first initialized with G = [d]
                     UQ           for each H in [0, ..., len(input)-1]:
       +G                            append to G the value
         %@Q+eG@QeGlQ                   input[G[-1] +input[G[-1]] % len(input)
                                        (notice that list lookups in pyth work with modular wrapping)
     t                            remove the first value (which is d)
    x                    d        and find the index of d in this shortend list
                                  (it's -1, if d is not in the list)
   h                              add 1
eS                              print the maximum (end of sorted list)  

редактировать: Python 2: 116 символов

Решение @proud haskeller было на несколько символов короче, чем у моего решения на Python, поэтому мне пришлось немного его укоротить.

a=input();A=len(a);l=lambda j,i,c:c<=A and(c*(i==j)or l(a[(j+a[j])%A]%A,i,c+1));print max(l(i,i,0)for i in range(A))

Разница в том, что я вычисляю число рекурсивно, а не итеративно.


8

Питон - 157

a=input()
z=len(a)
b=[]
for i in range(z):
    s,c,t=[],"",0
    while(c in s[:-1])-1:j=(i*t+a[i])%z;c=`t`+`i`;s+=[c];t^=1
    b+=[len(s)-s.index(c)-1]
print max(b)/2

1
Если вы введете len(a)переменную и замените все len(a)s на имя этой переменной, вы можете сохранить некоторые символы.
ProgramFOX

1
Некоторые идеи: t+=1;t%=2-> t^=1и if t: j=(j+a[j])%z else: j=a[j]%z->j=(t*j+a[j])%z
Векторизация

1
Для отступа используйте только один пробел. Сохраняет 9 символов здесь.
PurkkaKoodari

1
Другая идея: while c not in s[:-1]:может быть while(c in s[:-1])-1:.
PurkkaKoodari

1
И еще один. Вы не должны использовать j, поскольку этот цикл присваивает содержимое range(z)для iвместо приращения его. Просто замените jс , iчтобы сохранить 4 символов.
PurkkaKoodari

5

Хаскелл, 120 105

f s|t<-l s=maximum[g$drop t$iterate(\i->s!!mod(i+s!!mod i t)t)i|i<-s]
g(x:s)=l$0:fst(span(/=x)o)
l=length

это создает бесконечный список для каждой отправной точки (по соображениям игры в гольф мы перебираем все значения вместо всех индексов, которые эквивалентны). затем он вычисляет цикл каждого списка (длина цикла xsis xs % []).

он использует наблюдения @ jakubes о циклах. потому что он делает 2 шага за раз, нам не нужно делить на 2 в конце.

Изменить : теперь, используя трюк @ MthViewMark, отбрасываем первые nэлементы, чтобы гарантировать цикл с первым элементом. Кстати, мне удалось поиграть в свой алгоритм по 112персонажам:

l=length
o(x:y)=1+l(takeWhile(/=x)y)
j a|n<-l a=maximum$map(o.drop n.iterate(\i->mod(a!!mod(i+a!!i)n)n))[0..n-1]

2

Haskell - 139 символов

l=length
o(x:y)=1+l(takeWhile(/=x)y)
j a=maximum$map(o.drop n.iterate(b!!))[0..n-1]
 where b=zipWith(\x y->mod(a!!mod(x+y)n)n)a[0..];n=l a

Примеры:

λ: j [0]
1

λ: j [-213]
1

λ: j [1,3,12,-1,7]
1

λ: j [2,3,5,7,9,11,13,17,19]
2

λ: j [-2,3,-5,7,-9,11,-13,17,-19,23,-27]
3

λ: j [0,2,5,4,-9,0,-1,1,-1,1,-6]
4

Это использует наблюдение @ jakube о том, что вам нужно проверять только половину начальных значений, выполняя 2 шага за итерацию.


Вы могли бы раздавить whereдо предыдущего ]. Кроме того, вы пытались использоватьcycle l!!i вместо l!!mod n(length l)?
гордый haskeller

Кроме того, вы можете встроить bи использовать шаблон защиты |n<-l aдля устранения where.
гордый haskeller

2

Питон, 160

l=lambda a,b,c,d:(b,c)in d and len(d)-d.index((b,c))or l(a,(a[b]+[0,b][c])%len(a),~c,d+[(b,c)])
j=lambda a:max(l(a,b,c,[])for b in range(len(a))for c in(0,1))/2

Функция для ответа есть j.
Рекурсивная функция lвозвращает длину цикла для заданного массива, начала и первого поворота, и функция jнаходит максимальное значение.


Я думаю, что вы можете сохранить некоторые символы, определив j с помощью lambda.
KSFT

1

Mathematica, 189 162 161 байт

Если разрешены анонимные функции - 161 байт:

Max[l=Length;Table[b={};n=p;i=s-1;e:={i,n~Mod~2};While[b~Count~e<2,b~AppendTo~e;h=#[[i+1]];i=If[EvenQ@n++,h,i+h]~Mod~l@#];l@b-b~Position~e+1,{s,l@#},{p,0,1}]/4]&

В противном случае - 163 байта:

f=Max[l=Length;Table[b={};n=p;i=s-1;e:={i,n~Mod~2};While[b~Count~e<2,b~AppendTo~e;h=#[[i+1]];i=If[EvenQ@n++,h,i+h]~Mod~l@#];l@b-b~Position~e+1,{s,l@#},{p,0,1}]/4]&

Выполнение этого во всех тестовых случаях:

f /@ {
  {0},
  {-213},
  {1, 3, 12, -1, 7},
  {2, 3, 5, 7, 9, 11, 13, 17, 19},
  {-2, 3, -5, 7, -9, 11, -13, 17, -19, 23, -27},
  {0, 2, 5, 4, -9, 0, -1, 1, -1, 1, -6}
}

Результаты в:

{1, 1, 1, 2, 3, 4}

Python 2, 202 байта

def l(a,n,i):
 b=[]
 while not[i,n]in b:b.append([i,n]);i=(a[i]if n<1 else i+a[i])%len(a);n+=1;n%=2
 return len(b)-b.index([i,n])
def f(a):print max([l(a,n,i) for n in[0,1]for i in range(len(a))])/2

DEMO

Это почти порт моего ответа Mathematica.


Это выглядит очень похоже на мое. Мой был выключен одним (прежде, чем делиться на два) сначала. Я до сих пор не уверен, почему, но я просто вычел один перед делением.
KSFT

Я не знаю Mathematica, поэтому я не могу больше помочь.
KSFT

@ Згарб О! Ну, это все объясняет. Я даже не думал об этом. Благодарность!
kukac67

Forс 3 аргументами обычно короче While(так как вы можете сохранить точку с запятой перед For).
Мартин Эндер

1

Mathematica, 113 112 символов

l=Length;m=MapIndexed;f=Max[l/@ConnectedComponents@Graph@m[Tr@#2->#&,Part@@Thread@Mod[#+{Tr@#2,1}&~m~#,l@#,1]]]&

Пример:

f /@ {
  {0},
  {-213},
  {1, 3, 12, -1, 7},
  {2, 3, 5, 7, 9, 11, 13, 17, 19},
  {-2, 3, -5, 7, -9, 11, -13, 17, -19, 23, -27},
  {0, 2, 5, 4, -9, 0, -1, 1, -1, 1, -6}
}

{1, 1, 1, 2, 3, 4}


1

исп 82

ised '@1{0,2,5,4,-9,0,-1,1,-1,1,-6};@2{1};' '@{4 5}{(@3{:$1_x++x*@2{1-$2}:}2*#$1)::[#$1]};{1+?{:@5{$3::$5}=$4:}@::[2*#$1]_0}/2'

Первый аргумент не учитывается в длине (инициализация массива в $1и bинициализация в $2- выберите «игру»).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.