adventofcode/2018/07/sol2.pl

64 lines
1.0 KiB
Perl

use 5.20.0;
use warnings;
use experimental qw/
signatures
postderef
/;
use List::UtilsBy qw/ nsort_by /;
use List::AllUtils qw/ min /;
use Sim;
use Graph::Directed;
my $g = Graph::Directed->new;
while(<>) {
/Step (.).*before step (.)/;
$g->add_edge( $1 => $2 );
}
my $workers = 5;
Sim->schedule(
0 => \&check_for_work,
);
my %available = map { $_ => 1 } $g->vertices;
Sim->run( fires => 100_000 );
sub time_for {
ord(shift) - ord('A') + 1 + 60;
}
sub check_for_work {
say "time: ", Sim->now;
my @next = sort $g->predecessorless_vertices or return;
while( $workers ) {
my $next = shift @next or return;
$available{$next} or next;
delete $available{$next};
$workers--;
Sim->schedule(
Sim->now + time_for($next) => sub {
say "time done $next: ", Sim->now;
$g->delete_vertex($next);
$workers++;
Sim->schedule( Sim->now, \&check_for_work );
}
)
}
}