Beispiel #1
0
def search(goal):
    """
    >>> search(6)
    13
    >>> search(7)
    56003
    """
    already_searched = set()
    for prime in primes():
        if prime in already_searched:
            continue
        positions_list = list(position_combinations(prime))
        for positions in positions_list:
            digits = list(digits_of(prime))
            family = set()
            for digit in range(10):
                if 0 in positions and digit == 0:
                    continue
                for pos in positions:
                    digits[pos] = digit
                number = from_digits(digits)
                if is_prime(number):
                    already_searched.add(number)
                    family.add(number)
            if len(family) >= goal:
                return min(family)
Beispiel #2
0
def cancel_unorthodox(numerator, denominator):
    """
    >>> cancel_unorthodox(49, 98)
    (4, 8)
    >>> cancel_unorthodox(499, 998)
    (4, 8)
    >>> cancel_unorthodox(11, 12)
    (1, 2)
    """
    n_digits = digits_of(numerator)
    d_digits = digits_of(denominator)
    matching_digits = [d for d in n_digits if d in d_digits]
    for m in matching_digits:
        if m in n_digits and m in d_digits:
            n_digits.remove(m)
            d_digits.remove(m)
    return from_digits(n_digits), from_digits(d_digits)
Beispiel #3
0
def is_palindromic(n):
    """
    >>> is_palindromic(121)
    True
    >>> is_palindromic(7337)
    True
    >>> any(is_palindromic(n) for n in [47, 349, 1292, 4213])
    False
    """
    digits = digits_of(n)
    return digits == list(reversed(digits))
Beispiel #4
0
def gen_numbers():
    factorials = dict((n, factorial(n)) for n in range(10))
    import itertools
    for num_digits in itertools.count(1):
        limit = num_digits * factorials[9]
        if limit < 10**num_digits:
            break
    #for n in range(10, limit + 1):
    for n in range(10, 50000): #HACK, there aren't any above 50000
        if n == sum(factorials[d] for d in digits_of(n)):
            yield n
Beispiel #5
0
def iter_counting_digits():
    """
    >>> from utility import nth
    >>> nth(12 - 1, iter_counting_digits())
    1
    >>> ''.join(str(d) for d in itertools.islice(iter_counting_digits(), 33))
    '123456789101112131415161718192021'
    """
    for i in itertools.count(1):
        for d in digits_of(i):
            yield d
Beispiel #6
0
def position_combinations(n):
    """
    >>> list(position_combinations(2))
    []
    >>> list(position_combinations(29))
    [(0,)]
    >>> list(position_combinations(293))
    [(0,), (1,), (0, 1)]
    """
    length = len(digits_of(n))
    return filter(None, powerset(range(length - 1)))
Beispiel #7
0
def reverse_and_add(n):
    """
    >>> reverse_and_add(47)
    121
    >>> reverse_and_add(349)
    1292
    >>> reverse_and_add(1292)
    4213
    >>> reverse_and_add(4213)
    7337
    """
    rev_n = from_digits(list(reversed(digits_of(n))))
    return n + rev_n
Beispiel #8
0
def cube_permutations(size):
    """
    >>> sorted(cube_permutations(3))
    [345, 384, 405]
    """
    cubes_by_digits = defaultdict(list)
    for i in itertools.count(1):
        cube = i**3
        digits = tuple(sorted(digits_of(cube)))
        cubes = cubes_by_digits[digits]
        cubes.append(i)
        if len(cubes) >= size:
            return set(cubes)
Beispiel #9
0
def truncatable_primes():
    seen_primes = set()
    one_digit_primes = (2, 3, 5, 7)
    for p in primes():
        seen_primes.add(p)
        digits = digits_of(p)
        # One-digit primes are not considered truncatable.
        if len(digits) == 1:
            continue
        # All digits besides the first must be odd.
        if not all(d % 2 == 1 for d in digits[1:]):
            continue
        # First and last digit must be prime.
        if digits[0] not in one_digit_primes or \
           digits[-1] not in one_digit_primes:
            continue
        # Test whether each truncation is a prime.
        truncs = sorted(list(from_digits(d) for d in truncations(digits)))
        if all(t in seen_primes for t in truncs):
            yield p
Beispiel #10
0
def sf(n):
    """
    >>> sf(342)
    5
    """
    return sum(digits_of(f(n)))
Beispiel #11
0
from utility import digits_of, isqrt

# The maximum value of a is 99, because 99 * 100 = 9900, is the largest
# almost-square product with 9 or fewer digits.
# Since order doesn't matter for products, we define b to be greater than a.
# The maximum value for b is 9999, because 1 * 9999 = 9999 is the product with
# the largest value of b having 9 or fewer digits.

all_digits = list(range(1, 9 + 1))
solutions = []
for a in range(1, 100):
    for b in range(a + 1, 10000):
        c = a * b
        digits = digits_of(a) + digits_of(b) + digits_of(c)
        if len(digits) < 9:
            continue
        if len(digits) > 9:
            break
        assert len(digits) == 9
        if sorted(digits) == all_digits:
            solutions.append(c)

print(sum(set(solutions)))
Beispiel #12
0
from utility import digits_of

print(max(sum(digits_of(a**b)) for a in range(1, 100) for b in range(1, 100)))
Beispiel #13
0
import itertools
from utility import digits_of, from_digits

target_digits = set(range(1, 10))
solutions = []
for limit in [2, 3, 4, 5]:
    for i in itertools.count(1):
        digits = []
        for m in range(1, limit + 1):
            digits.extend(digits_of(m * i))
        if 0 in digits:
            continue
        if len(digits) < 9:
            continue
        if len(digits) > 9:
            break
        if set(digits) == target_digits:
            solutions.append(from_digits(digits))

print(max(solutions))
Beispiel #14
0
from fractions import Fraction
import itertools
from utility import digits_of


def sqrt_two_frac_terms():
    frac = Fraction(0, 1)
    while True:
        frac = 1 / (2 + frac)
        yield 1 + frac


count = 0
for term in itertools.islice(sqrt_two_frac_terms(), 1000):
    if len(digits_of(term.numerator)) > len(digits_of(term.denominator)):
        count += 1
print(count)
Beispiel #15
0
import itertools
from utility import digits_of

limit = 6
for n in itertools.count(1):
    digits_n = sorted(digits_of(n))
    if all(sorted(digits_of(n * m)) == digits_n for m in range(2, limit + 1)):
        break
print(n)
Beispiel #16
0
    >>> cancel_unorthodox(499, 998)
    (4, 8)
    >>> cancel_unorthodox(11, 12)
    (1, 2)
    """
    n_digits = digits_of(numerator)
    d_digits = digits_of(denominator)
    matching_digits = [d for d in n_digits if d in d_digits]
    for m in matching_digits:
        if m in n_digits and m in d_digits:
            n_digits.remove(m)
            d_digits.remove(m)
    return from_digits(n_digits), from_digits(d_digits)

two_digit_nums = [i for i in range(10, 100)
                  if 0 not in digits_of(i)]
unorthodox_numbers = []
for n in two_digit_nums:
    for d in two_digit_nums:
        f = Fraction(n, d)
        if f >= 1:
            continue
        n2, d2 = cancel_unorthodox(n, d)
        if d2 == 0:
            continue
        if (n, d) == (n2, d2):
            continue
        f2 = Fraction(n2, d2)
        if f == f2:
            unorthodox_numbers.append(f2)
Beispiel #17
0
def digit_permutations(n):
    for digits in itertools.permutations(digits_of(n)):
        yield from_digits(digits)
Beispiel #18
0
def f(n):
    """
    >>> f(342)
    32
    """
    return sum(factorial(d) for d in digits_of(n))
Beispiel #19
0
def sg(i):
    """
    >>> sg(5)
    7
    """
    return sum(digits_of(g(i)))
Beispiel #20
0
                break

if __name__ == '__main__':
    # Generate all four digit primes.
    four_digit_primes = []
    for p in primes():
        if p < 1000:
            continue
        four_digit_primes.append(p)
        if p >= 10000:
            break

    # Group primes by similar digits.
    primes_by_digits = defaultdict(list)
    for p in four_digit_primes:
        primes_by_digits[frozenset(digits_of(p))].append(p)

    # Strip out digit groups with less than three primes.
    for digits, primes in list(primes_by_digits.items()):
        if len(primes) < 3:
            del primes_by_digits[digits]

    # Look for arithmetic sequences of length 3.
    solutions = []
    for primes in primes_by_digits.values():
        for sequence in find_arithmetic_sequences(primes, 3):
            digits = []
            for n in sequence:
                digits.extend(digits_of(n))
            solutions.append(from_digits(digits))
Beispiel #21
0
def is_connection(a, b):
    """
    >>> is_connection(1234, 3456)
    True
    """
    return (digits_of(a)[-2:] == digits_of(b)[:2])
Beispiel #22
0
from utility import primes, digits_of, up_to

# In order to maximize the totient, we need to look for "sharp" numbers, having
# few prime factors, with those factors being large.

limit = 10**7

solutions = []
seen_primes = []
for a in up_to(limit // 2, primes()):
    for b in seen_primes:
        n = a * b
        if n > limit:
            break
        t = n
        t -= t // a
        if a != b:
            t -= t // b
        if sorted(digits_of(n)) == sorted(digits_of(t)):
            solutions.append((n, n / t))
    seen_primes.append(a)

solutions.sort(key=lambda x: x[1])
print(min(solutions, key=lambda x: x[1])[0])