Nhảy mảng!


19

Hãy chơi một trò chơi một người chơi gọi là nhảy mảng . Để chơi, bạn chỉ cần một mảng các số nguyên, nói a. Bạn bắt đầu ở một vị trí nào đó i, và trên mỗi lượt, bạn nhảy sang một vị trí mới. Lần lượt n,

  • nếu nlà chẵn, bạn nhảy đến vị trí tuyệt đối a[i] mod length(a),
  • nếu nlà số lẻ, bạn nhảy đến vị trí tương đối (i + a[i]) mod length(a).

Việc lập chỉ mục mảng bắt đầu từ 0. Bạn có thể tính bước nhảy đầu tiên là lượt 0hoặc lượt 1, điều này mang lại một trò chơi khác. Vì không gian trạng thái của trò chơi là hữu hạn (di chuyển của bạn được xác định bởi vị trí của bạn và tính chẵn lẻ của số lần lượt), nên cuối cùng bạn sẽ nhập một vòng có độ dài chẵn. Biểu thị theo loop(a, i, b)độ dài của vòng lặp này, khi bước nhảy đầu tiên được tính là lượt b.

Đầu vào

Một mảng không nhiều asố nguyên để chơi trò chơi.

Đầu ra

Số lượng tối đa psao cho, khi bắt đầu ở một số vị trí ivà đếm lượt đầu tiên là 0hoặc 1, cuối cùng bạn sẽ nhập một vòng có độ dài 2 * p. Nói cách khác, đầu ra của bạn là số

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

Quy tắc

Bạn có thể cung cấp một chức năng hoặc một chương trình đầy đủ. Số byte nhỏ nhất sẽ thắng và các sơ hở tiêu chuẩn không được phép.

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

[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 Vâng, đó là lựa chọn thứ hai, như Martin nói.
Zgarb

Tôi giả sử rằng nó modđược định nghĩa là luôn luôn dương ( -1 mod 5 == 4) không giống như trong C. Có phải vậy không?
nutki

@nutki Vâng, tôi sử dụng kiểu Haskell mod, luôn mang lại kết quả không âm.
Zgarb

Nếu các lượt lập chỉ mục bằng 0 cho kết quả khác với chỉ mục một, chúng ta nên đưa ra kết quả nào, hoặc kết quả nào ít hơn?
KSFT

@ MartinBüttner Không, tôi đã hỏi về việc lập chỉ mục các lượt , không phải các mảng.
KSFT

Câu trả lời:


6

Pyth : 28 ký tự (Python 2: 116 ký tự)

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

Sử dụng:

Dùng thử tại đây: Trình biên dịch / thực thi Pyth

Nó mong đợi một danh sách các số nguyên làm đầu vào [0,2,5,4,-9,0,-1,1,-1,1,-6]

Giải trình:

Tôi nhận thấy một thuộc tính quan trọng của hàm loop: Đối với mỗi icó một j, do đó loop(a,i,0) == loop(a,j,1)và ngược lại. Do đó chúng ta chỉ cần tính toán các giá trị loop(a,i,b)cho b=0.

Chứng minh: Nếu là một chu kỳ i -> j -> k -> ... -> z -> ivới b = 0, thì tồn tại chu trình j -> k -> ... -> z -> i -> jvới b = 1.

Do đó, một kịch bản đơn giản có thể làm việc theo cách sau. Lặp đi lặp lại tất cả ivà cố gắng tiếp cận ibằng cách tính toán lặp i = a[(i + a[i]) mod len(a)] mod len(a). Vì tính toán này có thể chạy trong một chu kỳ mà không có i, chúng tôi hủy tính toán sau len(a)các bước. Sau đó, chúng tôi in chu kỳ tối đa.

Một triển khai Python 2 trông như thế này ( 125 ký tự }:

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)

Để thực hiện pyth tôi đã sử dụng một cách tiếp cận khác nhau một chút. Đối với mỗi itôi tính toán danh sách các vị trí và tìm kiếm itrong danh sách này.

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)  

chỉnh sửa: Python 2: 116 ký tự

Giải pháp của @proud haskeller là một vài ký tự ngắn hơn giải pháp Python của tôi, do đó tôi 'đã' rút ngắn nó lại một chút.

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

Sự khác biệt là, tôi tính toán số đệ quy thay vì lặp.


8

Con trăn - 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
Nếu bạn đặt len(a)một biến và thay thế tất cả len(a)s bằng tên của biến đó, bạn có thể lưu một số ký tự.
Chương trìnhFOX

1
Một số ý tưởng: t+=1;t%=2-> t^=1if t: j=(j+a[j])%z else: j=a[j]%z->j=(t*j+a[j])%z
Vectorized

1
Chỉ sử dụng một không gian để thụt lề. Lưu 9 ký tự ở đây.
PurkkaKoodari

1
Một ý tưởng khác: while c not in s[:-1]:có thể while(c in s[:-1])-1:.
PurkkaKoodari

1
Và một cái nữa. Bạn không cần phải sử dụng j, như vòng lặp này gán nội dung của range(z)để ithay vì incrementing nó. Chỉ cần thay thế jvới iđể tiết kiệm 4 ký tự.
PurkkaKoodari

5

Haskell, 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

điều này tạo ra một danh sách vô hạn cho mỗi điểm bắt đầu (vì lý do chơi gôn, chúng tôi lặp lại trên tất cả các giá trị thay vì tất cả các chỉ mục, tương đương). sau đó nó tính toán chu kỳ của mỗi danh sách (độ dài chu kỳ xsxs % []).

nó sử dụng các quan sát của @ jakubes về các chu kỳ. bởi vì nó bước 2 bước cùng một lúc, chúng ta không cần chia cho 2 ở cuối.

Chỉnh sửa : hiện đang sử dụng thủ thuật của @ MthViewMark về việc bỏ các nphần tử đầu tiên để đảm bảo có một chu kỳ với phần tử đầu tiên. Nhân tiện, tôi đã xoay sở được thuật toán của anh ấy thành các 112nhân vật:

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 ký tự

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

Ví dụ:

λ: 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

Điều này giúp sử dụng quan sát của @ jakube rằng bạn chỉ cần kiểm tra một nửa giá trị bắt đầu, trong khi thực hiện 2 bước trên mỗi lần lặp.


Bạn có thể squish wherecái trước ]. Ngoài ra, bạn đã thử sử dụng cycle l!!ithay vì l!!mod n(length l)?
tự hào

Ngoài ra, bạn có thể nội tuyến bvà sử dụng một trình bảo vệ mẫu |n<-l ađể loại bỏ where.
tự hào

2

Con trăn, 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

Chức năng trả lời là j.
Hàm đệ quy ltrả về độ dài vòng lặp cho một mảng nhất định, bắt đầu và lượt đầu tiên và hàm jtìm cực đại.


Tôi nghĩ bạn có thể lưu một số ký tự bằng cách định nghĩa j với a lambda.
KSFT

1

Toán học, 189 162 161 byte

Nếu các chức năng ẩn danh được cho phép - 161 byte:

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

Mặt khác - 163 byte:

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

Chạy này trên tất cả các trường hợp thử nghiệm:

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

Kết quả trong:

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

Python 2, 202 byte

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

BẢN GIỚI THIỆU

Đây gần như là một cổng của câu trả lời Mathicala của tôi.


Cái này trông rất giống với tôi. Của tôi đã bị tắt bởi một (trước khi chia cho hai) lúc đầu. Tôi vẫn không chắc tại sao, nhưng tôi chỉ trừ đi một trước khi chia.
KSFT

Tôi không biết Mathicala, vì vậy tôi thực sự không thể giúp nhiều hơn.
KSFT

@Zgarb ơi! Vâng, điều đó giải thích mọi thứ. Tôi thậm chí không nghĩ về điều đó. Cảm ơn!
kukac67

Forvới 3 đối số thường ngắn hơn While(vì bạn có thể lưu vào dấu chấm phẩy ở phía trước For).
Martin Ender

1

Mathicala, 113 112 ký tự

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

Thí dụ:

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

là 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'

Đối số đầu tiên không tính vào độ dài (khởi tạo mảng $1bkhởi tạo thành $2- chọn "trò chơi").

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.