adventofcode/2023/08/Part2.pm

128 lines
2.7 KiB
Perl

use 5.38.0;
package Part2;
use Part1;
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 $steps = 0;
my @paths = grep { /A$/ } keys %nodes;
my $next_index = 0;
my @equations = map { equation_for($_,\@directions,\%nodes) } @paths;
return lcm map { $_->{b} } @equations;
for(@equations) {
$_->{i} = 1;
$_->{total} = $_->{b}+$_->{m};
}
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;