Lompat Array!


19

Mari kita main game satu pemain yang disebut jump the array . Untuk bermain, Anda hanya perlu array bilangan bulat, katakanlah a. Anda mulai pada suatu posisi i, dan pada setiap belokan, Anda melompat ke posisi baru. Pada gilirannya n,

  • jika ngenap, Anda melompat ke posisi absolut a[i] mod length(a),
  • jika naneh, Anda melompat ke posisi relatif (i + a[i]) mod length(a).

Pengindeksan array dimulai dari nol. Anda dapat menghitung lompatan pertama sebagai belokan 0atau belokan 1, yang memberikan gim yang berbeda. Karena ruang keadaan permainan terbatas (gerakan Anda ditentukan oleh posisi Anda dan paritas nomor belokan), Anda tentu saja pada akhirnya akan memasukkan lingkaran yang panjangnya genap. Dilambangkan dengan loop(a, i, b)panjang loop ini, ketika lompatan pertama dihitung sebagai belokan b.

Memasukkan

Array kosong kosong auntuk bermain game.

Keluaran

Jumlah maksimum psedemikian sehingga, ketika mulai pada beberapa posisi idan menghitung belokan pertama sebagai salah satu 0atau 1, Anda akhirnya memasukkan satu lingkaran panjang 2 * p. Dengan kata lain, output Anda adalah angka

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

Aturan

Anda dapat memberikan fungsi atau program lengkap. Hitungan byte terkecil menang, dan celah standar tidak diizinkan.

Uji kasus

[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 Ya, ini pilihan terakhir, seperti kata Martin.
Zgarb

Saya berasumsi bahwa moddidefinisikan sebagai selalu positif ( -1 mod 5 == 4) tidak seperti dalam C. Apakah itu yang terjadi?
nutki

@nutki Ya, saya menggunakan gaya Haskell mod, yang selalu memberikan hasil tidak negatif.
Zgarb

Jika ternyata pengindeksan nol memberikan hasil yang berbeda dari pengindeksan satu, haruskah kita mengeluarkan hasil, atau mana yang lebih rendah?
KSFT

@ MartinBüttner Tidak, saya bertanya tentang pengindeksan belokan , bukan array.
KSFT

Jawaban:


6

Pyth : 28 karakter (Python 2: 116 karakter)

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

Pemakaian:

Coba di sini: Pyth Compiler / Executor

Ia mengharapkan daftar bilangan bulat sebagai input [0,2,5,4,-9,0,-1,1,-1,1,-6]

Penjelasan:

Saya perhatikan satu properti penting dari fungsi loop: Untuk masing-masing iada j, sehingga loop(a,i,0) == loop(a,j,1)dan sebaliknya. Karena itu kita hanya perlu menghitung nilai loop(a,i,b)untuk b=0.

Bukti: Jika adalah siklus i -> j -> k -> ... -> z -> idengan b = 0, maka ada siklus j -> k -> ... -> z -> i -> jdengan b = 1.

Karenanya skrip sederhana dapat bekerja dengan cara berikut. Iterasi atas semua idan coba jangkau idengan komputasi berulang i = a[(i + a[i]) mod len(a)] mod len(a). Karena perhitungan ini dapat berjalan ke dalam siklus tanpa i, kami membatalkan perhitungan setelah len(a)langkah-langkah. Kemudian kami mencetak siklus maksimum.

Sebuah Python 2 implementasi terlihat seperti ini ( 125 karakter }:

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)

Untuk implementasi pyth saya menggunakan pendekatan yang sedikit berbeda. Untuk setiap isaya menghitung daftar posisi, dan mencari idalam daftar ini.

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)  

sunting: Python 2: 116 karakter

solusi @proud haskeller adalah saya beberapa karakter lebih pendek dari solusi Python saya, karena itu saya 'harus' mempersingkat sedikit.

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

Perbedaannya adalah, saya menghitung angka secara rekursif dan bukan iteratif.


8

Python - 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
Jika Anda memasukkan len(a)variabel dan mengganti semua len(a)dengan nama variabel itu, Anda dapat menyimpan beberapa karakter.
ProgramFOX

1
Beberapa ide: t+=1;t%=2-> t^=1dan if t: j=(j+a[j])%z else: j=a[j]%z->j=(t*j+a[j])%z
Vektor

1
Gunakan hanya satu ruang untuk indentasi. Menghemat 9 karakter di sini.
PurkkaKoodari

1
Gagasan lain: while c not in s[:-1]:bisa jadi while(c in s[:-1])-1:.
PurkkaKoodari

1
Dan satu lagi. Anda tidak harus menggunakan j, karena loop ini menetapkan konten range(z)untuk ibukannya menambahnya. Cukup ganti jdengan iuntuk menyimpan 4 karakter.
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

ini menghasilkan daftar tanpa batas untuk setiap titik awal (untuk alasan bermain golf, kami beralih pada semua nilai alih-alih semua indeks, yang setara). lalu menghitung siklus setiap daftar (panjang siklus xsadalah xs % []).

ini menggunakan pengamatan @ jakubes tentang siklus. karena langkah 2 langkah sekaligus, kita tidak perlu membagi 2 pada akhir.

Sunting : sekarang menggunakan trik @MthViewMark untuk menjatuhkan nelemen pertama untuk menjamin memiliki siklus dengan elemen pertama. Ngomong-ngomong, saya berhasil memasukkan algoritmanya ke 112karakter:

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 karakter

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

Contoh:

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

Ini menggunakan pengamatan @ jakube bahwa Anda hanya perlu memeriksa setengah nilai awal, sambil melakukan 2 langkah per iterasi.


Anda bisa menekan whereke sebelumnya ]. Juga, apakah Anda mencoba menggunakan cycle l!!ibukan l!!mod n(length l)?
haskeller bangga

Juga, Anda bisa sebaris b, dan menggunakan penjaga pola |n<-l auntuk menghilangkan where.
haskeller bangga

2

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

Fungsi untuk jawabannya adalah j.
Fungsi rekursif lmengembalikan panjang loop untuk array yang diberikan, mulai, dan belok pertama, dan fungsi jmenemukan maks.


Saya pikir Anda dapat menyimpan beberapa karakter dengan mendefinisikan j dengan a lambda.
KSFT

1

Mathematica, 189 162 161 byte

Jika fungsi anonim diizinkan - 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]&

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

Menjalankan ini pada semua kasus uji:

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

Hasil dalam:

{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

DEMO

Ini hampir merupakan port dari jawaban Mathematica saya.


Ini terlihat sangat mirip dengan milikku. Milik saya dimatikan satu (sebelum dibagi dua) pada awalnya. Saya masih tidak yakin mengapa, tetapi saya hanya mengurangi satu sebelum membaginya.
KSFT

Saya tidak tahu Mathematica, jadi saya benar-benar tidak bisa membantu lagi.
KSFT

@Zgarb Oh! Nah itu menjelaskan semuanya. Aku bahkan tidak memikirkan itu. Terima kasih!
kukac67

Fordengan 3 argumen biasanya lebih pendek dari While(karena Anda dapat menghemat titik koma di depan For).
Martin Ender

1

Mathematica, 113 112 karakter

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

Contoh:

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'

Argumen pertama tidak dihitung menjadi panjang (inisialisasi array ke $1dan binisialisasi ke $2- pilih "permainan").

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.