Advent of Code 2020, day 2
Let’s go for Day 2! As before, all my solutions are available in a Git repository: https://git.sr.ht/~schnouki/advent-of-code.
Today’s puzzle is about password policies. Our input is made of line with a simple structure: we can parse them with a simple regular expression, and store the result in a dataclass. (We could also use a namedtuple or even a tuple, but using a class we can add methods and properties, which is often useful.)
from dataclasses import dataclass
import re
RE_LINE = re.compile(r"^(?P<v1>\d+)-(?P<v2>\d+) (?P<char>\w): (?P<password>.+)$")
@dataclass
class Password:
v1: int
v2: int
char: str
password: str
@classmethod
def from_line(cls, line: str) -> "Password":
mtch = RE_LINE.match(line)
return cls(
v1=int(mtch["v1"]),
v2=int(mtch["v2"]),
char=mtch["char"],
password=mtch["password"],
)
Now, let’s solve this puzzle.
Part 1
A password is valid if the character in the password policy is present the right number of times in the password. OK, not a good password policy for the real world, but enough for the North Pole 😅
It’s probable tempting to use a regular expression here… but it’s also not needed at all: we can just use the string count()
method and check if it’s in the right range.
Let’s add this as a property in our dataclass:
@dataclass
class Password:
...
@property
def is_valid_p1(self) -> bool:
return self.v1 <= self.password.count(self.char) <= self.v2
Now we just have to count how many times it’s valid for our input.
data = [Password.from_line(line) for line in data.splitlines()]
result = sum(1 for password in data if password.is_valid_p1)
Done. 0.25 ms.
Part 2
Different rule: this time we need to check if the character from the policy is present in only one of the 2 given positions. One, or the other, but not both: did someone say XOR?
@dataclass
class Password:
...
@property
def is_valid_p2(self) -> bool:
ok1 = self.password[self.v1 - 1] == self.char
ok2 = self.password[self.v2 - 1] == self.char
return ok1 ^ ok2
data = [Password.from_line(line) for line in data.splitlines()]
result = sum(1 for password in data if password.is_valid_p2)
Done as well. 0.23 ms.
That was easy. See you tomorrow! 👋
Comments
Join the conversation by sending an email. Your comment will be added here and to the public inbox after moderation.