Day 14 - Advent of Code 2016

Working solutions for the day 14 puzzles.

Part One

""" day_14_01.py """

# usage: python3 day_14_01.py "ihaygndm"

import sys
from hashlib import md5


def n_tuple(num, text):
    """ determine if n-tuple of single character occurs """
    for pos, _ in enumerate(text[:1 - num]):
        chunk = text[pos:pos + num]
        if len(set(chunk)) == 1:
            if chunk[0] != text[pos + num:pos + num + 1]:
                return chunk[0]
    return ''


def triple(text):
    """ determine if triple of single character occurs """
    return n_tuple(3, text)


def quintuple(text):
    """ determine if quintuple of single character occurs """
    return n_tuple(5, text)


def md5_digest(salt_arg, index_arg):
    """ generate digest """
    digest = md5()
    digest.update((salt_arg + str(index_arg)).encode())
    return digest.hexdigest()


salt = sys.argv[1]

goal = 64
answer = []
keys = 0
index = 0
while keys < goal:
    hexdigest5 = md5_digest(salt, index)
    if (digit := quintuple(hexdigest5)) != '':
        for i in range(index - 1, max(-1, index - 1001), -1):
            hexdigest3 = md5_digest(salt, i)
            if digit == triple(hexdigest3):
                answer.append(i)
                keys += 1
    index += 1

answer.sort()
print(answer[goal - 1])

Part Two

""" day_14_02.py """

# usage: python3 day_14_02.py "ihaygndm"

import sys
from hashlib import md5


def n_tuple(num, text):
    """ determine if n-tuple of single character occurs """
    for pos, _ in enumerate(text[:1 - num]):
        chunk = text[pos:pos + num]
        if len(set(chunk)) == 1:
            if chunk[0] != text[pos + num:pos + num + 1]:
                return chunk[0]
    return ''


def triple(text):
    """ determine if triple of single character occurs """
    return n_tuple(3, text)


def quintuple(text):
    """ determine if quintuple of single character occurs """
    return n_tuple(5, text)


def md5_digest(salt_arg, index_arg):
    """ generate digest """
    digest = md5()
    digest.update((salt_arg + str(index_arg)).encode())
    for _ in range(2016):
        md = digest.hexdigest()
        digest = md5()
        digest.update(md.encode())
    return digest.hexdigest()


salt = sys.argv[1]

goal = 64
answer = []
keys = 0
index = 0
while keys < goal:
    hexdigest5 = md5_digest(salt, index)
    if (digit := quintuple(hexdigest5)) != '':
        for i in range(index - 1, max(-1, index - 1001), -1):
            hexdigest3 = md5_digest(salt, i)
            if digit == triple(hexdigest3):
                answer.append(i)
                keys += 1
    index += 1

answer.sort()
print(answer[goal - 1])