Solution to problem 5 in Python
This commit is contained in:
parent
5bb0f51743
commit
e467b686d7
123
src/Year_2015/P5.py
Normal file
123
src/Year_2015/P5.py
Normal file
@ -0,0 +1,123 @@
|
||||
# --- Day 5: Doesn't He Have Intern-Elves For This? ---
|
||||
|
||||
# Santa needs help figuring out which strings in his text file are naughty or
|
||||
# nice.
|
||||
|
||||
# A nice string is one with all of the following properties:
|
||||
|
||||
# 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.
|
||||
|
||||
# For example:
|
||||
|
||||
# ugknbfddgicrmopn is nice because it has at least three vowels
|
||||
# (u...i...o...), a double letter (...dd...), and none of the disallowed
|
||||
# substrings.
|
||||
# aaa is nice because it has at least three vowels and a double letter,
|
||||
# even though the letters used by different rules overlap.
|
||||
# jchzalrnumimnmhp is naughty because it has no double letter.
|
||||
# haegwjzuvuyypxyu is naughty because it contains the string xy.
|
||||
# dvszwmarrgswjxmb is naughty because it contains only one vowel.
|
||||
|
||||
# How many strings are nice?
|
||||
|
||||
from collections import Counter
|
||||
|
||||
with open("files/P5.txt") as f:
|
||||
strings = [line for line in f.read().strip().split()]
|
||||
|
||||
|
||||
def has_enough_vowels(s: str) -> bool:
|
||||
num_vowels = sum(s.lower().count(v) for v in "aeiou")
|
||||
if num_vowels >= 3:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def has_double_letter(s: str) -> bool:
|
||||
double_letters = sum(1 for i, j in zip(s, s[1:]) if i == j)
|
||||
if double_letters >= 1:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def has_substring(s: str) -> bool:
|
||||
substrings = ["ab", "cd", "pq", "xy"]
|
||||
for substring in substrings:
|
||||
if substring in s:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def part_1() -> None:
|
||||
nice = 0
|
||||
for string in strings:
|
||||
if (
|
||||
has_enough_vowels(string)
|
||||
and has_double_letter(string)
|
||||
and not has_substring(string)
|
||||
):
|
||||
nice += 1
|
||||
|
||||
print(f"There are {nice} nice strings")
|
||||
|
||||
|
||||
# --- Part Two ---
|
||||
|
||||
# Realizing the error of his ways, Santa has switched to a better model of
|
||||
# determining whether a string is naughty or nice. None of the old rules apply,
|
||||
# as they are all clearly ridiculous.
|
||||
|
||||
# Now, a nice string is one with all of the following properties:
|
||||
|
||||
# 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.
|
||||
|
||||
# For example:
|
||||
|
||||
# qjhvhtzxzqqjkmpb is nice because is has a pair that appears twice (qj)
|
||||
# and a letter that repeats with exactly one letter between them (zxz).
|
||||
# xxyxx is nice because it has a pair that appears twice and a letter that
|
||||
# repeats with one between, even though the letters used by each rule overlap.
|
||||
# uurcxstgmygtbstg is naughty because it has a pair (tg) but no repeat with
|
||||
# a single letter between them.
|
||||
# ieodomkazucvgmuy is naughty because it has a repeating letter with one
|
||||
# between (odo), but no pair that appears twice.
|
||||
|
||||
# How many strings are nice under these new rules?
|
||||
|
||||
|
||||
def has_pairs(s: str) -> bool:
|
||||
for i in range(len(s) - 3):
|
||||
_str = s[i : i + 2]
|
||||
if _str in s[i + 2 :]:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def has_letter_between(s: str) -> bool:
|
||||
_my_str = zip(s, s[1:], s[2:])
|
||||
for triple in _my_str:
|
||||
if triple[0] == triple[-1]:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def part_2() -> None:
|
||||
nice = 0
|
||||
for string in strings:
|
||||
if has_pairs(string) and has_letter_between(string):
|
||||
nice += 1
|
||||
print(f"There are {nice} nicer strings")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part_1()
|
||||
part_2()
|
Loading…
Reference in New Issue
Block a user