John Lekberg


JUNTO Practice - "Project Euler Problem 44"

Discussed on 2018-11-28.

Project Euler Problem 44


Solution - John

import itertools


class Pentagonal:
    def __init__(self):
        self._generator = (
            n * (3 * n - 1) // 2 for n in itertools.count(1)
        )
        self._max = None
        self._seen = set()
        self._seen_ordered = list()

    def check_pentagonal(self, n):
        while self._max is None or self._max < n:
            item = next(self._generator)
            self._max = item
            self._seen.add(item)
            self._seen_ordered.append(item)

        return n in self._seen

    def get_pentagonal(self, n):
        while len(self._seen_ordered) < n:
            item = next(self._generator)
            self._max = item
            self._seen.add(item)
            self._seen_ordered.append(item)

        return self._seen_ordered[n - 1]


def candidate_indices():
    for i in itertools.count(1):
        for j in range(1, i):
            yield (i, j)


db = Pentagonal()

for (i, j) in candidate_indices():
    p_i = db.get_pentagonal(i)
    p_j = db.get_pentagonal(j)

    sum_pentagonal = db.check_pentagonal(p_i + p_j)
    diff_pentagonal = db.check_pentagonal(abs(p_i - p_j))

    if sum_pentagonal and diff_pentagonal:
        print(f"The answer is {abs(p_i - p_j)}")
        break

Solution - Oscar

#!/usr/bin/env python3

import itertools as it


class Pents:
    def __init__(self):
        self.new_set()

    def new_set(self):
        self.pset = self.gen_pents()

    def gen_pents(self):
        return map(self.pent, it.count(start=1))

    def pent(self, integer):
        return int((integer * (3 * integer - 1)) / 2)

    def is_pent(self, integer):
        self.new_set()
        for p in self.pset:
            if p > integer:
                return False
            elif p == integer:
                return True


def min_d():
    p_i = Pents()
    trail_p = []
    for i in p_i.pset:
        trail_p.append(i)
        # print(i)
        if len(trail_p) > 1:
            for j in range(len(trail_p) - 2, -1, -1):
                if (
                    (i - trail_p[j]) in trail_p
                ) and Pents().is_pent(i + trail_p[j]):
                    # print('Got it')
                    return (abs(i - trail_p[j]), i, trail_p[j])


d, _, _ = min_d()
print(d)