72 lines
1.2 KiB
Perl
72 lines
1.2 KiB
Perl
|
use lib '.';
|
||
|
|
||
|
use Part1;
|
||
|
|
||
|
package Part2;
|
||
|
|
||
|
use 5.36.0;
|
||
|
|
||
|
sub read_input ($file) {
|
||
|
my $i = 0;
|
||
|
my $data = 1;
|
||
|
my $x = [
|
||
|
map { [ ( $data++ % 2 ) ? $i++ : -1, $_ ] }
|
||
|
split '', $file->slurp
|
||
|
];
|
||
|
return $x;
|
||
|
}
|
||
|
|
||
|
|
||
|
sub print_disk(@disk) {
|
||
|
for (@disk) {
|
||
|
my @a = ($_->[0] == -1 ? '.':$_->[0]) x $_->[1];
|
||
|
print @a;
|
||
|
}
|
||
|
print "\n";
|
||
|
}
|
||
|
|
||
|
sub my_first_index($max,@disk) {
|
||
|
my $i = -1;
|
||
|
while(++$i < $max ) {
|
||
|
return $i if $_->[0] == -1 and $_->[1] >= $disk[$i][1];
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
sub solve (@disk) {
|
||
|
use DDP;
|
||
|
|
||
|
my $i = @disk;
|
||
|
|
||
|
use List::MoreUtils qw/ first_index /;
|
||
|
|
||
|
while( --$i >= 0 ) {
|
||
|
next if $i > $#disk;
|
||
|
|
||
|
next if $disk[$i][0] == -1;
|
||
|
|
||
|
my $swap = first_index {
|
||
|
$_->[0] == -1 and $_->[1] >= $disk[$i][1];
|
||
|
} @disk;
|
||
|
|
||
|
next if $swap == -1 or $swap >= $i;
|
||
|
|
||
|
$disk[$swap][1] -= $disk[$i][1];
|
||
|
splice @disk, $swap, 0, [ $disk[$i]->@* ];
|
||
|
$disk[++$i][0] = -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
my $checksum = 0;
|
||
|
|
||
|
$i = 0;
|
||
|
while( my $p = shift @disk ) {
|
||
|
$checksum += $i++ * ( $_ == -1 ? 0 : $_ ) for ( $p->[0]) x $p->[1];
|
||
|
}
|
||
|
|
||
|
return $checksum;
|
||
|
|
||
|
}
|
||
|
|
||
|
1;
|