배열을 뛰어라!


19

jump the array 라는 1 인용 게임을하겠습니다 . 재생하려면 정수 배열 만 필요합니다 (예 :) a. 당신은 어떤 위치에서 시작하고 i, 매 턴마다 새로운 위치로 점프합니다. 차례 n

  • 경우 n에도, 당신은 절대 위치로 이동 a[i] mod length(a),
  • 경우 n홀수, 당신은 상대적인 위치로 이동합니다 (i + a[i]) mod length(a).

배열 인덱싱은 0에서 시작합니다. 첫 번째 점프를 turn 0또는 turn 으로 계산하여 1다른 게임을 할 수 있습니다. 게임의 상태 공간이 유한하기 때문에 (당신의 이동은 당신의 위치와 턴 번호의 패리티에 의해 결정됩니다), 결국 당신은 결국 짝수 길이의 루프에 들어갈 것입니다. loop(a, i, b)첫 번째 점프가 turn으로 계산 될 때이 루프의 길이를 나타냅니다 b.

입력

a게임을하기 위해 비어 있지 않은 정수 배열 .

산출

최대 번호 p일부 위치에서 시작할 경우 같은 것을 i하고 중 바와 같이, 제 1 회전을 계산 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

예, Martin이 말한 것처럼 후자의 옵션입니다.
Zgarb

C와 달리 mod항상 긍정적 ( -1 mod 5 == 4) 으로 정의되어 있다고 가정합니다 . 그 경우입니까?
nutki

@nutki 예, Haskell 스타일을 사용하여 mod항상 음이 아닌 결과를 얻습니다 .
Zgarb

제로 인덱싱 회전이 원 인덱싱과 다른 결과를 제공하는 경우 결과를 출력해야합니까, 아니면 더 적은 것을 출력해야합니까?
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하여 도달하려고 노력하십시오 . 이 계산은가없는 주기로 진행될 수 있으므로 단계 후에 계산을 취소 합니다. 그런 다음 최대 사이클을 인쇄합니다.ii = a[(i + a[i]) mod len(a)] mod len(a)ilen(a)

파이썬 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)  

편집 : 파이썬 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)그 변수의 이름들, 당신은 몇 가지 문자를 저장할 수 있습니다.
ProgramFOX

1
몇 가지 아이디어 : t+=1;t%=2-> t^=1if 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그것을 증가 대신. 그냥 교체 ji4 저장 문자.
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

이것은 각 시작점에 대해 무한한 목록을 생성합니다 (골프를 이유로 모든 인덱스 대신 모든 값을 반복합니다). 그런 다음 각 목록의주기를 계산합니다 (주기 길이 xsxs % []).

사이클에 대한 @jakubes의 관찰을 사용합니다. 한 번에 2 단계 씩 진행되므로 마지막에 2로 나눌 필요가 없습니다.

편집 : 이제 첫 번째 n요소와의 순환을 보장하기 위해 첫 번째 요소를 삭제하는 @MthViewMark의 트릭을 사용합니다. 그건 그렇고, 나는 그의 알고리즘을 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

하스켈-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로 j를 정의하여 일부 문자를 저장할 수 있다고 생각합니다 lambda.
KSFT

1

Mathematica, 189162161 바이트

익명 함수가 허용되는 경우-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}

파이썬 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

데모

이것은 거의 Mathematica 답변의 포트입니다.


이것은 내 것과 매우 비슷합니다. 처음에는 광산이 1 개씩 (2로 나누기 전에) 꺼졌습니다. 나는 왜 그런지 잘 모르겠지만, 나누기 전에 하나를 뺍니다.
KSFT

나는 Mathematica를 모른다. 그래서 나는 정말로 더 많은 것을 도울 수 없다.
KSFT

@Zgarb 오! 그것은 모든 것을 설명합니다. 나는 그런 생각조차하지 않았다. 감사!
kukac67

For3 개의 인수는 일반적으로보다 짧습니다 While(앞의 세미콜론에 저장할 수 있으므로 For).
Martin Ender

1

매쓰, 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

ised 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'

첫 번째 인수는 길이에 포함되지 않습니다 (배열 초기화 $1b초기화 $2- "게임"선택).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.