Advent of Code 2020 - Day 2

Good Morning AoC! Welcome to Day 2. If you don’t known what is AoC take a look on Day 1 post. So, continuing our journey to our vacation, we are about to leave North Pole (I really enjoy the story, though), but we can’t use the toboggan to get to the airport.

Day 2: Password Philosophy

https://adventofcode.com/2020/day/2

For the 2nd day, the two task are search in really big file, valid and invalid passwords. The rules for the first task is: “Each line gives the password policy and then the password. The password policy indicates the lowest and highest number of times a given letter must appear for the password to be valid. For example, 1-3 a means that the password must contain a at least 1 time and at most 3 times.” This a sample password file.

11-3 a: abcde
21-3 b: cdefg
32-9 c: ccccccccc
plain

Well, for this task, it is just a matter to count how many times the char occurs in the password and check if the count result is between the boundaries. Of course… for each line. Nothing that two repetition structures, substrings and some variables can do. But… with Python we can do better.

Data Preparation

First things first. There is a factory in the Python standard collection library called namedtuple. We can use it to create a Tuple subclass with our own fields.

1from collections import namedtuple
2Entry = namedtuple("Entry", "low high c pw")
python

Now, we can create objects with an easier way to reference its properties. We can access the low value using entry.low instead of entry.get('low'). We defined a new “type” (sic), now we have to create a new collection with the parsed data.

 1data = [
 2	Entry(
 3		int(x[0].split('-')[0]),  # low
 4		int(x[0].split('-')[1]),  # high
 5		x[1][0],                  # c
 6		x[2]                      # pw
 7	) 
 8	for x in [
 9		line.split() for line in downloaded.GetContentString().replace('\r', '').splitlines()
10	]
11]
python

Again, pythonic way #FTW. We can see I used Nested List Comprehensions to create the collection of Entry. Like day 1, using those List Comprehensions we write less code, use less memory and time. So, collection created, now we have to validate the passwords.

The strategy here is create a collection with only password that meets the password policy, and count how many objects this collection have. Again, a List Comprehension can handle this to create a collection.

1len([pwd for pwd in data if pwd.low <= pwd.pw.count(pwd.c) <= pwd.high])
python

Python standard library provides a lot of methods and tools to help us to create super optimized software. Like this case, the String class already have a count(char:str) implemented and the len function can also count how many elements a in collection. Know how to use this tricks helps you to create better products.

Task 1 done… gimme the ⭐

Task 2 - Tales of the XOR

The second task tell us that our password police is wrong. The correct policy is “Each policy actually describes two positions in the password, where 1 means the first character, 2 means the second character, and so on. Exactly one of these positions must contain the given letter. Other occurrences of the letter are irrelevant for the purposes of policy enforcement.”.

So… this is one of rare use of the XOR operator (^ in Python). Remembering the XOR truth table where the result is True only when one of parts is True and the another is False, it fits perfectly in our case here. Like task 1, a simple Conditional List Comprehension can solve this problem.

1len([pwd for pwd in data if (pwd.pw[pwd.low-1]==pwd.c) ^ (pwd.pw[pwd.high-1]==pwd.c)])
python

Task 2 done… gimme more ⭐

Comments