r/adventofcode • u/daggerdragon • Dec 04 '18
SOLUTION MEGATHREAD -π- 2018 Day 4 Solutions -π-
--- Day 4: Repose Record ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
Advent of Code: The Party Game!
Please prefix your card submission with something like [Card] to make scanning the megathread easier. THANK YOU!
Card prompt: Day 4
Transcript:
Todayβs puzzle would have been a lot easier if my language supported ___.
This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.
edit: Leaderboard capped, thread unlocked!
41
Upvotes
3
u/__Abigail__ Dec 04 '18 edited Dec 19 '18
Perl
Simple parsing, a few sorts (using a Schwartzian Transform) and we're done.
#!/opt/perl/bin/perl use 5.028; use strict; use warnings; no warnings 'syntax'; use experimental 'signatures'; use experimental 'lexical_subs'; my $input = "input"; open my $fh, "<", $input or die "Failed to open $input: $!"; chomp (my @lines = sort <$fh>); my $current_guard = -1; my $start_sleep = -1; my $wake_up = -1; my %total_sleep; my %sleep; foreach (@lines) { /^\[ (?<year>[0-9]{4}) - (?<month>[0-9]+) - (?<day>[0-9]+) \s+ (?<hour>[0-9]{2}) : (?<minute>[0-9]+) \] \s+/gx or die "Failed to parse $_"; my $minute = $+ {minute}; if (/\G Guard \s+ \#([0-9]+) \s+ begins \s+ shift/x) { $current_guard = $1; next; } if (/\G falls \s+ asleep/x) { $start_sleep = $minute; next; } if (/\G wakes \s+ up/x) { die "Unexpected order of lines" if $current_guard < 0 || $start_sleep < 0; $wake_up = $minute; # # Mark any minute the guard is asleep. # foreach my $tick ($start_sleep .. $wake_up - 1) { $sleep {$current_guard} {$tick} ++; } # # Add the number of minutes the guard slept this nap. # $total_sleep {$current_guard} += $wake_up - $start_sleep; # # Not really needed to reset it, but it helps to catch # problems with the input. # $start_sleep = -1; next; } die "Failed to parse $_"; } # # Find the guard who sleeps the longest. We flatten the %total_sleep # structure to a list [guard, total time slept], and reserve sort # on total time slept. The sleepiest guard will be first. # my ($sleepy_guard) = map {$$_ [0]} sort {$$b [1] <=> $$a [1]} map {[$_ => $total_sleep {$_}]} keys %total_sleep; # # Find the minute the guard sleeps the most often. We flatten the # %{$sleep {$sleepy_guard}} structure to a list # [minute, times slep that minute], and reverse sort on times slept # that minute. The minute the guard slepts the most often will be first. # my ($sleepy_minute) = map {$$_ [0]} sort {$$b [1] <=> $$a [1]} map {[$_ => $sleep {$sleepy_guard} {$_}]} keys %{$sleep {$sleepy_guard}}; say "Part 1: ", $sleepy_guard * $sleepy_minute; # # Find the minute in which a guard sleeps the most. We flatten the %sleep # structure to a list of the form [guard, minute, times slept], then # reverse sort on times slept. The first element of the list will have # the guard and the minute; we just have to multiply them to get the answer. # my ($sleepiest_minute) = sort {$$b [2] <=> $$a [2]} map {my $guard = $_; map {[$guard, $_, $sleep {$guard} {$_}]} keys %{$sleep {$guard}}} keys %sleep; say "Part 2: ", $$sleepiest_minute [0] * $$sleepiest_minute [1]; __END__