adventofcode/2023/08/Part2.pm

89 lines
1.9 KiB
Perl

use 5.38.0;
package Part2;
use Part1;
use List::AllUtils qw/all first_index none min max /;
sub get_cycle( $current, $directions, $nodes ) {
my @tracks;
my $next_index = 0;
while() {
use DDP; #p @tracks;
my $t = join '-', $current,$next_index;
my $i = first_index { $_ eq $t } @tracks;
if( $i > -1 ) {
my $c = 0;
# p @tracks;
# warn $i, " ",$t;
return $i, map {
$c++;
if(/Z-/) {
my $x = $c; $c = 0; $x;
}else {
()
}
} splice @tracks, $i;
}
push @tracks, $t;
$current = $nodes->{$current}[ $directions->[ $next_index ] ];
$next_index = ( $next_index+1)% @$directions;
}
}
sub find_z($current,$next_index,$directions,$nodes) {
my $visited = 0;
while ( ) {
$visited++;
$current =
$nodes->{$current}[ $directions->[ $next_index++ % @$directions ] ];
last if $current =~ /Z$/
}
return $visited, $current, $next_index;
}
sub speedrun($current,$next_index,$directions,$nodes,$n) {
$current =
$nodes->{$current}[ $directions->[ $next_index++ % @$directions ] ]
for 1..$n;
return $current;
}
sub solution_2 ($input) {
my $p = Part1::parse_input($input);
my @directions = $p->{directions}->@*;
my %nodes = $p->{nodes}->%*;
my $steps = 0;
my @paths = grep { /A$/ } keys %nodes;
my $next_index = 0;
until( all {/Z$/ } @paths ) {
my($incr,$current,$new_index) = find_z($paths[0],$next_index,\@directions,\%nodes);
$paths[0] = $current;
@paths = ( $current, map {
speedrun($paths[$_],$next_index,\@directions,\%nodes,$incr)
} 1..$#paths );
$next_index = $new_index;
$steps += $incr;
}
return $steps;
}
1;