diff options
Diffstat (limited to 'day4/solve.py')
-rw-r--r-- | day4/solve.py | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/day4/solve.py b/day4/solve.py new file mode 100644 index 0000000..3f9ea3b --- /dev/null +++ b/day4/solve.py @@ -0,0 +1,106 @@ +from collections import defaultdict + +from antlr4 import CommonTokenStream, ParseTreeWalker +from antlr4 import InputStream + +from commons import get_input +from day4.GrammarLexer import GrammarLexer +from day4.GrammarListener import GrammarListener +from day4.GrammarParser import GrammarParser + + +def parse_date(date: GrammarParser.DateContext): + mon = int(date.month.text) + day = int(date.day.text) + min = int(date.minute.text) + return mon * 31 + day, min + + +class GuardTimeListener(GrammarListener): + + def enterWakeup(self, ctx: GrammarParser.WakeupContext): + date: GrammarParser.DateContext = ctx.parentCtx.date() + date = parse_date(date) + events.append((date, 'wakeup')) + + def enterAsleep(self, ctx: GrammarParser.AsleepContext): + date: GrammarParser.DateContext = ctx.parentCtx.date() + date = parse_date(date) + events.append((date, 'asleep')) + + def enterShift(self, ctx: GrammarParser.ShiftContext): + date: GrammarParser.DateContext = ctx.parentCtx.date() + date = parse_date(date) + events.append((date, ctx.guard.text)) + + +def find_times(): + current_guard = 0 + asleep_since = [] + for time, ev in events: + if ev == 'asleep': + asleep_since = time + elif ev == 'wakeup': + if type(current_guard) != str: + print(type(current_guard)) + print(current_guard) + print(time) + day_table = guards[current_guard][asleep_since[0]] + for minute in range(asleep_since[1], time[1]): + day_table[minute] = True + else: + current_guard = ev + + +def parse_tree(): + lexer = GrammarLexer(InputStream(txt)) + stream = CommonTokenStream(lexer) + parser = GrammarParser(stream) + tree = parser.root() + listener = GuardTimeListener() + walker = ParseTreeWalker() + walker.walk(listener, tree) + + +def find_sums(): + for guard, times in guards.items(): + sleepy_time[guard] = sum(map(sum, times.values())) + + +def find_sleepiest_minute(guard): + mm = defaultdict(int) + for day, minutes in guards[guard].items(): + for minute, sleeps in minutes.items(): + if sleeps: + mm[minute] += 1 + return max(mm.items(), key=lambda x: x[1]) + + +def find_sleepiest_minute_guard(): + currentmax = 0 + gm, mm = '0', 0 + for guard in guards.keys(): + minute, value = find_sleepiest_minute(guard) + if value > currentmax: + currentmax = value + print(value) + gm, mm = guard, minute + return int(gm) * mm + + +txt = get_input(4) +events = [] +sleepy_time = defaultdict(int) +guards = defaultdict(lambda: defaultdict(lambda: defaultdict(bool))) +parse_tree() + +events.sort() +find_times() +find_sums() + +sleepiest = max(sleepy_time, key=sleepy_time.get) +sleepiest_minute = find_sleepiest_minute(sleepiest)[0] + +if __name__ == '__main__': + print('first:', sleepiest_minute * int(sleepiest)) + print('second:', find_sleepiest_minute_guard()) |