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
すべてを数えるのに指数関数的な時間がかかり、計算にすでに〜8秒かかっているためn = 1..15
です。代わりに99を使用して1バイトを保存しても問題ないでしょう。これはもう必要ありませんが、組み込みの複素数のおかげで、任意の入力サイズに対して正しいことが保証されています。