[py] Port 2018_04

This commit is contained in:
Joscha 2022-12-06 15:23:45 +01:00
parent 71b7bcc548
commit fe36dd0af3
4 changed files with 118 additions and 133 deletions

View file

@ -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)

View file

@ -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

View file

@ -2,7 +2,7 @@ import sys
import argparse import argparse
from pathlib import Path from pathlib import Path
from .y2018 import d01, d02, d03 from .y2018 import d01, d02, d03, d04
from .y2020 import d10 from .y2020 import d10
from .y2021 import d14 from .y2021 import d14
from .y2022 import d01, d02, d03, d04, d05, d06 from .y2022 import d01, d02, d03, d04, d05, d06
@ -11,6 +11,7 @@ DAYS = {
"2018_01": y2018.d01.solve, "2018_01": y2018.d01.solve,
"2018_02": y2018.d02.solve, "2018_02": y2018.d02.solve,
"2018_03": y2018.d03.solve, "2018_03": y2018.d03.solve,
"2018_04": y2018.d04.solve,
"2020_10": y2020.d10.solve, "2020_10": y2020.d10.solve,
"2021_14": y2021.d14.solve, "2021_14": y2021.d14.solve,
"2022_01": y2022.d01.solve, "2022_01": y2022.d01.solve,

116
py/aoc/y2018/d04.py Normal file
View file

@ -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}")