跳阵列!


19

让我们玩一个名为“ 跳数组”的单人游戏。要播放,您只需要一个整数数组,例如a。您从某个位置开始i,然后在每个转弯处都跳到一个新位置。反过来n

  • 如果n是偶数,则跳至绝对位置a[i] mod length(a)
  • 如果n是奇数,则跳到相对位置(i + a[i]) mod length(a)

数组索引从零开始。您可以将第一个跳跃算作turn 0或turn 1,这会带来不同的游戏。由于游戏的状态空间是有限的(您的举动取决于您的位置和回合数的奇偶性),因此您最终将进入一个长度均匀的循环。loop(a, i, b)当第一个跳转被计为turn时,由该循环的长度表示b

输入项

一个非空a整数数组,用于玩游戏。

输出量

这样的最大数量p,当从某个位置开始i并将第一圈计算为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

@ kukac67是的,正如马丁所说,这是后一种选择。
Zgarb 2015年

与C中不同,我假定将mod其定义为始终为正(-1 mod 5 == 4)。是这种情况吗?
nutki'1

@nutki是的,我使用Haskell样式mod,它总是给出非负结果。
Zgarb 2015年

如果零分度转弯得出的结果与单分度转回的结果不同,那么我们应该输出其中一个结果,还是输出较小的那个?
KSFT 2015年

@MartinBüttner不,我问的是索引转弯,而不是数组。
KSFT 2015年

Answers:


6

Pyth:28个字符(Python 2:116个字符)

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

用法:

在这里尝试:Pyth编译器/执行器

它期望一个整数列表作为输入 [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并尝试i通过迭代计算达到目的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^=1if t: j=(j+a[j])%z else: j=a[j]%z->j=(t*j+a[j])%z
2015年

1
仅使用一个空格缩进。在这里保存9个字符。
PurkkaKoodari'1

1
另一个想法:while c not in s[:-1]:可能是while(c in s[:-1])-1:
PurkkaKoodari'1

1
还有一个。您不必使用j,因为此循环分配range(z)to 的内容,i而不是增加它的内容。只需替换ji以保存4个字符。
PurkkaKoodari'1

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

这会为每个起点生成一个无限列表(出于打高尔夫球的原因,我们迭代所有值而不是等效的所有索引)。然后计算每个列表的周期(周期长度xsxs % [])。

它使用@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

这利用了@jakube的观察,即您只需检查一半的起始值,而每次迭代执行2步。


您可以将压缩where到上一个]。另外,您是否尝试使用cycle l!!i代替l!!mod n(length l)
自豪的haskeller 2015年

另外,您可以内联b,并使用模式防护|n<-l a消除where
2015年

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 2015年

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}

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答案的一部分。


这看起来与我的非常相似。首先,我的是一分(在二分之前)。我仍然不确定为什么,但是我只是在相除之前减去了一个。
KSFT 2015年

我不了解Mathematica,所以我真的不能提供更多帮助。
KSFT 2015年

@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

第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-选择“游戏”)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.