Python 3中,480个 433 406 364 309 299 295字节
看起来是开始我的PPCG事业的好时机(或没有?)。
def C(s):
S,*a={''},0,1;n=d=r=1
for c in s:d=c*d*1jor d;n+=d;a+=n,;r*=not{n}&S;x,*a=a;S|={x+t+u*1jfor t in A for u in A}
return r
from itertools import*;A=-1,0,1;n,y=int(input())-2,0;x={*filter(C,product(*[A]*n))}
while x:s=x.pop();S=*(-u for u in s),;x-={s[::-1],S,S[::-1]}-{s};y+=1
print(y)
在线尝试!
编辑:
- 内联
D
和X
,并在一些高尔夫球场上进行了一些调整。
- 应用更多的技巧,主要是与集合相关的技巧。
- 更改为程序形式,并更改为使用复数而不是任意数
m
。(复数确实是一个强大的功能,但经常被忽略,它是根据xnor的解决方案改编而成的,以应对另一个挑战)
- 将
LFR
字符串表示形式更改为-1,0,1
元组,并牺牲了执行时间以减少疯狂的字节减少量(!)。现在从理论上讲解决方案是正确的,但是在输出结果15之前会超时。
- 多亏了乔纳森·弗雷奇(Jonathan Frech),单行循环了,然后我找到了更好的计算方法
r
。最终不到300个字节!!!
- 令人惊讶的是,它
1j
可以坚持使用其他任何东西而不会混淆解析器(-2B),并且not
具有极低的优先级(-2B)。
过时的版本(480字节):
def C(s):
m=999;a=[0,1];n=d=1
D={'F':{},'L':{1:m,m:-1,-1:-m,-m:1},'R':{1:-m,-m:-1,-1:m,m:1}}
X=lambda x:{x+~m,x-m,x-m+1,x-1,x,x+1,x+m-1,x+m,x-~m}
for c in s:
d=D[c].get(d,d);n+=d;a+=n,
if n in set().union(*map(X,a[:-3])):return 0
return 1
def f(n):
if n<3:return 1
x={*'LF'}
for _ in range(3,n):x={s+c for s in x for c in({*'LRF'}-{s[-1]})|{'F'}}
y={*x}
for s in x:
if s in y:S=s.translate(str.maketrans('LR','RL'));y-={s[::-1],S,S[::-1]}-{s}
return sum(map(C,y))
在线尝试!
带有注释的非解决方案:
t = str.maketrans('LR','RL')
# hole checking function
def check(s):
m = 999 # (imaginary) board size enough to fit all generated polyominoes
a = [0,1] # previous path
n = 1 # current cell
d = 1 # current direction
# dict for direction change
D = {'F':{}, 'L':{1:m, m:-1, -1:-m, -m:1}, 'R':{1:-m, -m:-1, -1:m, m:1}}
# used to 'blur' all cells in path into 3x3
X = lambda x: {x-m-1,x-m,x-m+1,x-1,x,x+1,x+m-1,x+m,x+m+1}
for c in s:
d = D[c].get(d,d) # change direction
n += d # move current cell
# the polyomino has a hole if the current cell touches previous cells (including diagonally; thus the blurring function)
if n in set().union(*map(X,a[:-2])): return False
a.append(n) # add current cell to the path
return True
# main function
def f(n):
if n < 3: return 1
x = {*'LF'}
# generate all polystrips using the notation similar to the reference
for _ in range(3, n): x = {s+c for s in x for c in ({*'LRF'}-{s[-1]})|{'F'}}
y = {*x}
# remove duplicates (mirror, head-to-tail, mirror of head-to-tail) but retain self
for s in x:
if s in y:
S = s.translate(t)
y -= {s[::-1], S, S[::-1]} - {s}
# finally filter out holey ones
return sum(map(check,y))
在线尝试!
m = 999
之所以选择,是因为它花费了所有时间的指数时间,并且已经花费了大约8s的时间进行计算n = 1..15
。也许可以使用99代替保存1个字节。我们不再需要它了,由于内置了复杂的数字,现在可以保证它对于任意输入大小都是正确的。