zerosleeps

Since 2010

Advent of Code 2020 day 2

My Python solution for Advent of Code 2020 day 2. Taking the object-orientated path when I tackled part one didn’t really buy me much for part two, but I stand by my decision!

from pathlib import Path
import re
import unittest

def get_input():
    input_file = Path(__file__).parent / 'day_02_input.txt'

    with open(input_file) as file:
        return [line.strip() for line in file.readlines()]

class Password():
    def __init__(self, input):
        match = re.match('^(\d+)-(\d+) (\w): (\w+)$', input)
        self.min = int(match[1])
        self.max = int(match[2])
        self.letter = match[3]
        self.password = match[4]

    def valid_password(self):
        c = self.password.count(self.letter)
        if c >= self.min and c <= self.max:
            return True
        else:
            return False

    def new_valid_password(self):
        if (self.password[self.min - 1] == self.letter) ^ (self.password[self.max - 1] == self.letter):
            return True
        else:
            return False

class TestExamples(unittest.TestCase):
    def setUp(self):
        example_list = """1-3 a: abcde
                   1-3 b: cdefg
                   2-9 c: ccccccccc"""
        self.passwords = [Password(p.strip()) for p in example_list.splitlines()]

    def test_part_one(self):
        self.assertEqual(len([p for p in self.passwords if p.valid_password()]), 2)

    def test_part_two(self):
        self.assertEqual(len([p for p in self.passwords if p.new_valid_password()]), 1)

if __name__ == '__main__':
    passwords = [Password(p) for p in get_input()]
    print(f'Part one: {len([p for p in passwords if p.valid_password()])}')
    print(f'Part two: {len([p for p in passwords if p.new_valid_password()])}')