--- /dev/null
+#!/usr/bin/perl -w
+
+use v5.40;
+
+chomp (my $line = <>);
+my $i = 0;
+my @blk = map { [ $i++, $_ ] } split //, $line;
+
+my $bno = 0;
+my $csum;
+sub add_blk($id, $count) {
+ die "$id" if $id % 2;
+ $id = $id/2;
+ $csum += ($bno++ * $id) for (1 .. $count);
+}
+
+my $freesp = 0;
+while (@blk) {
+ if (!$freesp) {
+ my $b = shift @blk;
+ add_blk(@$b);
+ last if !@blk;
+ $freesp = (shift @blk)->[1];
+ }
+
+ my ($eid, $ecnt) = $blk[-1]->@*;
+ if ($freesp < $ecnt) {
+ $blk[-1]->[1] -= $freesp;
+ add_blk($blk[-1]->[0], $freesp);
+ $freesp = 0;
+ } else {
+ last if !@blk;
+ my $b = pop @blk;
+ add_blk(@$b);
+ $freesp -= $b->[1];
+ last if !@blk;
+ pop @blk;
+ }
+}
+
+say $csum;
+
--- /dev/null
+#!/usr/bin/perl -w
+
+use v5.40;
+
+chomp (my $line = <>);
+my $i = 0;
+my @blk = map { [ $i++, $_ ] } split //, $line;
+
+my $mfile = $#blk;
+my %seen;
+while ($mfile) {
+ my ($id, $count) = $blk[$mfile]->@*;
+ if ($seen{$id}++) {
+ $mfile -= 2;
+ next;
+ }
+
+ my $freesp = 1;
+ while ($freesp < $mfile) {
+ if ($blk[$freesp]->[1] >= $count) {
+ if ($mfile < $#blk) {
+ my $free = $blk[$mfile+1]->[1];
+ splice @blk, $mfile+1, 1;
+ if ($mfile) {
+ $blk[$mfile-1]->[1] += $free + $count;
+ }
+ }
+ splice @blk, $mfile, 1;
+ my $free = $blk[$freesp]->[1];
+ splice @blk, $freesp, 1, [ -1, 0 ], [ $id, $count ],
+ [ -1, $free - $count ];
+ last;
+ }
+ $freesp += 2;
+ }
+}
+
+my $csum = 0;
+$i = 0;
+my $bno = 0;
+while ($i < @blk) {
+ my ($id, $count) = $blk[$i++]->@*;
+ $id /= 2;
+ $csum += ($bno++ * $id) for (1 .. $count);
+
+ last if $i >= @blk;
+ ($id, $count) = $blk[$i++]->@*;
+ $bno += $count;
+}
+say $csum;
+