From bf4373ced86010452a5c87f2aea9ec7d1ccd53cf Mon Sep 17 00:00:00 2001 From: daviddoji Date: Tue, 1 Mar 2022 10:46:32 +0100 Subject: [PATCH] Solution to problem 5 in Python --- src/Year_2016/P5.py | 58 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/Year_2016/P5.py b/src/Year_2016/P5.py index ecaf05b..46f7417 100644 --- a/src/Year_2016/P5.py +++ b/src/Year_2016/P5.py @@ -30,7 +30,9 @@ # Your puzzle input is abbhdwsy. +from collections import defaultdict from hashlib import md5 +from typing import DefaultDict _input = "abbhdwsy" @@ -48,5 +50,61 @@ def part_1() -> None: break +# --- Part Two --- + +# As the door slides open, you are presented with a second door that uses a +# slightly more inspired security mechanism. Clearly unimpressed by the last +# version (in what movie is the password decrypted in order?!), the Easter +# Bunny engineers have worked out a better solution. + +# Instead of simply filling in the password from left to right, the hash now +# also indicates the position within the password to fill. You still look for +# hashes that begin with five zeroes; however, now, the sixth character +# represents the position (0-7), and the seventh character is the character to +# put in that position. + +# A hash result of 000001f means that f is the second character in the +# password. Use only the first result for each position, and ignore invalid +# positions. + +# For example, if the Door ID is abc: + +# The first interesting hash is from abc3231929, which produces 0000015...; +# so, 5 goes in position 1: _5______. +# In the previous method, 5017308 produced an interesting hash; however, it +# is ignored, because it specifies an invalid position (8). +# The second interesting hash is at index 5357525, which produces +# 000004e...; so, e goes in position 4: _5__e___. + +# You almost choke on your popcorn as the final character falls into place, +# producing the password 05ace8e3. + +# Given the actual Door ID and this new method, what is the password? Be extra +# proud of your solution if it uses a cinematic "decrypting" animation. + + +def part_2() -> None: + passwd = defaultdict(list) + end = "9" * len(_input) + for num in range(int(end)): + testing = _input + str(num) + result = md5(testing.encode()).hexdigest() + if ( + result.startswith("0" * 5) + # only numbers are allow + and str(result[5]).isdecimal() + # the passwd is 8 letters long + and int(result[5]) < 8 + ): + passwd[str(result[5])].append(result[6]) + if len(passwd.keys()) == 8: + ordered_passwd = dict(sorted(passwd.items())) + # take the first result for each key + my_lst = [elem[0] for elem in ordered_passwd.values()] + print(f"The password is {''.join(my_lst)}") + break + + if __name__ == "__main__": part_1() + part_2()