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)
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
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)
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)
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