mirror of
https://github.com/thib8956/advent-of-code.git
synced 2026-05-25 19:53:26 +00:00
79 lines
2.3 KiB
Python
79 lines
2.3 KiB
Python
#!/usr/bin/env python3
|
|
from itertools import islice
|
|
|
|
VOWELS = "aeiou"
|
|
BAD = ["ab", "cd", "pq", "xy"]
|
|
|
|
|
|
def window(seq, n=3):
|
|
"Returns a sliding window (of width n) over data from the iterable"
|
|
" s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ... "
|
|
it = iter(seq)
|
|
result = tuple(islice(it, n))
|
|
if len(result) == n:
|
|
yield result
|
|
for elem in it:
|
|
result = result[1:] + (elem,)
|
|
yield result
|
|
|
|
|
|
def part1(inp):
|
|
total = 0
|
|
for line in inp:
|
|
"""
|
|
- It contains at least three vowels (aeiou only), like aei, xazegov, or
|
|
aeiouaeiouaeiou.
|
|
- It contains at least one letter that appears twice in a row, like xx,
|
|
abcdde (dd), or aabbccdd (aa, bb, cc, or dd).
|
|
- It does not contain the strings ab, cd, pq, or xy, even if they are
|
|
part of one of the other requirements.
|
|
"""
|
|
if any(x in line for x in BAD) or sum(1 for x in line if x in VOWELS) < 3:
|
|
continue
|
|
total += any(a == b for a, b in zip(line, line[1:]))
|
|
print("Part 1: ", total)
|
|
|
|
|
|
def part2(inp):
|
|
"""
|
|
- 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).
|
|
- It contains at least one letter which repeats with exactly one letter
|
|
between them, like xyx, abcdefeghi (efe), or even aaa.
|
|
"""
|
|
total = 0
|
|
for line in inp:
|
|
has_repeat = False
|
|
for triplet in window(line, n=3):
|
|
if triplet[0] == triplet[2]:
|
|
has_repeat = True
|
|
break
|
|
|
|
seen_pairs = set()
|
|
has_pair = False
|
|
prev_pair = None
|
|
for pair in window(line, n=2):
|
|
if pair in seen_pairs:
|
|
has_pair = True
|
|
else:
|
|
# Add the previous pair to avoid overlapping
|
|
if prev_pair is not None:
|
|
seen_pairs.add(prev_pair)
|
|
prev_pair = pair
|
|
if has_pair and has_repeat:
|
|
break # Early exit when both conditions are met
|
|
|
|
if has_pair and has_repeat:
|
|
total += 1
|
|
|
|
print("Part 2: ", total)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import fileinput
|
|
|
|
lines = [x.rstrip() for x in fileinput.input()]
|
|
part1(lines)
|
|
part2(lines)
|