--- /dev/null
+#!/usr/bin/perl -w
+
+use v5.30;
+use strict;
+
+$; = ',';
+my @map = map { chomp; [ split // ] } <>;
+my $xmax = $#{ $map[0] };
+my $ymax = $#map;
+
+my @carts;
+for my $y (0 .. $ymax) {
+ for my $x (0 .. $xmax) {
+ my $p = $map[$y][$x];
+ if ($p eq '^') {
+ $map[$y][$x] = '|';
+ push @carts, [ $x, $y, 0, 0 ];
+ }
+ if ($p eq '>') {
+ $map[$y][$x] = '-';
+ push @carts, [ $x, $y, 1, 0 ];
+ }
+ if ($p eq 'v') {
+ $map[$y][$x] = '|';
+ push @carts, [ $x, $y, 2, 0 ];
+ }
+ if ($p eq '<') {
+ $map[$y][$x] = '-';
+ push @carts, [ $x, $y, 3, 0 ];
+ }
+ }
+}
+
+my %cartpos;
+for my $i (0 .. $#carts) {
+ my $c = $carts[$i];
+ my ($x, $y) = @$c;
+ $cartpos{$x,$y} = $i;
+}
+while (1) {
+ for my $i (0 .. $#carts) {
+ my $c = $carts[$i];
+ next if $c->[4];
+ my ($x, $y, $dir, $state) = @$c;
+ my $m = $map[$y][$x];
+ if ($m eq '/') {
+ $dir =~ y/0123/1032/;
+ } elsif ($m eq '\\') {
+ $dir =~ y/0123/3210/;
+ } elsif ($m eq '+') {
+ if ($state == 0) {
+ $dir =~ y/0123/3012/;
+ } elsif ($state == 2) {
+ $dir =~ y/0123/1230/;
+ }
+ $state = 0 if ++$state > 2;
+ }
+ delete $cartpos{$x,$y};
+ $y-- if $dir == 0;
+ $x++ if $dir == 1;
+ $y++ if $dir == 2;
+ $x-- if $dir == 3;
+ if (defined $cartpos{$x,$y}) {
+ $c->[4] = 1;
+ $carts[$cartpos{$x,$y}]->[4] = 1;
+ delete $cartpos{$x,$y};
+ } else {
+ $cartpos{$x,$y} = $i;
+ }
+ $c->[0] = $x;
+ $c->[1] = $y;
+ $c->[2] = $dir;
+ $c->[3] = $state;
+ }
+ @carts = sort { $a->[1] == $b->[1]
+ ? $a->[0] <=> $b->[0]
+ : $a->[1] <=> $b->[1] } grep { !defined $_->[4] } @carts;
+ if (@carts == 1) {
+ say $carts[0][0], ',', $carts[0][1];
+ last;
+ }
+}