これは、さまざまな戦略を使用します。ほとんどの戦略は特定の条件下でのみ適用されますが、常に使用できるフォールバック戦略が1つあります。最後に、最小の候補プログラムが選択されます。
from functools import reduce
from math import sqrt
symbols = " !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}"
def uncycle(arr):
for size in range(1, len(arr)):
if all(e == arr[i % size] for (i, e) in enumerate(arr)):
return arr[:size]
return arr
def constant(val):
return "A" if val == 10 else str(val)
def shift(val):
if not val: return ""
return constant(abs(val)) + "+-"[val < 0]
def encode(a, offsetMode):
result = "";
if offsetMode:
for i in range(len(a) - 1, 0, -1):
a[i] -= a[i - 1]
for i in range(len(a)):
parts = []
signBit = (a[i] < 0) * 2
continuing = (offsetMode and i == len(a) - 1) * 1
remain = abs(a[i])
while remain > 22:
parts.insert(0, remain % 46 * 2 + continuing);
remain //= 46
continuing = 1
parts.insert(0, remain * 4 + signBit + continuing)
result += "".join(symbols[p] for p in parts)
return result
def cram(arr):
flat = encode(arr, False)
offset = encode(arr, True)
return offset if len(offset) < len(flat) else flat;
def issquare(num):
root = int(sqrt(num))
return root * root == num
def isgeometric(arr):
r = arr[0]
return all(r ** (i + 1) == e for (i,e) in enumerate(arr))
def generateProgram(arr):
candidates = []
rotated = uncycle(arr)
rotated = rotated[-1:] + rotated[:-1]
deltas = [b - a for a,b in zip(arr, arr[1:])]
# single constant strategy
if len(arr) == 1:
candidates.append(constant(arr[0]))
# repeated constant
elif len(set(arr)) == 1:
num = arr[0]
if num == 10: candidates.append("A")
if num % 2 == 0: candidates.append(constant(num // 2) + "H")
if issquare(num): candidates.append(str(int(sqrt(num))) + "J")
candidates.append(constant(num - 1) + "^")
# repdigit
if len(arr) == 2 and 10 < arr[1] == arr[0] * 11 < 100:
candidates.append(str(arr[0]) + "p")
# single digits
if max(arr) < 10:
candidates.append("".join(map(str, rotated)) + "E|X@")
# max 10
if max(arr) == 10 and rotated[0] != 1:
candidates.append("".join(str(e - 1) for e in rotated) + "E|X@^")
fns = [
("", lambda x: x),
("H", lambda x: 2 * x),
("^", lambda x: x + 1),
("J", lambda x: x * x),
("Hv", lambda x: 2 * x - 1),
("H^", lambda x: 2 * x + 1),
("^H", lambda x: 2 * x + 2),
("HJ", lambda x: 4 * x * x),
("JH", lambda x: 2 * x * x),
(":T", lambda x: x * (x + 1) / 2),
("|F", lambda x: reduce(lambda a, b: a*b, range(1, x+1))),
("J^", lambda x: x * x + 1),
("^J", lambda x: x * x + 2 * x + 1),
]
for (stax, fn) in fns:
if all(fn(i + 1) == e for (i,e) in enumerate(arr)):
candidates.append("|X" + stax)
# fixed delta
if len(set(deltas)) == 1:
delta = deltas[0]
start = arr[0] - delta
if start == 0:
candidates.append(shift(delta))
if delta == 1:
candidates.append("|X" + shift(start))
elif delta == -1:
candidates.append("|x" + shift(start))
elif delta > 1:
candidates.append("|X" + constant(delta) + "*" + shift(start))
elif delta < -1:
candidates.append("|x" + constant(-delta) + "*" + shift(start))
# geometric series
if isgeometric(arr):
candidates.append(constant(arr[0]) + "*")
# prefix
if len(arr) == 2 and arr[1] // 10 == arr[0] < 10:
candidates.append("." + str(arr[1]) + "|X(")
# suffix
if len(arr) == 2 and arr[0] % 10 == arr[1] < 10:
candidates.append("." + "".join(map(str, arr)) + "|X)")
# uncycled cram
candidates.append('"' + cram(rotated) + '"!|X@')
candidates.sort(key=len)
return candidates[0]
while True:
arr = eval(input())
prog = generateProgram(arr)
print(prog)
オンラインでお試しください!
更新:検証 各プログラムの各多重度を個別に実行するには時間がかかります。それらをすべて同時に実行することが可能です。これを行うには、小さなコードを使用する必要があります。それはいくつかのことに責任があります。
もしあれば、暗黙の出力を行います。通常、staxプログラムの最後に、他に出力がなかった場合、スタックの先頭が出力されます。同じソースファイルで複数のプログラムを実行する場合、これは明示的に行う必要があります。
両方のスタックをクリアします。
レジスタをリセットします。これらのプログラムでは、xレジスタのみが使用されます。
このボイラープレートは、個々のプログラムを実行するたびに適用する必要があります。
|d{P}{zP}?0XLd
たとえば、入力[5,2,7,3]
はstaxプログラムを生成し3527E|X@
ます。4つの多重度すべてを一度にテストできます。
3527E|X@
|d{P}{zP}?0XLd
3527E|X@3527E|X@
|d{P}{zP}?0XLd
3527E|X@3527E|X@3527E|X@
|d{P}{zP}?0XLd
3527E|X@3527E|X@3527E|X@3527E|X@
|d{P}{zP}?0XLd
オンラインでお試しください!
このようにして、何も中断しないと仮定して、すべてのプログラムのすべての多重度を同じ実行でテストすることが可能です。これは、500をすべて実行した場合、おそらくこれまでに実行された最大のスタックスプログラムになるでしょう。