python/beltomatic.py
DomNomNomVR 028fb0bc3a dump
2025-04-14 15:58:38 +12:00

61 lines
1.5 KiB
Python

# from math import abs
from collections import defaultdict
max_num = 16
initial_nums = list(range(1, max_num + 1))
initial_nums.remove(10)
# end number -> list of steps to get here which are
# (prev_number, operation description)
target = 7387
upper_bound = target * max_num
ops = []
for n in initial_nums:
ops.append((lambda x, n=n: x + n, f"+{n}"))
ops.append((lambda x, n=n: abs(x - n), f"-{n}"))
ops.append((lambda x, n=n: x * n, f"*{n}"))
ops.append((lambda x, n=n: x // n if x and x % n == 0 else x, f"/{n}"))
ops.append((lambda x, n=n: x**n if x**2 < upper_bound else x, f"**{n}"))
seen = {n: [] for n in initial_nums}
recent = seen.keys()
while target not in seen:
news = defaultdict(list)
for n in recent:
for op, description in ops:
new = op(n)
if new > upper_bound:
continue
if new in seen:
continue
news[new].append((n, description))
seen.update(news)
recent = sorted(news.keys())
if not news:
assert False
print(f"progress: {len(seen)=}")
pickers = [
lambda l: l[0],
lambda l: l[len(l) // 2],
lambda l: l[-1],
]
for picker in pickers:
steps = [target]
picks = []
while prevs := seen[steps[-1]]:
pick = picker(prevs)
picks.append(pick)
steps.append(pick[0])
print(f"{steps[-1]:>3}", end=" ")
for pick in reversed(picks):
print(f"{pick[1]:>4}", end=" ")
print(f" = {target}")