Solution to problem 11 in Python

This commit is contained in:
David Doblas Jiménez 2022-06-13 21:04:02 +02:00
parent 8104461429
commit 4c3960b56e

105
src/Year_2015/P11.py Normal file
View 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()