92 lines
2.0 KiB
Perl
92 lines
2.0 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 solution_2 ($input) {
|
|
my $p = Part1::parse_input($input);
|
|
my @directions = $p->{directions}->@*;
|
|
my %nodes = $p->{nodes}->%*;
|
|
|
|
my @paths;
|
|
my @initial = grep { /A$/ } keys %nodes;
|
|
for (@initial ) {
|
|
push @paths, [
|
|
Part2::get_cycle($_,\@directions,\%nodes)
|
|
];
|
|
}
|
|
|
|
my $visited = 0;
|
|
my @preloop = map { shift @$_ } @paths;
|
|
p @preloop;
|
|
my $pre = max @preloop;
|
|
$visited += $pre;
|
|
|
|
my @current = map { $preloop[$_] - $pre } 0..$#preloop;
|
|
p @current;p @paths;
|
|
for(0..$#current) {
|
|
while( $current[$_] <= 0 ) {
|
|
$current[$_] += $paths[$_][0];
|
|
push $paths[$_]->@*, shift $paths[$_]->@*;
|
|
}
|
|
}
|
|
p @current;p @paths;
|
|
|
|
until( none { $_ } @current ) {
|
|
use DDP;
|
|
warn $visited;
|
|
p @current;p @paths;
|
|
my $incr = max @current;
|
|
warn $incr;
|
|
$visited += $incr;
|
|
for ( 0..$#current) {
|
|
$current[$_] -= $incr;
|
|
while( $current[$_] < 0 ) {
|
|
$current[$_] += $paths[$_][0];
|
|
push $paths[$_]->@*, shift $paths[$_]->@*;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $visited;
|
|
|
|
|
|
}
|
|
|
|
1;
|
|
|
|
1;
|