--- /dev/null
+#!/usr/bin/perl -w
+
+use v5.16;
+
+my @m = map { chomp; [ split // ] } <>;
+
+my $xmax = @{ $m[0] };
+my $ymax = @m;
+
+sub print_map {
+ my $m = shift;
+ for my $row (@m) {
+ say join('', @$row);
+ }
+ say "";
+}
+
+my $step;
+my $moved;
+do {
+ $moved = 0;
+ my @m1;
+ for my $y (0 .. $ymax-1) {
+ for my $x (0 .. $xmax-1) {
+ if ($m[$y][$x] eq '>') {
+ my $nx = $x+1;
+ $nx = 0 if $nx >= $xmax;
+ if ($m[$y][$nx] eq '.') {
+ $m1[$y][$nx] = '>';
+ $m1[$y][$x] = '.';
+ $moved++;
+ } else {
+ $m1[$y][$x] = $m[$y][$x];
+ }
+ } else {
+ if (!defined $m1[$y][$x]) {
+ $m1[$y][$x] = $m[$y][$x];
+ }
+ }
+ }
+ }
+ @m = @m1;
+ @m1 = ();
+
+ for my $y (0 .. $ymax-1) {
+ for my $x (0 .. $xmax-1) {
+ if ($m[$y][$x] eq 'v') {
+ my $ny = $y+1;
+ $ny = 0 if $ny >= $ymax;
+ if ($m[$ny][$x] eq '.') {
+ $m1[$ny][$x] = 'v';
+ $m1[$y][$x] = '.';
+ $moved++;
+ } else {
+ $m1[$y][$x] = $m[$y][$x];
+ }
+ } else {
+ if (!defined $m1[$y][$x]) {
+ $m1[$y][$x] = $m[$y][$x];
+ }
+ }
+ }
+ }
+ @m = @m1;
+ $step++;
+ print_map(\@m);
+} while ($moved);
+
+say "$step steps";
+