Dizi atlamak!


19

Diziyi atlama adlı tek oyunculu bir oyun oynayalım . Oynamak için, sadece bir dizi tamsayıya ihtiyacınız var a. Bir pozisyonda başlarsınız ive her turda yeni bir pozisyona atlarsınız. Sırayla n,

  • eğer neşitse, mutlak pozisyona atlarsınız a[i] mod length(a),
  • eğer ngarip, göreli konuma atlamak (i + a[i]) mod length(a).

Dizi indeksleme sıfırdan başlar. İlk atlamayı farklı bir oyun veren dönüş 0veya dönüş olarak sayabilirsiniz 1. Oyunun durum alanı sınırlı olduğu için (hareketiniz pozisyonunuza ve dönüş numarasının paritesine göre belirlenir), elbette sonunda eşit uzunlukta bir döngü gireceksiniz. loop(a, i, b)İlk atlama dönüş olarak sayıldığında, bu döngünün uzunluğunu belirtin b.

Giriş

aOyunu oynamak için boş bir tamsayı dizisi .

Çıktı

Maksimum sayı p, bir konuma başlarken ive ilk dönüşü ya 0da olarak sayarken, 1sonunda bir uzunluk döngüsü girersiniz 2 * p. Başka bir deyişle, çıktınız sayıdır

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

kurallar

Bir işlev veya tam bir program verebilirsiniz. En küçük bayt sayısı kazanır ve standart boşluklara izin verilmez.

Test senaryoları

[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 Evet, Martin'in dediği gibi ikinci seçenek.
Zgarb

Ben bunun aksine modher zaman pozitif ( -1 mod 5 == 4) olarak tanımlandığını varsayalım.
nutki

@nutki Evet, modher zaman olumsuz olmayan sonuçlar veren Haskell tarzı kullanıyorum .
Zgarb

Sıfır indeksleme dönüşleri bir endekslemeden farklı bir sonuç verirse, sonuçlardan birini veya hangisinin daha azını çıkarmalıyız?
KSFT

MartinBüttner No @, ben indeksleme soruyordu dönüşler değil, diziler.
KSFT

Yanıtlar:


6

Pyth : 28 karakter (Python 2: 116 karakter)

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

Kullanımı:

Burada deneyin: Pyth Derleyici / Yönetici

Girdi olarak bir tamsayı listesi bekliyor [0,2,5,4,-9,0,-1,1,-1,1,-6]

Açıklama:

İşlevin önemli bir özelliğini fark ettim loop: Her biri iiçin bir j, böylece loop(a,i,0) == loop(a,j,1)ve tam tersi var. Bu nedenle biz sadece değerlerini hesaplamak gerekir loop(a,i,b)için b=0.

İspat: ile bir döngü i -> j -> k -> ... -> z -> iise b = 0, j -> k -> ... -> z -> i -> jile döngü vardır b = 1.

Bu nedenle basit bir komut dosyası aşağıdaki şekilde çalışabilir. Her şeyi yineleyin ve yinelemeli hesaplamayla iulaşmaya çalışın . Bu hesaplama olmadan bir döngüye girebileceğinden , adımlardan sonra hesaplamayı iptal ederiz . Sonra maksimum döngüyü yazdırıyoruz.ii = a[(i + a[i]) mod len(a)] mod len(a)ilen(a)

Bir Python 2 uygulaması şöyle görünür ( 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)

Pyth uygulaması için biraz farklı bir yaklaşım kullandım. Her biri iiçin pozisyon listesini hesaplar ve ibu listede ararım.

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)  

düzenleme: Python 2: 116 karakter

@proud haskeller'ın çözümü Python çözümümden birkaç karakter daha kısaydı, bu yüzden biraz kısaltmak zorunda kaldım.

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

Fark, sayıyı yinelemeli olarak yinelemeli olarak hesaplamamdır.


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
len(a)Bir değişken koyar ve tüm len(a)değişkenleri bu değişkenin adıyla değiştirirseniz , bazı karakterleri kaydedebilirsiniz.
ProgramFOX

1
Bazı fikirler: t+=1;t%=2-> t^=1ve if t: j=(j+a[j])%z else: j=a[j]%z->j=(t*j+a[j])%z
Vectorized

1
Girintilemek için yalnızca bir boşluk kullanın. Burada 9 karakter kaydeder.
PurkkaKoodari

1
Başka bir fikir: while c not in s[:-1]:olabilir while(c in s[:-1])-1:.
PurkkaKoodari

1
Ve bir tane daha. Sen kullanımı gerekmez jbu döngü içeriğini atar gibi range(z)hiç ibunu artan yerine. Sadece 4 karakter kaydetmek için jile değiştirin i.
PurkkaKoodari

5

Haskell'in 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

bu, her başlangıç ​​noktası için sonsuz bir liste oluşturur (golf nedenleriyle, eşdeğer olan tüm dizinler yerine tüm değerler üzerinde yineliyoruz). Daha sonra her bir listesi (döngü uzunluğu döngüsünü hesaplar xsIS xs % []).

@ jakubes'ın döngüler hakkındaki gözlemlerini kullanır. çünkü bir seferde 2 adım atıyor, sonunda 2'ye bölmemize gerek yok.

Düzenleme : şimdi @ MthViewMark ilk nöğe ile bir döngü olması garanti ilk öğeleri bırakarak hile kullanarak . Bu arada, algoritmasını 112karakterlere golf etmeyi başardım :

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

Örnekler:

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

Bu, @ jakube'nin yineleme başına 2 adım gerçekleştirirken başlangıç ​​değerlerinin sadece yarısını kontrol etmeniz gerektiğini gözlemlemesini kullanır.


Bir whereöncekine ezebilirsin ]. Ayrıca, cycle l!!iyerine kullanmayı denediniz l!!mod n(length l)mi?
gururlu haskeller

Ayrıca, satır içi bve |n<-l aortadan kaldırmak için bir desen koruma kullanabilirsiniz where.
gururlu haskeller

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

Cevaplama işlevi j.
Özyinelemeli işlev l, belirli bir dizi, başlatma ve ilk dönüş için döngü uzunluğunu döndürür ve işlev jmaks.


Sanırım j ile a tanımlayarak bazı karakterler kaydedebilirsiniz lambda.
KSFT

1

Mathematica, 189162161 bayt

Anonim işlevlere izin veriliyorsa - 161 bayt:

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

Aksi takdirde - 163 bayt:

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

Bunu tüm test senaryolarında çalıştırma:

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

Sonuçlar:

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

Python 2, 202 bayt

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

Bu neredeyse Mathematica cevabımın bir limanı.


Bu benimkine çok benziyor. Benimki ilk başta (ikiye bölmeden önce) bir kişi tarafından kapandı. Hala neden olduğundan emin değilim, ama bölmeden önce bir tane çıkardım.
KSFT

Mathematica'yı tanımıyorum, bu yüzden daha fazla yardım edemem.
KSFT

@Zgarb Oh! Bu her şeyi açıklıyor. Bunu düşünmedim bile. Teşekkürler!
kukac67

For3 argümanla genellikle daha kısadır While(çünkü önünde noktalı virgül kaydedebilirsiniz 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]]]&

Misal:

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'

İlk argüman uzunluğa dahil edilmez (diziye başlatma $1ve biçine başlatma $2- "oyunu" seçin).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.