diff --git a/py/2018/04/solve.py b/py/2018/04/solve.py deleted file mode 100644 index 5e46e7a..0000000 --- a/py/2018/04/solve.py +++ /dev/null @@ -1,115 +0,0 @@ -import re -import sys - -# PART 1 - -ACTION_RE = r"\[(\d+)-(\d+)-(\d+) (\d+):(\d+)\] (.*)\n" -GUARD_RE = r"Guard #(\d+) begins shift" - -def load_actions(filename): - actions = [] - with open(filename, "r") as f: - for line in f: - match = re.fullmatch(ACTION_RE, line) - y, m, d, hour, minute, action = match.groups() - y, m, d, hour, minute = int(y), int(m), int(d), int(hour), int(minute) - actions.append((y, m, d, hour, minute, action)) - return actions - -def calculate_guards(actions): - guards = {} - - guard = None - asleep_since = None - - for action in sorted(actions): - _, _, _, _, m, text = action - - match = re.fullmatch(GUARD_RE, text) - if match: - guard = int(match.group(1)) - - elif text == "falls asleep": - asleep_since = m - - elif text == "wakes up": - l = guards.get(guard, []) - guards[guard] = l - - l.append((asleep_since, m)) - - return guards - -def sleeps_longest(guards): - sleepiest_guard = None - sleepy_time = -1 - - for guard, sleep_times in guards.items(): - total = 0 - for start, end in sleep_times: - total += end - start - - if total > sleepy_time: - sleepiest_guard = guard - sleepy_time = total - - return sleepiest_guard - -def sleepiest_minute(times): - counter = {} - for start, end in times: - for m in range(start, end): - counter[m] = counter.get(m, 0) + 1 - - max_minute = None - amount = -1 - for m, n in sorted(counter.items()): - if n > amount: - max_minute = m - amount = n - - return max_minute - -# PART 2 - -def sleep_times(times): - minutes = {} - for start, end in times: - for m in range(start, end): - minutes[m] = minutes.get(m, 0) + 1 - return minutes - -def sleepy_minutes(guards): - minutes = {} - for guard, times in guards.items(): - for m, n in sleep_times(times).items(): - md = minutes.get(m, {}) - minutes[m] = md - md[guard] = n - - sleepy_minute = m - sleepy_guard = None - sleep_time = -1 - - for m, md in minutes.items(): - for guard, n in md.items(): - if n > sleep_time: - sleepy_minute = m - sleepy_guard = guard - sleep_time = n - - return sleepy_guard, sleepy_minute - -def main(filename): - actions = load_actions(filename) - guards = calculate_guards(actions) - print(f"Solutions for {filename}") - guard = sleeps_longest(guards) - minute = sleepiest_minute(guards[guard]) - print(f"Part 1: {guard * minute} - Guard {guard} slept most on minute {minute}.") - guard_2, minute_2 = sleepy_minutes(guards) - print(f"Part 2: {guard_2 * minute_2} - Guard {guard_2} slept most on minute {minute_2}.") - -if __name__ == "__main__": - for filename in sys.argv[1:]: - main(filename) diff --git a/py/2018/04/test_input.txt b/py/2018/04/test_input.txt deleted file mode 100644 index 496d314..0000000 --- a/py/2018/04/test_input.txt +++ /dev/null @@ -1,17 +0,0 @@ -[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 diff --git a/py/aoc/__init__.py b/py/aoc/__init__.py index d03f79a..2e871aa 100644 --- a/py/aoc/__init__.py +++ b/py/aoc/__init__.py @@ -2,7 +2,7 @@ import sys import argparse from pathlib import Path -from .y2018 import d01, d02, d03 +from .y2018 import d01, d02, d03, d04 from .y2020 import d10 from .y2021 import d14 from .y2022 import d01, d02, d03, d04, d05, d06 @@ -11,6 +11,7 @@ DAYS = { "2018_01": y2018.d01.solve, "2018_02": y2018.d02.solve, "2018_03": y2018.d03.solve, + "2018_04": y2018.d04.solve, "2020_10": y2020.d10.solve, "2021_14": y2021.d14.solve, "2022_01": y2022.d01.solve, diff --git a/py/aoc/y2018/d04.py b/py/aoc/y2018/d04.py new file mode 100644 index 0000000..6691c2e --- /dev/null +++ b/py/aoc/y2018/d04.py @@ -0,0 +1,116 @@ +import re + +# PART 1 + +ACTION_RE = r"\[(\d+)-(\d+)-(\d+) (\d+):(\d+)\] (.*)" +GUARD_RE = r"Guard #(\d+) begins shift" + + +def load_actions(inputstr): + actions = [] + for line in inputstr.splitlines(): + match = re.fullmatch(ACTION_RE, line) + y, m, d, hour, minute, action = match.groups() + y, m, d, hour, minute = int(y), int(m), int(d), int(hour), int(minute) + actions.append((y, m, d, hour, minute, action)) + return actions + + +def calculate_guards(actions): + guards = {} + + guard = None + asleep_since = None + + for action in sorted(actions): + _, _, _, _, m, text = action + + match = re.fullmatch(GUARD_RE, text) + if match: + guard = int(match.group(1)) + + elif text == "falls asleep": + asleep_since = m + + elif text == "wakes up": + l = guards.get(guard, []) + guards[guard] = l + + l.append((asleep_since, m)) + + return guards + + +def sleeps_longest(guards): + sleepiest_guard = None + sleepy_time = -1 + + for guard, sleep_times in guards.items(): + total = 0 + for start, end in sleep_times: + total += end - start + + if total > sleepy_time: + sleepiest_guard = guard + sleepy_time = total + + return sleepiest_guard + + +def sleepiest_minute(times): + counter = {} + for start, end in times: + for m in range(start, end): + counter[m] = counter.get(m, 0) + 1 + + max_minute = None + amount = -1 + for m, n in sorted(counter.items()): + if n > amount: + max_minute = m + amount = n + + return max_minute + + +# PART 2 + + +def sleep_times(times): + minutes = {} + for start, end in times: + for m in range(start, end): + minutes[m] = minutes.get(m, 0) + 1 + return minutes + + +def sleepy_minutes(guards): + minutes = {} + for guard, times in guards.items(): + for m, n in sleep_times(times).items(): + md = minutes.get(m, {}) + minutes[m] = md + md[guard] = n + + sleepy_minute = m + sleepy_guard = None + sleep_time = -1 + + for m, md in minutes.items(): + for guard, n in md.items(): + if n > sleep_time: + sleepy_minute = m + sleepy_guard = guard + sleep_time = n + + return sleepy_guard, sleepy_minute + + +def solve(inputstr): + actions = load_actions(inputstr) + guards = calculate_guards(actions) + guard = sleeps_longest(guards) + minute = sleepiest_minute(guards[guard]) + print(f"Part 1: {guard * minute}") + guard_2, minute_2 = sleepy_minutes(guards) + print(f"Part 2: {guard_2 * minute_2}")