Skip to main content

Advent of Code 2020 Day 2

Part 1

After a first day of manipulating numbers, Day 2 is all about manipulating caracters and strings. The problem’s context is about verifying that a password is compliant with some simple rules.

For example, let’s take a look at this input set:

1-3 a: abcde
1-3 b: cdefg
2-9 c: ccccccccc

The left-hand part of each line defines the password rule, the right-hand part is the actual password to test. And so, with the example set above, we have the following output:

1-3 a: abcde     # Password is valid
1-3 b: cdefg     # Password id invalid
2-9 c: ccccccccc # Password is valid

The objective of this first part is to determine how many passwords in your input data are valid. So, we are simply going to check if the password follows its rule, and increment a count variable if it’s actually the case.

A difficulty here might be to correctly parse the input data. Thankfully, they all have the same structure and it’s just a matter of taking things carefully. In the snippet below, I’m taking things really slowly to make sure that every step is clear.

line = "1-3 a: abcde"             # This is the first line of the example data set
left_part = line.split(": ")[0]   # left_part <- "1-3 a"
min_max = left_part.split(" ")[0] # min_max   <- "1-3"
min_value = int(min_max.split("-")[0])
max_value = int(min_max.split("-")[1])
letter = left_part[-1]            # The letter is always at the end of left_part
password = line.split(": ")[1]    # The password is always the right part of line

After that, it is just a matter of creating a count variable and checking if the password complies with the rule:

for line in lines:
    # Do the part above to appropriately parse the input line
    count = 0
    if min_value <= password.count(letter) <= max_value:
        count += 1

And that should be it for Part 1!

Part 2

The second part (as every second part) is a little trickier. We are told that the rules are not to be interpreted as we did in Part 1. Instead of representing the lowest and highest number of times a letter must appear in the password, these numbers now represent positions in the password. And so, a password is now considered valid if and only if the given letter is present in exactly one of the positions. To illustrate this new rule, let’s take a look at the example data:

1-3 a: abcde     # Valid because 'a' is in position 1 and not in position 3
1-3 b: cdefg     # Invalid because 'b' is not in position 1 nor in position 3
2-9 c: ccccccccc # Invalid because 'c' appears in both positions 1 and 3

The snippet written to parse the data is still valid. The names of the variables could change to be more closer to their actual use in the final solution, but that will do for me now). Solving this problem is, once again, a matter of correctly identifying the condition under which a password is valid. Written in pseudocode, it could be summarised with the following declaration:

password[min] == letter or password[max] == letter

But if that is the case, password[min] must be different from password[max]

We can thus write the following program to solve Part 2:

for line in lines:
    # Do the part to appropriately parse the input line
    count = 0
    if (password[min] == letter or password[max] == letter) and (password[min] != password[max]):
        count += 1

Concepts and difficulties

In Day 2, the difficulties are mainly concerned with parsing correctly the input data. Looking at the input data, we can quickly identify a structure (or a pattern) that is always present: we need to make use of this pattern when splitting each line.

Then, Day 2’s problem is mostly about writing up fairly simple conditions. So it’s a good way to practice that if you are still struggling with those.

comments powered by Disqus