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