Sean McLemon | Advent of Code

Home | Czech | Blog | GitHub | Advent Of Code | Notes


2015-12-05 - Doesn't He Have Intern-Elves For This?

(original .ipynb)

Puzzle input is a bunch of newline separated strings. Part one involves finding how many of these fit three rules:

1) It contains at least three vowels (aeiou only), like aei, xazegov, or aeiouaeiouaeiou.

2) It contains at least one letter that appears twice in a row, like xx, abcdde (dd), or aabbccdd (aa, bb, cc, or dd).

3) It does not contain the strings ab, cd, pq, or xy, even if they are part of one of the other requirements.

Part two involves finding how many fit two different rules:

1) It contains a pair of any two letters that appears at least twice in the string without overlapping, like xyxy (xy) or aabcdefgaa (aa), but not like aaa (aa, but it overlaps).

2) It contains at least one letter which repeats with exactly one letter between them, like xyx, abcdefeghi (efe), or even aaa.

My solution is ugly and inefficient :)

puzzle_input_str = open("./puzzle_input/day5.txt").read()

vowels = {"a", "e", "i", "o", "u"}
forbidden_strings = ["ab", "cd", "pq", "xy"]


def three_vowels(string):
    string_vowels = [c for c in string if c in vowels]
    return len(string_vowels) >= 3


def one_letter_twice_row(string):
    prev_c = None
    for c in string:
        if c == prev_c:
            return True
        prev_c = c
    return False


def no_forbidden_strings(string):
    for fs in forbidden_strings:
        if fs in string:
            return False
    return True


def is_nice(string):
    return three_vowels(string) and one_letter_twice_row(string) and no_forbidden_strings(string)


def part_one(input_str):
    return len([string for string in input_str.split("\n") if is_nice(string)])


assert is_nice("ugknbfddgicrmopn")
assert is_nice("aaa")
assert not is_nice("jchzalrnumimnmhp")
assert not is_nice("haegwjzuvuyypxyu")
assert not is_nice("dvszwmarrgswjxmb")


print("part one:", part_one(puzzle_input_str))
part one: 258
def rule_one(string):
    for i, c in enumerate(string):
        if i+1 == len(string):
            return False
        if c+string[i+1] in string[i+2:]:
            return True
    return False


def rule_two(string):
    for i, c in enumerate(string):
        if i+2 == len(string):
            return False
        if c == string[i+2]:
            return True
    return False

def is_nice(string):
    return rule_one(string) and rule_two(string)


assert rule_one("xyxy")
assert rule_one("aabcdefgaa")
assert not rule_one("aaa")

assert rule_two("xyx")
assert rule_two("abcdefeghi")
assert rule_two("aaa")

assert is_nice("qjhvhtzxzqqjkmpb")
assert is_nice("xxyxx")
assert not is_nice("uurcxstgmygtbstg")
assert not is_nice("ieodomkazucvgmuy")


def part_two(input_str):
    return len([string for string in input_str.split("\n") if is_nice(string)])

print("part two:", part_two(puzzle_input_str))
part two: 53