Compare commits

...

2 Commits

Author SHA1 Message Date
felixm 908cdb9a7e Solve problem 381 2026-06-18 15:42:03 -04:00
felixm 5c9e9d775f Solve problem 961 2026-06-17 14:39:33 -04:00
4 changed files with 108 additions and 1 deletions
+42
View File
@@ -0,0 +1,42 @@
from lib_prime import primes
from lib_misc import modinv
def s(p: int) -> int:
a = p - 1
fp = p - 1
r = fp
# Calculate (!(p - 1) + !(p - 2) + ... + !(p - 5)) % p
for _ in range(4):
fp = fp * modinv(a, p) % p
a -= 1
r += fp
r %= p
return r
def euler_381():
assert s(5) == 4
assert s(7) == 4
# Example given by problem statement
t = 0
for p in primes(100):
if p < 5:
continue
t += s(p)
assert t == 480
# Actual solution (#slow)
t = 0
for p in primes(10**8):
if p < 5:
continue
t += s(p)
return t
if __name__ == "__main__":
solution = euler_381()
print(f"e381.py: {solution}")
assert solution == 139602943319822
+50
View File
@@ -0,0 +1,50 @@
from functools import cache
@cache
def remove(n: str, pos: int) -> str:
assert pos < len(n)
r = n[:pos] + n[pos + 1:]
r = r.lstrip("0")
return r
@cache
def player_wins(n: str) -> bool:
if len(n) == 1:
return True
for i in range(len(n)):
if not player_wins(remove(n, i)):
return True
return False
def w(n: int) -> int:
r = 0
xs = [("", 0)]
for _ in range(n):
nxs = []
for x, x_count in xs:
nxs.append(("0" + x, x_count))
nx, nx_count = "x" + x, x_count + 1
if player_wins(nx):
r += (9 ** nx_count)
nxs.append((nx, nx_count))
xs = nxs
return r
def euler_961():
assert remove("105", 0) == "5"
assert remove("105", 1) == "15"
assert remove("105", 2) == "10"
assert remove("10005", 0) == "5"
assert w(2) == 18
assert w(4) == 1656
return w(18)
if __name__ == "__main__":
solution = euler_961()
print("e961.py: " + str(solution))
# assert(solution == 0)
+1 -1
View File
@@ -7,7 +7,7 @@ def euler_XXX():
if __name__ == "__main__":
solution = euler_XXX()
print("eXXX.py: " + str(solution))
print(f"eXXX.py: {solution}")
# assert(solution == 0)
"""
+15
View File
@@ -230,3 +230,18 @@ def cache(f):
return r
return func_cached
def ext_gcd(a: int, b: int) -> tuple[int, int, int]:
if a == 0:
return (b, 0, 1)
else:
gcd, x, y = ext_gcd(b % a, a)
return (gcd, y - (b // a) * x, x)
def modinv(a: int, b: int) -> int:
gcd, x, _ = ext_gcd(a, b)
if gcd != 1:
raise Exception('Modular inverse does not exist')
else:
return x % b