Compare commits
3 Commits
fd0cecbbbe
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| f0d81aba24 | |||
| 908cdb9a7e | |||
| 5c9e9d775f |
@@ -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
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
from math import floor
|
||||||
|
from time import time_ns
|
||||||
|
|
||||||
|
|
||||||
|
def d(_num: int, den: int, n: int) -> int:
|
||||||
|
""" (10^n // d) % 10 -> (10^n % 10*d) // d % 10 """
|
||||||
|
return pow(10, n, 10 * den) // den % 10
|
||||||
|
|
||||||
|
|
||||||
|
def d_naiv(num: int, den: int, n: int, debug: bool = False) -> int:
|
||||||
|
"""Return the nth digit of the factional part of num / den."""
|
||||||
|
if num == den:
|
||||||
|
if debug:
|
||||||
|
print("1.0")
|
||||||
|
return 0
|
||||||
|
assert num < den
|
||||||
|
if debug:
|
||||||
|
print("0.", end="")
|
||||||
|
|
||||||
|
x = None
|
||||||
|
r = 0
|
||||||
|
i = 0
|
||||||
|
num *= 10 # 0.
|
||||||
|
nums = {}
|
||||||
|
while i < n:
|
||||||
|
if num == 0:
|
||||||
|
r = 0
|
||||||
|
break
|
||||||
|
elif num < den:
|
||||||
|
r = 0
|
||||||
|
if debug:
|
||||||
|
print(0, end="")
|
||||||
|
else:
|
||||||
|
r = num // den
|
||||||
|
num %= den
|
||||||
|
if debug:
|
||||||
|
print(r, end="")
|
||||||
|
i += 1
|
||||||
|
if x is None:
|
||||||
|
if num in nums:
|
||||||
|
j = nums[num]
|
||||||
|
delta = i - j
|
||||||
|
x = floor((n - i) / delta)
|
||||||
|
if debug:
|
||||||
|
print("---")
|
||||||
|
print(f"{den=} {j} -> {i} (d={delta} mult={x})")
|
||||||
|
print(f"\n{j} -{delta} {x}> {i} ")
|
||||||
|
i += x * delta
|
||||||
|
else:
|
||||||
|
nums[num] = i
|
||||||
|
num *= 10
|
||||||
|
if debug:
|
||||||
|
print()
|
||||||
|
# dr = (10**n % (10*den)) // den
|
||||||
|
dr = pow(10, n, 10 * den) // den
|
||||||
|
assert r == dr
|
||||||
|
# print(f"k = {den} n= {n}")
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
def s(n: int) -> int:
|
||||||
|
return sum(d(1, k, n) for k in range(1, n + 1))
|
||||||
|
|
||||||
|
|
||||||
|
def euler_820():
|
||||||
|
d(1, 7, 10)
|
||||||
|
assert d(1, 2, 7) == 0
|
||||||
|
assert d(1, 3, 7) == 3
|
||||||
|
assert d(1, 5, 7) == 0
|
||||||
|
assert d(1, 6, 7) == 6
|
||||||
|
assert d(1, 7, 7) == 1
|
||||||
|
assert s(7) == 10
|
||||||
|
assert s(100) == 418
|
||||||
|
assert s(10000) == 43742
|
||||||
|
return s(10**7)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
solution = euler_820()
|
||||||
|
print(f"e820.py: {solution}")
|
||||||
|
assert solution == 44967734
|
||||||
@@ -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)
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ def euler_XXX():
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
solution = euler_XXX()
|
solution = euler_XXX()
|
||||||
print("eXXX.py: " + str(solution))
|
print(f"eXXX.py: {solution}")
|
||||||
# assert(solution == 0)
|
# assert(solution == 0)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -230,3 +230,18 @@ def cache(f):
|
|||||||
return r
|
return r
|
||||||
return func_cached
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user