Skip to content

Instantly share code, notes, and snippets.

@biancadanforth
Created August 14, 2025 15:16
Show Gist options
  • Save biancadanforth/297e77c481609227fd495c7712953a03 to your computer and use it in GitHub Desktop.
Save biancadanforth/297e77c481609227fd495c7712953a03 to your computer and use it in GitHub Desktop.
Advent of Code 2015 - Day 07 - Python
import os, re
# Based on AOC day 5
class PuzzleBase:
@classmethod
def parse_input(cls, puzzle_input):
lines = []
for line in puzzle_input.splitlines():
lines.append(line.strip())
return lines
@classmethod
def solve(cls, puzzle_input):
strings = cls.parse_input(puzzle_input)
num_nice_strings = 0
for string in strings:
if cls.is_a_nice_string(string):
num_nice_strings += 1
return num_nice_strings
@classmethod
def is_a_nice_string(cls, string):
raise NotImplementedError("You must override this method in subclasses")
class Part1(PuzzleBase):
@classmethod
def is_a_nice_string(cls, string):
# Process the input as a stream of characters
# Convert the chars to lower case just in case?
# First requirement:
# - For each char, increment a count for the number of vowels
# - If count < 3, return False
vowel_count = 0
for c in string:
if c in "aeiou":
vowel_count += 1
if vowel_count < 3:
return False
# Second requirement:
# - Break the string into a series of inclusive 2-tuples
# - For each 2-tuple, see if the tuple consists of two identical characters
# - If not, return False
has_double_char = False
prev_char = string[0]
for c in string[1:]:
if c == prev_char:
has_double_char = True
break
else:
prev_char = c
if not has_double_char:
return False
# Third requirement:
# - If any of ["ab", "cd", "pq", "xy"] are a substring, return False
substring_list = ["ab", "cd", "pq", "xy"]
contains_substrings = any(substring in string for substring in substring_list)
if contains_substrings:
return False
return True
class Part2(PuzzleBase):
@classmethod
def is_a_nice_string(cls, string):
first_regex = re.compile(r"([a-z][a-z]).*\1")
second_regex = re.compile(r"([a-z]).\1")
if not first_regex.search(string):
return False
if not second_regex.search(string):
return False
return True
# # Process the input as a stream of characters
# # First requirement:
# # - Break up the string into a list of 2-char substrings,
# # - As each pair is created, add it to a set
# # - If the set already has the substring, continue to the next requirement
# # - Else if we get to the end of the string, return False
# n = 2
# two_char_substring = [string[i:i+n] for i in range(0, len(string), n)]
# unique_pairs = set([])
# for pair in two_char_substring:
# print(pair)
# if pair in unique_pairs:
# print(f'Pair {pair} found in string')
# break
# else:
# unique_pairs.add(pair)
# if (len(two_char_substring) == len(unique_pairs)):
# return False
# print("passed first req")
# # Second requirement:
# # - For each char in the string, compare it to the penultimate char
# # - if it matches the penultimate char, requirement is satisfied
# meets_second_req = False
# penultimate_char = string[0]
# prev_char = string[1]
# for c in string[2:]:
# if c == penultimate_char:
# meets_second_req = True
# break
# else:
# penultimate_char = prev_char
# prev_char = c
# if not meets_second_req:
# return False
# return True
def main():
path = os.path.join(os.path.dirname(__file__), "input")
with open(path) as f:
puzzle_input = f.read()
print("Part 1:", Part1.solve(puzzle_input))
print("Part 2:", Part2.solve(puzzle_input))
# print("Part 1:", part1(puzzle_input)) # 238
# print("Part 2:", part2(puzzle_input))
if __name__ == '__main__':
main()
from day04 import part1
class TestPuzzle1(object):
def test_example_1(self):
input = "abcdef"
expected = 609043
assert part1(input) == expected
def test_example_2(self):
input = "pqrstuv"
expected = 1048970
assert part1(input) == expected
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment