diff --git a/2023/08/Part2.pm b/2023/08/Part2.pm index d7a70ee..969720c 100644 --- a/2023/08/Part2.pm +++ b/2023/08/Part2.pm @@ -4,30 +4,86 @@ package Part2; use Part1; -use List::AllUtils qw/all /; +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 $visited = 0; - my $next_index = 0; - my @current = grep { /A$/ } keys %nodes; + my @paths; + my @initial = grep { /A$/ } keys %nodes; + for (@initial ) { + push @paths, [ + Part2::get_cycle($_,\@directions,\%nodes) + ]; + } - until ( all { /Z$/ } @current ) { - # use DDP; p @current; - # my $foo = <>; - $visited++; + my $visited = 0; + my @preloop = map { shift @$_ } @paths; + p @preloop; + my $pre = max @preloop; + $visited += $pre; - @current = map { - $nodes{$_}->[ $directions[ $next_index % @directions ] ] - } @current; - $next_index++; + 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; diff --git a/2023/08/part2.t b/2023/08/part2.t index cb5f141..50662fa 100644 --- a/2023/08/part2.t +++ b/2023/08/part2.t @@ -8,10 +8,7 @@ use File::Serialize; use Part2; my $input = path('input')->slurp; -my $example = path('example')->slurp; -my %solutions = deserialize_file('solutions.yml')->%*; - -is Part2::solution_2(<<'END') => 6; +my $example = <%*; + + +my $parsed = Part1::parse_input($example); +is [Part2::get_cycle('11A',$parsed->{directions},$parsed->{nodes})] => [1,2]; +#use DDP; my @x = Part2::get_cycle('22A',$parsed->{directions},$parsed->{nodes});p @x; +is [Part2::get_cycle('22A',$parsed->{directions},$parsed->{nodes})] => [1,2,3]; + + +is Part2::solution_2($example) => 6; +exit; + + + +$parsed = Part1::parse_input($input); + +# my @initial = grep { /A$/ } keys $parsed->{nodes}->%*; +# for (@initial ) { +# say join " ", Part2::get_cycle($_,$parsed->{directions},$parsed->{nodes}); +# } + is Part2::solution_2($input) => $solutions{2};