Project Euler Problem 93 Statement
Solution
HackerRank version
Given a set of $m$ distinct digits, $S$, find the largest possible integer $n$ such that each integer from $1$ to $n$ is expressible using elements of $S$ and following the above rules. If $1$ is also not expressible, output $0$ instead.
Python Source Code
from functools import lru_cache
from itertools import combinations
from math import gcd
def simplify(n, d):
if d == 0:
return None # Avoid division by zero
g = gcd(abs(n), abs(d)) * (-1 if d < 0 else 1)
return n // g, d // g
def generate_rational(m, n):
results = set()
if m and n:
results.update({
simplify(m[0] * n[1] + n[0] * m[1], m[1] * n[1]),
simplify(m[0] * n[0], m[1] * n[1]),
simplify(m[0] * n[1], m[1] * n[0]),
simplify(n[0] * m[1], n[1] * m[0]),
simplify(m[0] * n[1] - n[0] * m[1], m[1] * n[1]),
simplify(n[0] * m[1] - m[0] * n[1], n[1] * m[1])
})
return {r for r in results if r}
def fold_digits(digits):
return sum(1 << d for d in digits)
@lru_cache(None)
def arithmetic_exp(bitmask):
digits = [i for i in range(10) if (bitmask >> i) & 1]
if len(digits) == 1:
return {simplify(digits[0], 1)}
result = set()
for i in range(1, len(digits)):
for sel in combinations(digits, i):
a = fold_digits(sel)
b = bitmask ^ a
for m in arithmetic_exp(a):
for n in arithmetic_exp(b):
result.update(generate_rational(m, n))
return result
def main():
n = int(input())
digits = list(map(int, input().split()))
bitmask = fold_digits(digits)
rationals = arithmetic_exp(bitmask)
numbers = {r[0] for r in rationals if r and r[1] == 1 and r[0] >= 0}
r = 0
while r + 1 in numbers:
r += 1
print(r)
if __name__ == "__main__":
main()