Example #1
0
def _remove_invalid_sums(cells, sum_val, i):
    """Removes any possibilities which have become impossible due to changes in
  other cells.

  Example:
    sum_val = 12
    [<789>, <345789>] -> [<789>, <345>]
  """

    sets = [cell.set for cell in cells]

    # The big list comprehension below is a very expensive computation when
    # there are lots of possibilities for the given set of cells. The cost is
    # something like n_0 * n_1 * n_2 ... where n_0 is the number of
    # possibilities in cell 0, and so on. This block calculates that sum and
    # aborts on sets of cells with big sums when i is small. As i increases,
    # larger checks are allowed. It saves a lot of wasted compute time for most
    # puzzles.
    size = product(len(s) for s in sets)
    if not 1 < size < 1.7**i + 500:
        return

    # The reduction work is done in this block. This is an expensive line!
    new_sets = izip(*(seq for seq in i_product(*sets)
                      if sum(seq) == sum_val and len(seq) == len(set(seq))))
    for old, new in izip(cells, new_sets):
        old.set = set(new)
Example #2
0
def main(verbose=False):
    prime_factors_hash = {}

    MINIMUM_SOLUTIONS = 4*(10**6)
    # P^k < 10**7 (10 mil)
    powers = [power_up_to_digits(prime, 7)
              for prime in [3, 5, 7]]
    products = [reduce(operator.mul, triple) for
                triple in list(i_product(*powers))]
    products = [product for product in sorted(products)
                if product > 2*MINIMUM_SOLUTIONS][:20]

    PRIMES = sieve(100)

    max_prod = 10**21
    res = []
    for product in products:
        factors = prime_factors(product, unique=False, hash_=prime_factors_hash)
        factors = [(factor - 1)/2 for factor in factors][::-1]
        curr_prod = 1
        for i, exp in enumerate(factors):
            curr_prod = curr_prod*(PRIMES[i]**exp)

        if curr_prod < max_prod:
            max_prod = curr_prod

    return max_prod
Example #3
0
def main(verbose=False):
    product = 13082761331670030
    factors = prime_factors(product)

    candidate_lists = []
    for factor in factors:
        candidate_lists.append([(factor, root)
                                for root in find_cube_roots(factor)])

    result = list(i_product(*candidate_lists))

    coprime_units = {}
    for factor in factors:
        _, multiplier = extended_euclid(factor, product / factor)
        coprime_units[factor] = multiplier * (product / factor)

    vals = []
    for pairing in result:
        count = 0
        for prime, residue in pairing:
            count += residue * coprime_units[prime]
        count = count % product
        vals.append(count)

    return sum(vals) - 1  # 1 is in there as (1,1,...,1)
Example #4
0
def _remove_invalid_sums(cells, sum_val, i):
  """Removes any possibilities which have become impossible due to changes in
  other cells.

  Example:
    sum_val = 12
    [<789>, <345789>] -> [<789>, <345>]
  """

  sets = [cell.set for cell in cells]

  # The big list comprehension below is a very expensive computation when
  # there are lots of possibilities for the given set of cells. The cost is
  # something like n_0 * n_1 * n_2 ... where n_0 is the number of
  # possibilities in cell 0, and so on. This block calculates that sum and
  # aborts on sets of cells with big sums when i is small. As i increases,
  # larger checks are allowed. It saves a lot of wasted compute time for most
  # puzzles.
  size = product(len(s) for s in sets)
  if not 1 < size < 1.7**i+500:
    return

  # The reduction work is done in this block. This is an expensive line!
  new_sets = izip(*(seq for seq in i_product(*sets)
                   if sum(seq)==sum_val and len(seq) == len(set(seq))))
  for old, new in izip(cells, new_sets):
    old.set = set(new)
Example #5
0
def main(verbose=False):
    MAX_DIGITS = 12
    candidate_lists = [['0', '1', '2']]*MAX_DIGITS

    values = list(i_product(*candidate_lists))
    values = [int(''.join(value)) for value in values][1:]

    running_sum = 0
    for n in range(1, 10000 + 1):
        running_sum += find(n, values)/n
    return running_sum