def product(numbers): r = 1 for n in numbers: r = r * n return r def _incrementer(): """ Generator function that returns natural numbers where the higher digits are smaller or equal than the lower digits. """ n_digits = 2 r = [1] * n_digits while True: yield r incremented = False for i in range(n_digits - 1): if r[i] < r[i + 1]: r[i] += 1 incremented = True for j in range(i): r[j] = 1 break if incremented: continue elif r[-1] < 2000: r[-1] += 1 for j in range(n_digits - 1): r[j] = 1 else: n_digits += 1 r = [1] * n_digits for k in range(40, 50): s = product_sum_number(k) print("k={}: {} = {}".format(k, product(s), s)) def product_sum(k): # Create initial list of canditates canditates = [] for n in range(2, k + 1): rest_sum = k - n if rest_sum + n * 2 < 2 ** n: break canditates.append(tuple([2 for _ in range(n)])) processed = set(canditates) solutions = [] while canditates: numbers = canditates.pop() processed.add(numbers) s = k - len(numbers) + sum(numbers) p = product(numbers) if s == p: solutions.append(numbers) elif s > p: for i in range(len(numbers) - 1): if numbers[i] < numbers[i + 1]: n = list(numbers) n[i] += 1 t = tuple(n) if not t in processed: canditates.append(t) n = list(numbers) n[-1] += 1 t = tuple(n) if not t in processed: canditates.append(t) else: pass result = min([product(ns) for ns in solutions]) return result def euler_088(): ns = set() for k in range(2, 12001): r = product_sum_2d(k) print("k={}: {}".format(k, r)) ns.add(r) return sum(ns) if __name__ == "__main__": solution = euler_088() print("e088.py: " + str(solution)) assert(solution == 7587457)