Advent of code 2021

It's time again for Google Advent of Code 2021. This year I will try to do as many of the exercises as is possible but the focus will be different. Instead of pushing myself to get to the solution, which often meant sub-optimal code,  I will instead try to learn the patterns beneath each exercises, in effect the general class of software problem that is being solved.

Inspiration

I found Peter Norvig's solutions to the Advent of Code 2021 to be very elegant. So for 2021 I will use his pytudes as a base for developing the solutions. Norvig pytudes are basically a collection of terse functions that can be combined to solve each problem, many of which involve finding the first of something or to quantify something.


def quantify(iterable, pred=bool) -> int:
    "Count the number of items in iterable for which pred is true."
    return sum(1 for item in iterable if pred(item))
    
def first(iterable, default=None) -> object:
    "Return first item in iterable, or default."
    return next(iter(iterable), default)


def prod(numbers) -> Number:
    "The product of an iterable of numbers."
    return reduce(operator.mul, numbers, 1)


def dot(A, B) -> Number:
    "The dot product of two vectors of numbers."
    return sum(a * b for a, b in zip(A, B))


def ints(text: str) -> Tuple[int]:
    "Return a tuple of all the integers in text."
    return mapt(int, re.findall('-?[0-9]+', text))


def lines(text: str) -> List[str]:
    "Split the text into a list of lines."
    return text.strip().splitlines()


def mapt(fn, *args):
    "Do map(fn, *args) and make the result a tuple."
    return tuple(map(fn, *args))


def atoms(text: str, ignore=r'', sep=None) -> Tuple[Union[int, str]]:
    "Parse text into atoms separated by sep, with regex ignored."
    text = re.sub(ignore, '', text)
    return mapt(atom, text.split(sep))


def atom(text: str, types=(int, str)):
    "Parse text into one of the given types."
    for typ in types:
        try:
            return typ(text)
        except ValueError:
            pass
Peter Norvig's Advent Pytudes

Day 1

Now that we have the basis functions Day 1 was easy to solve.

def day1_1(nums):
    """How many measurements are larger than the previous measurement?"""
    return quantify(map(lambda i: nums[i] > nums[i - 1],
                        range(1, len(nums))
                        )
                    )


def day1_2(nums):
    "How many sliding window sums are greater than the previous"
    return quantify(map(lambda i:
                        sum(nums[i - 3:i]) > sum(nums[i - 4: i - 1]),
                        range(4, len(nums) + 1)
                        )
                    )
Dwight Gunning

Dwight Gunning