Solution to problem 11 in Python
This commit is contained in:
parent
8104461429
commit
4c3960b56e
105
src/Year_2015/P11.py
Normal file
105
src/Year_2015/P11.py
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
# --- Day 11: Corporate Policy ---
|
||||||
|
|
||||||
|
# Santa's previous password expired, and he needs help choosing a new one.
|
||||||
|
|
||||||
|
# To help him remember his new password after the old one expires, Santa has
|
||||||
|
# devised a method of coming up with a password based on the previous one.
|
||||||
|
# Corporate policy dictates that passwords must be exactly eight lowercase
|
||||||
|
# letters (for security reasons), so he finds his new password by incrementing
|
||||||
|
# his old password string repeatedly until it is valid.
|
||||||
|
|
||||||
|
# Incrementing is just like counting with numbers: xx, xy, xz, ya, yb, and so
|
||||||
|
# on. Increase the rightmost letter one step; if it was z, it wraps around to
|
||||||
|
# a, and repeat with the next letter to the left until one doesn't wrap around.
|
||||||
|
|
||||||
|
# Unfortunately for Santa, a new Security-Elf recently started, and he has
|
||||||
|
# imposed some additional password requirements:
|
||||||
|
|
||||||
|
# Passwords must include one increasing straight of at least three letters,
|
||||||
|
# like abc, bcd, cde, and so on, up to xyz. They cannot skip letters; abd
|
||||||
|
# doesn't count.
|
||||||
|
# Passwords may not contain the letters i, o, or l, as these letters can be
|
||||||
|
# mistaken for other characters and are therefore confusing.
|
||||||
|
# Passwords must contain at least two different, non-overlapping pairs of
|
||||||
|
# letters, like aa, bb, or zz.
|
||||||
|
|
||||||
|
# For example:
|
||||||
|
|
||||||
|
# hijklmmn meets the first requirement (because it contains the straight
|
||||||
|
# hij) but fails the second requirement requirement (because it contains i and
|
||||||
|
# l).
|
||||||
|
# abbceffg meets the third requirement (because it repeats bb and ff) but
|
||||||
|
# fails the first requirement.
|
||||||
|
# abbcegjk fails the third requirement, because it only has one double
|
||||||
|
# letter (bb).
|
||||||
|
# The next password after abcdefgh is abcdffaa.
|
||||||
|
# The next password after ghijklmn is ghjaabcc, because you eventually skip
|
||||||
|
# all the passwords that start with ghi..., since i is not allowed.
|
||||||
|
|
||||||
|
# Given Santa's current password (your puzzle input), what should his next
|
||||||
|
# password be?
|
||||||
|
|
||||||
|
import re
|
||||||
|
from string import ascii_lowercase
|
||||||
|
|
||||||
|
with open("files/P11.txt", "r") as f:
|
||||||
|
password = [c for c in f.read().strip()]
|
||||||
|
|
||||||
|
forbidden_chars = {105, 108, 111}
|
||||||
|
|
||||||
|
|
||||||
|
def rule_1(chars: list[str]) -> bool:
|
||||||
|
# increasing straight of at least three letters
|
||||||
|
return any(
|
||||||
|
"".join(chars[i : i + 3]) in ascii_lowercase
|
||||||
|
for i in range(len(chars) - 2)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def rule_2(chars: list[str], pos: int) -> list[str]:
|
||||||
|
# not contain the letters i, o, or l
|
||||||
|
a = ord(chars[pos]) + 1
|
||||||
|
# rule # 2
|
||||||
|
if a in forbidden_chars:
|
||||||
|
a += 1
|
||||||
|
# wraps around to a
|
||||||
|
if a > 122:
|
||||||
|
a = 97
|
||||||
|
chars[pos] = chr(a)
|
||||||
|
rule_2(chars, pos - 1)
|
||||||
|
else:
|
||||||
|
chars[pos] = chr(a)
|
||||||
|
return chars
|
||||||
|
|
||||||
|
|
||||||
|
def rule_3(chars: list[str]) -> bool:
|
||||||
|
# at least two different, non-overlapping pairs of letters
|
||||||
|
return bool(re.search(r"(\w)\1.*(\w)\2", "".join(chars)))
|
||||||
|
|
||||||
|
|
||||||
|
def part_1() -> None:
|
||||||
|
new_password = password
|
||||||
|
found = False
|
||||||
|
while not found:
|
||||||
|
new_password = rule_2(new_password, -1)
|
||||||
|
# rule 1
|
||||||
|
if not rule_1(new_password):
|
||||||
|
continue
|
||||||
|
# rule # 3
|
||||||
|
if not rule_3(new_password):
|
||||||
|
continue
|
||||||
|
|
||||||
|
res = "".join(new_password)
|
||||||
|
print(f"Santa's next password is {res}")
|
||||||
|
found = True
|
||||||
|
|
||||||
|
|
||||||
|
# --- Part Two ---
|
||||||
|
|
||||||
|
# Santa's password expired again. What's the next one?
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
part_1()
|
||||||
|
# Same code again
|
||||||
|
part_1()
|
Loading…
x
Reference in New Issue
Block a user