advent-of-code/2021-python
Anders Ytterström 93c3322770 Solve 2021:14 "Extended Polymerization" part 2
Solved by total rewrite, since part 1 solution was too slow and was
killed by the OS. I tried to use deque and prepending instead of
appending, but no luck.

I looked for inspiration on AOC subreddit, and realized I could
solve the puzzle without constructing a new polymer string.

Instead, **it should be solved by counting pairs**.

First of all, a little zip trick is used to construct an initial list of
pairs from the initial polymer.

collections.defaultdicts are excellent tools for storing the counts,
since they will default to a value of 0 for any key that is added.

the initial count of the initial polymer is this:

    {
        ('N', 'N'): 1,
        ('N', 'C'): 1,
        ('C', 'B'): 1
    }

And the initial character count looks like this, and was constructed by
collections.Counter. This is what we increase and use after the 40 steps.

    {
        'N': 2,
        'C': 1,
        'B': 1
    }

So, lets see what happens after the first step.

First of all, all existing pair counts should be reset each step, since
this will be faster. nxt is used to store the next step pairs.

the current pairs are iterated.

 - for NN, the new pairs NC and CN are added for the next step. Since NN exists
   1 time, the pairs NC and CN also will exist exactly 1 more time each. The char C will also
     exist 1 more time, so add it to the char counter.
 - for NC, the new pairs NB and BC are added for the next step. Pair
   counter is once again synced with NC, and B is added to the char
counter.
 - and the same for CB, where CH and HB is added.

The count looks like this after step 1.

    {
        ('N', 'C'): 1,
        ('C', 'N'): 1,
        ('N', 'B'): 1,
        ('B', 'C'): 1,
        ('C', 'H'): 1,
        ('H', 'B'): 1,
    }

The pair counts are all 1 for step 2, since **no pairs have reoccured yet**.

The char counts looks like this, and matches polymer 'NCNBCHB', even
though it does not matter in which order the chars are written:

    {
        'N': 2,
        'C': 2,
        'B': 2,
        'H': 1
    }

Lets see the counts for step 2.

    {
        ('N', 'B'): 2,
        ('B', 'C'): 2,
        ('C', 'C'): 1,
        ('C', 'N'): 1,
        ('B', 'B'): 2,
        ('C', 'B'): 2,
        ('B', 'H'): 1,
        ('H', 'C'): 1
    }

Polymer NBCCNBBBCBHCB are present in the char count:

    {
        'N': 2,
        'C': 4,
        'B': 6,
        'H': 1
    }

Here some pairs have started to reoccour, and the char counts have
increased. So it will continue up to 40 steps, smooth and fast.

It works, since the char count are increased to match the polymer, and
it is fast, since the program does not care about the order of the
chars.
2021-12-14 08:56:57 +01:00
..
solutions Solve 2021:14 "Extended Polymerization" part 2 2021-12-14 08:56:57 +01:00
tests Solve 2021:14 "Extended Polymerization" part 1 2021-12-14 07:03:44 +01:00
.gitignore 🔧 Setup Advent of Code 2021 2021-10-22 17:17:55 +02:00
.python-version 🔧 Setup Advent of Code 2021 2021-10-22 17:17:55 +02:00
aoc.py 🔧 Setup Advent of Code 2021 2021-10-22 17:17:55 +02:00
README.md 🔧 Setup Advent of Code 2021 2021-10-22 17:17:55 +02:00

Advent of Code 2021

Solutions for #aoc2020 in Python 3 (3.8+).

Help scripts

Solve all puzzles:

python aoc.py

To bootstrap a new puzzle (creates inputs/<day_no>.txt, solutions/day_<day_no>.py och tests/test_day_<day_no>.py):

python aoc.py <dag_no> "<puzzle_name>"

Manually copy the puzzle input from https://adventofcode.com and paste it in inputs/<day_no>.txt to start coding.

Solve separate puzzle (replace XX with the puzzle number):

python -m solutions.day_XX

Run tests (replace XX with the puzzle number):

python -m unittest --locals -v
# or, if `pytest` is preferred:
pytest