2020-12-02 - Password Philosophy
(original .ipynb)
Day 2 puzzle input is a list of password policy and password pairs (mine is here). Part 1 involves returning the number of passwords valid according to the policy (where x-y c: pass
means "between x
and y
occurrences of the character c
are in password pass
"). Part 2 is broadly similar, but with a with slightly different policy logic (x-y c: pass
means "either pass[x-1]==c
XOR pass[y-1]==c
")
def parse_line(line): policy, password = line.split(": ") minmax_letter, letter = policy.split(" ") min_letter_str, max_letter_str = minmax_letter.split("-") return (int(min_letter_str), int(max_letter_str), letter, password) def is_password_valid(min_letter, max_letter, letter, password): occurrences = len([ c for c in password if c == letter ]) return occurrences >= min_letter and occurrences <= max_letter test_input_str = """1-3 a: abcde 1-3 b: cdefg 2-9 c: ccccccccc""" real_input_str = open("puzzle_input/day2.txt").read() def count_valid_passwords(input_str): parsed_passwords = [ parse_line(l) for l in input_str.split("\n") ] password_validity = [ p for p in parsed_passwords if is_password_valid(*p) ] return len(password_validity) assert 2 == count_valid_passwords(test_input_str) count_valid_passwords(real_input_str)
620
def is_password_valid_new(position_one, position_two, letter, password): # 0-index the positions position_one -= 1 position_two -= 1 letter_one_match = password[position_one] == letter letter_two_match = password[position_two] == letter return (letter_one_match != letter_two_match) and (letter_one_match or letter_two_match) def count_valid_passwords_new(input_str): parsed_passwords = [ parse_line(l) for l in input_str.split("\n") ] password_validity = [ p for p in parsed_passwords if is_password_valid_new(*p) ] return len(password_validity) assert 1 == count_valid_passwords_new(test_input_str) count_valid_passwords_new(real_input_str)
727