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;