diff --git a/2023/08/Part2.pm b/2023/08/Part2.pm index d7a70ee..49a699d 100644 --- a/2023/08/Part2.pm +++ b/2023/08/Part2.pm @@ -4,32 +4,124 @@ package Part2; use Part1; -use List::AllUtils qw/all /; +use List::AllUtils qw/all first_index none min max product /; +use List::UtilsBy qw/ min_by max_by /; + use Math::Utils qw/ lcm /; + +sub get_cycle( $current, $directions, $nodes ) { + + my @tracks; + my $next_index = 0; + + while() { + 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 equation_for($current,$directions,$nodes) { + + my $visited = 0; + my $next_index=0; + + while ( ) { + $visited++; + + $current = + $nodes->{$current}[ $directions->[ $next_index++ % @$directions ] ]; + + last if $current =~ /Z$/ + } + + my $first = $visited; + $visited = 0; + + while ( ) { + $visited++; + + $current = + $nodes->{$current}[ $directions->[ $next_index++ % @$directions ] ]; + + last if $current =~ /Z$/ + } + + my $entry = { b => $first, m => $visited }; + return $entry; +} + sub solution_2 ($input) { my $p = Part1::parse_input($input); my @directions = $p->{directions}->@*; my %nodes = $p->{nodes}->%*; - my $visited = 0; + my $steps = 0; + my @paths = grep { /A$/ } keys %nodes; my $next_index = 0; - my @current = grep { /A$/ } keys %nodes; - until ( all { /Z$/ } @current ) { - # use DDP; p @current; - # my $foo = <>; - $visited++; + my @equations = map { equation_for($_,\@directions,\%nodes) } @paths; - @current = map { - $nodes{$_}->[ $directions[ $next_index % @directions ] ] - } @current; - $next_index++; + return lcm map { $_->{b} } @equations; + + for(@equations) { + $_->{i} = 1; + $_->{total} = $_->{b}+$_->{m}; } - return $visited; + until( all { $_->{total} == $equations[0]->{total} } @equations ) { + my $i = max map { $_->{total} } @equations; + for(@equations) { + while( $_->{total}<$i) { + $_->{total}+=$_->{m}; + } + } + # use DDP; p @equations; + } + + $equations[0]->{total}; } 1; - -1; diff --git a/2023/08/benchmark.pl b/2023/08/benchmark.pl index 0d7280d..6154f18 100644 --- a/2023/08/benchmark.pl +++ b/2023/08/benchmark.pl @@ -36,6 +36,7 @@ for my $part (@parts) { language => 'perl', part => $part->{part}, time => $res->cpu_a / $res->iters, + persec => $res->iters / $res->cpu_a, timestamp => DateTime->now->iso8601, }; say to_json $result; diff --git a/2023/08/part2.t b/2023/08/part2.t index cb5f141..f812d5f 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; + +$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}; diff --git a/2023/08/solutions.yml b/2023/08/solutions.yml index b7e185a..1e0b577 100644 --- a/2023/08/solutions.yml +++ b/2023/08/solutions.yml @@ -1,2 +1,2 @@ 1: 19631 -2: TODO +2: 21003205388413 diff --git a/2023/benchmark.json b/2023/benchmark.json index aeaa9cd..aaa69f8 100644 --- a/2023/benchmark.json +++ b/2023/benchmark.json @@ -18,3 +18,6 @@ {"day":"7","part":2,"persec":85.2380952380952,"year":"2023","timestamp":"2023-12-07T16:08:43","time":0.011731843575419,"language":"perl"} {"persec":113.488372093023,"timestamp":"2023-12-09T17:57:35","language":"perl","year":"2023","time":0.00881147540983607,"day":"9","part":1} {"persec":109.783631232361,"timestamp":"2023-12-09T17:57:47","language":"perl","time":0.00910882604970008,"day":"9","part":2,"year":"2023"} +{"day":"8","persec":131.374407582938,"language":"perl","part":1,"time":0.00761183261183261,"timestamp":"2023-12-09T19:45:23","year":"2023"} +{"day":"8","language":"perl","time":0.0874789915966387,"year":"2023","timestamp":"2023-12-09T20:31:05","persec":11.431316042267,"part":2} + diff --git a/2023/cpanfile b/2023/cpanfile new file mode 100644 index 0000000..2c446d6 --- /dev/null +++ b/2023/cpanfile @@ -0,0 +1 @@ +requires 'Math::Utils';