Solve problem 313

This commit is contained in:
2026-09-10 20:05:39 -04:00
parent f885638c74
commit b34c8f4f3b
+99
View File
@@ -0,0 +1,99 @@
from lib_prime import primes, is_prime
from dataclasses import dataclass
from heapq import heappop, heappush
from collections import namedtuple
from collections import defaultdict
from math import sqrt
P = namedtuple("P", ["x", "y"])
State = namedtuple("State", ["f", "g", "red", "space"])
@dataclass(order=True)
class State:
g: int
red: P
space: P
def s(m: int, n: int) -> int:
"""What am I doing? It was necessary to find the pattern."""
def h(s: State) -> int:
return abs(m - s.space.x) + abs(n - s.space.y)
def f(s: State) -> int:
return s.g + h(s)
def done(s: State) -> bool:
return s.red.x == m - 1 and s.red.y == n - 1
# assert m < n, then we could just take result times 2
init = State(0, P(0, 0), P(m - 1, n - 1))
states = [(0, init)]
g_costs = {(init.red, init.space): init.g}
while states:
_, s = heappop(states)
if done(s):
return s.g
for dx, dy in [(-1, 0), (0, 1), (1, 0), (0, -1)]:
nx, ny = s.space.x + dx, s.space.y + dy
if not (0 <= nx < m and 0 <= ny < n):
continue
nstate = State(s.g + 1, s.red, P(nx, ny))
if s.red.x == nx and s.red.y == ny:
nstate.red = P(s.space.x, s.space.y)
if (
not (nstate.red, nstate.space) in g_costs
or g_costs[(nstate.red, nstate.space)] > nstate.g
):
g_costs[nstate.red, nstate.space] = nstate.g
heappush(states, (f(nstate), nstate))
return -1
def solve_naiv(p_max: int) -> int:
t = 0
p2_max = p_max * p_max
ps = primes(p_max)
p2s = set([p * p for p in ps])
for m in range(2, p2_max):
for n in range(m, p2_max):
r = s(m, n)
if r in p2s:
t += 2
if r > p2_max:
break
return t
def solve(p_max: int) -> int:
t = 2
r_base = 0
delta = 1
three = 3
for p in range(3, p_max + 1, 2):
if is_prime(p):
t += r_base * 2
r_base += delta
three -= 1
if three == 0:
delta += 1
three = 3
return t
def euler_313():
assert solve_naiv(5) == 4
assert solve(20) == 86
assert solve(100) == 5482
return solve(10**6)
if __name__ == "__main__":
solution = euler_313()
print(f"e313.py: {solution}")
# assert solution == 2057774861813004