<filename>2020/02/solution.py
from collections import Counter

with open("input.txt") as handle:
    lines = map(lambda s: s.strip(), handle.readlines())

    part1, part2 = 0, 0
    for line in lines:
        rng, char, password = line.split(" ")
        c = char[0]
        lower, upper = map(int, rng.split("-"))

        # I used the counter because I was anticipating that Part II would have
        # something to do with the count of some other letter in the password.
        # I was wrong, but don't see much point in changing this.
        counter = Counter(password)

        # Boolean values can be added to integers, so there's no need for an
        # if-statement.
        part1 += lower <= counter[c] and counter[c] <= upper


        # The `^` operator is XOR. In this case, it takes two boolean values
        # and gives back `True` if exactly one of the two arguments is `True`
        #
        # If you don't like bitwise operations, you could also use `!=`. Give
        # that a thought if it seems kind of weird.
        part2 += (password[lower - 1] == c) ^ (password[upper - 1] == c)

    print("Part I: ", part1)
    print("Part II:", part2)

<filename>2020/02/solution.py
from collections import Counter

with open("input.txt") as handle:
    lines = map(lambda s: s.strip(), handle.readlines())

    part1, part2 = 0, 0
    for line in lines:
        rng, char, password = line.split(" ")
        c = char[0]
        lower, upper = map(int, rng.split("-"))

        # I used the counter because I was anticipating that Part II would have
        # something to do with the count of some other letter in the password.
        # I was wrong, but don't see much point in changing this.
        counter = Counter(password)

        # Boolean values can be added to integers, so there's no need for an
        # if-statement.
        part1 += lower <= counter[c] and counter[c] <= upper


        # The `^` operator is XOR. In this case, it takes two boolean values
        # and gives back `True` if exactly one of the two arguments is `True`
        #
        # If you don't like bitwise operations, you could also use `!=`. Give
        # that a thought if it seems kind of weird.
        part2 += (password[lower - 1] == c) ^ (password[upper - 1] == c)

    print("Part I: ", part1)
    print("Part II:", part2)

# I used the counter because I was anticipating that Part II would have # something to do with the count of some other letter in the password. # I was wrong, but don't see much point in changing this. # Boolean values can be added to integers, so there's no need for an # if-statement. # The `^` operator is XOR. In this case, it takes two boolean values # and gives back `True` if exactly one of the two arguments is `True` # # If you don't like bitwise operations, you could also use `!=`. Give # that a thought if it seems kind of weird.