<jupyter_start><jupyter_text>Avent Of Code 2018 - DAY 4 <NAME>, 2018https://adventofcode.com/2018/day/4  strategy- read input- sort alphabetically- parse lines and build list (date, guard, minutes)- use pandas dataframes to sum and search asleep time<jupyter_code>import re
import numpy as np
import pandas as pd


def dumps(line):
    """writes the date as in sample"""
    d, g, l = line[0], line[1], line[2:]
    return '{} {:04} {}'.format(d, g, ''.join(('#' if x else '.') for x in l))


def read(input_file):
    """reads input and returns input sorted"""
    inputs = []
    with open(input_file) as f:
        for l in f:
            inputs.append(l.strip())
    inputs.sort()
    return inputs


def parse_input(inputs):
    """parse input to represent minutes as 0 or 1"""
    begin = re.compile(r"\[([0-9]+)-([0-9]+)-([0-9]+) ([0-9]+):([0-9]+)\] Guard #([0-9]+) begins shift")
    wakes_up = re.compile(r"\[([0-9]+)-([0-9]+)-([0-9]+) ([0-9]+):([0-9]+)\] wakes up")
    asleep = re.compile(r"\[([0-9]+)-([0-9]+)-([0-9]+) ([0-9]+):([0-9]+)\] falls asleep")

    state = 0
    g = 0
    lines = []
    for l in inputs:
        l = l.strip()
        b = begin.match(l.strip())
        w = wakes_up.match(l.strip())
        a = asleep.match(l.strip())

        if b:
            y, m, d, h, mi, g = (int(x) for x in b.groups())
            state = 0
            continue
        elif w:
            y, m, d, h, mi = (int(x) for x in w.groups())
            state = 0
        elif a:
            y, m, d, h, mi =(int(x) for x in a.groups())
            state = 1
        else:
            continue
        
        if not lines or lines[-1][0] != (y, m, d, g):
            lines.append([(y, m, d, g),[1-state] * 60])
        lines[-1][1] = lines[-1][1][0:mi]+([state] * (60-mi))

    return [['{}-{:02}-{:02}'.format(y, m, d), g] + l for (y, m, d, g), l in lines]<jupyter_output><empty_output><jupyter_text>Sample- read sample- apply the strategy<jupyter_code>def sample():
    return [x.strip() for x in 
            """
                [1518-11-01 00:00] Guard #10 begins shift
                [1518-11-01 00:05] falls asleep
                [1518-11-01 00:25] wakes up
                [1518-11-01 00:30] falls asleep
                [1518-11-01 00:55] wakes up
                [1518-11-01 23:58] Guard #99 begins shift
                [1518-11-02 00:40] falls asleep
                [1518-11-02 00:50] wakes up
                [1518-11-03 00:05] Guard #10 begins shift
                [1518-11-03 00:24] falls asleep
                [1518-11-03 00:29] wakes up
                [1518-11-04 00:02] Guard #99 begins shift
                [1518-11-04 00:36] falls asleep
                [1518-11-04 00:46] wakes up
                [1518-11-05 00:03] Guard #99 begins shift
                [1518-11-05 00:45] falls asleep
                [1518-11-05 00:55] wakes up
            """.split('\n') if x]

inputs = sample()
lines = parse_input(inputs)
print('\n'.join(dumps(l) for l in lines))<jupyter_output>1518-11-01 0010 .....####################.....#########################.....
1518-11-02 0099 ........................................##########..........
1518-11-03 0010 ........................#####...............................
1518-11-04 0099 ....................................##########..............
1518-11-05 0099 .............................................##########.....<jupyter_text>part 1<jupyter_code>def strategy_1(lines):
    # create the dataframe with minutes as columns
    df = pd.DataFrame(lines, columns=['date', 'guard']+[str(x) for x in range(60)])
    df.set_index(['date', 'guard'], inplace=True)
    
    # sums the total asleep time per line
    df['total'] = df['0':'59'].sum(axis=1)
    
    # sum columns (minutes + total) by guard
    df2 = df.reset_index().set_index(['guard']).drop(['date'], axis=1).groupby('guard').sum()
    
    # finds the guard with greatest total
    guard = df2['total'].idxmax()
    
    # sum all columns (after drop total) for this guard
    minute = int(df2.drop(['total'], axis=1).loc[guard].idxmax())
    
    return guard * minute<jupyter_output><empty_output><jupyter_text>sample<jupyter_code>lines = parse_input(sample())
print(strategy_1(lines))<jupyter_output>240<jupyter_text>input file<jupyter_code>lines = parse_input(read('input.txt'))
print(strategy_1(lines))<jupyter_output>19874<jupyter_text>Part 2<jupyter_code>def strategy_2(lines):
    df = pd.DataFrame(lines, columns=['date', 'guard']+[str(x) for x in range(60)])
    df.set_index(['date', 'guard'], inplace=True)
    
    # sum group by guard
    df2 = df.reset_index().set_index(['guard']).drop(['date'], axis=1).groupby('guard').sum()
    guard = df2.max(axis=1).idxmax()
    minute = df2.loc[guard].idxmax()
    minute = int(minute)
    return guard * minute<jupyter_output><empty_output><jupyter_text>Sample<jupyter_code>lines = parse_input(sample())
print(strategy_2(lines))<jupyter_output>4455<jupyter_text>Input file<jupyter_code>lines = parse_input(read('input.txt'))
print(strategy_2(lines))<jupyter_output>22687
{'fraction_non_alphanumeric': 0.2225952992297057, 'fraction_numerical': 0.07722694054908157, 'mean_word_length': 2.275549805950841, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 1, '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': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '667330', 'license': 'Unlicense', 'n_tokens_mistral': 1989, 'n_tokens_neox': 1757, 'n_words': 419, 'path': '04/day-4.ipynb', 'repo_name': 'jdhalimi/aoc-2018', 'size': '5074'}