アレイをジャンプ!


19

jump the arrayというワンプレイヤーゲームをプレイしましょう。プレイするには、整数の配列、たとえばのみが必要aです。ある位置から開始しi、各ターンで新しい位置にジャンプします。順番にn

  • n偶数の場合、絶対位置にジャンプしa[i] mod length(a)
  • nが奇数の場合、相対位置にジャンプします(i + a[i]) mod length(a)

配列のインデックス付けはゼロから始まります。最初のジャンプをturn 0またはturn としてカウントできます1。これにより、異なるゲームができます。ゲームの状態空間は有限であるため(あなたの動きは自分の位置とターン番号のパリティによって決定されます)、もちろん最終的には偶数の長さのループに入ります。表すloop(a, i, b)最初のジャンプがターンとしてカウントされ、このループの長さ、b

入力

aゲームをプレイする整数の空でない配列。

出力

pある位置から開始しi、最初のターンをかのいずれかとしてカウントする0場合1、最終的にlengthのループに入るような最大数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ええ、マーティンが言ったように、後者のオプションです。
ズガルブ

Cの場合とは異なり、mod常に正(-1 mod 5 == 4)と定義されていると思います。そうですか?
-nutki

@nutkiはい、私はHaskellスタイルを使用しmodます。これは常に非負の結果をもたらします。
ズガルブ

ゼロインデックスターンが1インデックスと異なる結果を与える場合、結果を出力する必要がありますか、どちらか小さい方を出力しますか?
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]

説明:

関数の1つの重要なプロパティに気付きましたloop。それぞれiにがあるjためloop(a,i,0) == loop(a,j,1)、その逆も同様です。そこで我々は唯一の値を計算する必要があるloop(a,i,b)ためb=0

証明:サイクルである場合i -> j -> k -> ... -> z -> ib = 0は、サイクルが存在するj -> k -> ... -> z -> i -> jb = 1

したがって、単純なスクリプトは次のように機能します。すべてii反復処理し、反復計算によって到達しようとします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
インデントするにはスペースを1つだけ使用します。ここに9文字を保存します。
PurkkaKoodari

1
別のアイデア:while c not in s[:-1]:可能性がありますwhile(c in s[:-1])-1:
-PurkkaKoodari

1
そしてもう一つ。を使用する必要はありません。jこのループは、インクリメントrange(z)するi代わりにto の内容を割り当てます。に置き換え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

これにより、開始点ごとに無限リストが生成されます(ゴルフの理由から、すべてのインデックスではなく、すべての値を反復処理しますが、これは同等です)。次に、各リストのサイクルを計算します(のサイクル長はxsです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

これは、繰り返しごとに2ステップを実行しながら、開始値の半分しかチェックする必要がないという@jakubeの観察を利用します。


where前につぶすことができました]。また、cycle l!!i代わりに使用してみましたl!!mod n(length l)か?
誇りに思ってhaskeller

また、インラインにすることができb、パターンガード|n<-l aを使用してwhere
誇りに思っている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

答えの関数は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

デモ

これは、私のMathematicaの答えのほぼ移植版です。


これは私のものと非常によく似ています。鉱山は最初は1つ(2で割る前)オフでした。理由はまだわかりませんが、分割する前に1を差し引いただけです。
KSFT

私はMathematicaを知らないので、それ以上のことは本当にできません。
KSFT

@Zgarbああ!まあそれはすべてを説明しています。私もそれを考えていませんでした。ありがとう!
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

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.