一元数有多强?


10

通常,您会得到一个由0到8组成的非进制(基数9)非负整数。但是,此数字中的位数(没有前导零)是一个完美的正方形。

因此,可以将数字排列在正方形网格中(仍保留读取顺序)。

1480(1125以10为基)的示例:

14
80

现在,让这样的一元网格中的每个数字指示运动到另一个网格空间(具有周期性边界条件):

432
501
678

就是说

0 = stay still
1 = move right
2 = move right and up
3 = move up
...
8 = move right and down

因此,如果在1480网格中从4开始,然后向上移动(记住pbc)并向左移动到8,这意味着您将向右和向下移动回到4,从周期2开始一个循环。

通常,此过程一直持续到您达到0或注意到一个循环为止。(0被认为是周期为1的周期。)

在1480的情况下,最终到达4个起始数字中的每个数字的时间段2 2 2 1分别是。

对于更大的网格,这些数字可能大于8,但是我们仍然可以将它们用作新的非二进制数字中的“数字”(简单地将9 ^ n的系数视为数字):

2*9^3 + 2*9^2 + 2*9 + 1 = 1639 (base 10) = 2221 (base 9)

我们将其称为原始一元数的强度。因此1480的强度为1639(以10为基数)或2221(以9为基数)。

挑战

编写最短的程序,告诉一个非整数的强度是大于,小于还是等于非整数本身。(您不一定需要计算强度。)

输入将是一个非负一元数字,该数字包含一个平方的数字(除了0本身的特殊情况外,没有前导零)。它应该来自命令行或标准输入。

输出应以以下方式进入标准输出:

G if the strength is larger than the original number (example: 1480 -> strength = 2221)
E if the strength is equal to the original number (example: 1 -> strength = 1)
L if the strength is less than the original number (example: 5 -> strength = 1)

有趣的奖金挑战:
您能找到的最高输入等于其强度?(有限制吗?)


至于输入,它是以十进制数字形式给出的,其位数与非进制数字相同还是以非进制数字的十进制(或二进制)表示?即:对于1480(非),输入是1480还是1125?
overactor 2014年

@overactor以非二进制格式。

2
我非常有信心,没有人会找到比其强度高的输入,而不是10 ^ 71-1(non),即64位数字,只包含8个数字
演员

@overactor我认为周期大于8的周期可能是可能的。
马丁·恩德

如果您发现其中任何一个,@MartinBüttner都会给我留下深刻的印象。
演员

Answers:


2

Python 2中,213 209 202

编辑:消除了短路,这有时是不正确的。见下文。

(大)算法与@KSab相同,但是打的很重。

n=`input()`
s=int(len(n)**.5)
c=0
for i in range(s*s):
 a=[]
 while(i in a)<1:a+=[i];x='432501678'.find(n[i]);i=(i+x%3-1)%s+((i/s+x/3-1)%s)*s
 c=c*9+len(a)-a.index(i)
d=long(n,9)
print'EGL'[(c>d)-(c<d)]

高尔夫:

  • 213:短路,有缺陷的解决方案。

  • 209:第一个可行的解决方案。

  • 202:将两个字符串查找合并为一个。

编辑:我只是意识到该程序以及KSab的缺陷在于它们忽略了多位数的循环长度。失败示例:

3117
2755
3117
7455

尽管3的循环长度为2,因此上述算法将短路至“ L”,但实际上应该返回“ G”,因为第二个数字上的14的循环长度可以克服该问题。因此,我更改了程序。它也变得更短,更有趣。要测试您的程序,请使用3117275531177455。它应该返回G


哇,我以为我打得不错,但是你在那里做了一些非常聪明的事情。
KSab 2014年

@KSab谢谢-您的算法一开始很聪明-我找不到更好的方法。
isaacg 2014年

2

Python 296

实际上效率不是很高,它只检查所需位数。

n=raw_input();s=int(len(n)**.5);t=0
for i in range(s**2):
    l=[]
    while i not in l:l.append(i);c=n[i];i=(i%s+(-1 if c in'456'else 1 if c in'218'else 0))%s+((i/s+(-1 if c in'432'else 1 if c in'678'else 0))%s)*s
    t=t*9+len(l)-l.index(i)
print'EGL'[cmp(t,long(n,9))]

对于等于其强度的数字,我认为唯一的解决方案是,对于每个N x N平方,直到N = 8,每个空间中都包含N的平方。我的想法是,由于循环中的每个数字都必须是相同的数字(循环的长度),因此每个循环都必须全都在一个方向上。当然,这意味着循环的大小必须为N(每个元素必须为N)。我很确定该逻辑可以应用于任何大小的正方形和环形,这意味着除了第一个8之外,没有其他正方形等于其强度。


虽然不太可能,它可能比8大循环是可能的
overactor

2
我认为这会在上产生错误的结果3117275531177455,因为循环大小大于8。请参阅我的文章。
isaacg 2014年

1
@isaacg哦,我没有看到,我对其进行了更改以使其正常运行,但我不会尝试进一步进行打高尔夫球,因为那几乎只能是复制粘贴您的答案。哦,我认为您可以使用来改善最后两行cmp
KSab 2014年


0

Lua-尚未打高尔夫球

只是放在这里保管。我将对其进行打高尔夫球(并实现“对于更大的网格,这些数字可能大于8,但我们仍然可以将其用作”数字””)。虽然有效。

d={{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}}
d[0]={0,0}ssd=''
n=arg[1]
q=math.sqrt(#n)t={}

    for y=1,q do
    table.insert(t,y,{})
    for x =1,q do
        v=(y-1)*q+x
        table.insert(t[y],x,n:sub(v,v)+0)
        io.write(t[y][x])
    end
end
for y=1,q do
    for x=1,q do
        cx=x cy=y pxy=''sd=0
        while pxy:match(cx..':%d*:'..cy..' ')==nil do
            pxy=pxy..cx..':'..sd..':'..cy.." "
            ccx=cx+d[t[cx][cy]][2]
            ccy=cy+d[t[cx][cy]][1]
            cx=ccx cy=ccy
            if cx<1 then cx=q elseif cx>q then cx=1 end
            if cy<1 then cy=q elseif cy>q then cy=1 end
            sd=sd+1
        end
        dds=(pxy:sub(pxy:find(cx..':%d+:'..cy)):match(':%d*'))
        ssd=ssd..(sd-dds:sub(2))
    end
end
print(ssd)
nn=tonumber(n,9) tn=tonumber(ssd,9)
if tn>nn then print("G") elseif tn==nn then print("E") else print("L") end
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.