<jupyter_start><jupyter_text>This first part is just cleaning out the list to get something nicer<jupyter_code>with open("input_day4.txt", "r") as infile:
    contents = infile.read().strip()
contents = contents.split("\n")
contents[1]
import datetime

logs = list()

for line in contents: 
    date = datetime.datetime.strptime(line[0:18],  "[%Y-%m-%d %H:%M]")
    action = line[19:]
    logs.append([date, action]) # We create a list of lists with two elements: a date object and the action associated
    
logs[0]
logs.sort()
# We add the ID of the guard at the beginning of each line for clarity
guard_id = 0
ix = 0
while ix < len(logs):
    if 'Guard' in logs[ix][1]:
        guard_id = int(logs[ix][1][7:-13])
    logs[ix] = [guard_id] + logs[ix]
    ix += 1<jupyter_output><empty_output><jupyter_text>Part 1<jupyter_code>id_list = list()

for log in logs:
    if int(log[0]) not in id_list:
        id_list.append(int(log[0])) # We create a list of all the guard IDs
sleepers = list()

for guard in id_list:
    ix = 0
    sleeping = 0
    while ix < len(logs):
        if guard in logs[ix]:
            if 'wakes' in logs[ix][2]:
                if sleeping == 0:
                    sleeping = (logs[ix][1] - logs[ix-1][1])
                else:
                    sleeping += (logs[ix][1] - logs[ix-1][1])
        ix += 1
    if sleeping != 0:
        sleepers.append([sleeping, guard]) # We create a list of lists of 2 elements: total sleeping time, guard ID
target_guard = max(sleepers)[1]
target_guard<jupyter_output><empty_output><jupyter_text>We know now that the guard that sleeps the most in total is 2917! Now, we build a series of functions that feed into each other: function 2 uses function 1, function 3 uses function 2.<jupyter_code>def sleeptimes(guard):
    """Gives a list of all the minutes where the guard fell asleep / awoke: [minute slept, minute awoke]"""
    ix = 0
    sleep_log = list()
    sleep = 0
    awake = 0

    while ix < len(logs):
        if guard == logs[ix][0]:
            if 'wakes' in logs[ix][2]:
                sleep = logs[ix-1][1].minute
                awake = logs[ix][1].minute
                sleep_log.append([sleep, awake]) 
        ix += 1
    
    return sleep_log
import numpy as np

def totalsleep(guard):
    """Gives a list of 60 elements, where each element represents the number of times the guard was sleeping during that minute"""
    
    minutes = np.zeros(60) # We create a list of 60 zeros that represent each minute of the midnight hour
    sleep_log = sleeptimes(guard)
    
    for log in sleep_log:
        minutes[log[0]:log[1]] += 1 # Each time the guard is asleep during a certain minute, we increment this minute
    
    return minutes
def maxminute(guard):
    """Gives the minute during which the guard was most asleep and the number of times associated under the form\
    (guard ID, index of minute, number of times asleep)"""
    
    minutes = totalsleep(guard)
    m = max(minutes)
    m_ix = 0
    
    for ix, value in enumerate(minutes):
        if value == m:
            m_ix = ix # We find the index of the minute with the highest occurence of sleeping
            
    return(guard, m_ix, m)
maxminute(target_guard)
maxminute(target_guard)[0] * maxminute(target_guard)[1]<jupyter_output><empty_output><jupyter_text>Part 2<jupyter_code># We create a list of the 'maxminute's for each guard

max_minutes = list()

for guard in id_list:
    max_minutes.append(maxminute(guard))
minute_times = 0
minute_id = 0
guard_id = 0

# We want to identify the minute with the max occurence amongst all the guards

for minute in max_minutes:
    if minute[2] > minute_times:
        minute_times = minute[2] # We stock the max occurence
        minute_id = minute[1] # We stock the corresponding minute
        guard_id = minute[0] # We stock the corresponding guard id
guard_id * minute_id # Our answer!<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10158244002041858, 'fraction_numerical': 0.017866258295048495, 'mean_word_length': 2.9706180344478215, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '316393', 'license': 'MIT', 'n_tokens_mistral': 1283, 'n_tokens_neox': 1217, 'n_words': 450, 'path': 'solutions/2018/celine/day4.ipynb', 'repo_name': 'kws/AdventOfCode', 'size': '3918'}