--- /dev/null
+#!/usr/bin/perl -w
+
+use v5.36;
+use strict;
+
+local $/ = "\n\n";
+my @map = map { chomp; [ split // ] } split /\n/, scalar <>;
+my $ymax = $#map;
+
+local $/ = "\n";
+chomp (my $list = <>);
+
+my $dir = 0;
+my $dim;
+my ($x, $y) = (0, 0);
+$x++ while $map[$y][$x] eq ' ';
+
+my %face_ndir = (
+ A => [ 1, 1, 1, 3],
+ B => [ 0, 0, 0, 0],
+ C => [ 0, 1, 2, 3],
+ D => [ 2, 2, 2, 2],
+ E => [ 3, 1, 3, 3],
+ F => [ 2, 1, 0, 3],
+);
+my %face_next = (
+ A => [ qw(D C B F) ],
+ B => [ qw(C E F A) ],
+ C => [ qw(D E B A) ],
+ D => [ qw(F E C A) ],
+ E => [ qw(D F B C) ],
+ F => [ qw(D A B E) ],
+);
+
+my %face_of;
+my %face_dir;
+if ($Y::AoC::Task::in_test) {
+ $dim = 4;
+ %face_of = (
+ '20' => 'A',
+ '11' => 'B',
+ '21' => 'C',
+ '32' => 'D',
+ '22' => 'E',
+ '01' => 'F',
+ );
+ %face_dir = (
+ A => 0,
+ B => 0,
+ C => 0,
+ D => 1,
+ E => 0,
+ F => 2,
+ );
+} else {
+ $dim = 50;
+ %face_of = (
+ '10' => 'A',
+ '02' => 'B',
+ '11' => 'C',
+ '20' => 'D',
+ '12' => 'E',
+ '03' => 'F',
+ );
+ %face_dir = (
+ A => 0,
+ B => 3,
+ C => 0,
+ D => 3,
+ E => 0,
+ F => 1,
+ );
+}
+
+
+my %pos_of = reverse %face_of;
+sub pos_of($face) {
+ return map { $dim * $_ } split //, $pos_of{$face};
+}
+
+sub face_of($x, $y) {
+ return undef if $x < 0 || $y < 0;
+ my $fx = int($x/$dim);
+ my $fy = int($y/$dim);
+ return $face_of{"$fx$fy"};
+}
+
+sub move($sx, $sy, $dir) {
+ my $f1 = face_of($sx, $sy);
+ my ($dx, $dy) = ($sx, $sy);
+ if ($dir == 0) {
+ $dx++;
+ } elsif ($dir == 1) {
+ $dy++;
+ } elsif ($dir == 2) {
+ $dx--;
+ } elsif ($dir == 3) {
+ $dy--;
+ }
+ my $f2 = face_of($dx, $dy);
+ if (defined($f2) && $f2 eq $f1) {
+ return ($dx, $dy, $dir);
+ }
+ my $ndir;
+ say "moving from $f1 $dir";
+ my $rdir = ($dir - $face_dir{$f1}) % 4;
+ say "rdir = $rdir";
+ $f2 = $face_next{$f1}[$rdir];
+ my $rdir2 = $face_ndir{$f1}[$rdir];
+ say "rdir2 = $rdir";
+ $ndir = ($rdir2 + $face_dir{$f2}) % 4;
+ my ($nx, $ny) = ($dx % $dim, $dy % $dim);
+ my $rot = ($ndir - $dir) % 4;
+ say "$sx,$sy $nx,$ny $f1 -> $f2 r$rot $dir -> $ndir";
+ while ($rot--) {
+ # ($nx, $ny) = ($ny, (-$nx % $dim));
+ ($nx, $ny) = ((($dim-1-$ny) % $dim), $nx);
+ say "rot -> $nx,$ny";
+ }
+ say " -> $nx $ny $ndir";
+ my ($ox, $oy) = pos_of($f2);
+ $nx += $ox;
+ $ny += $oy;
+ say " -> $nx $ny";
+ say "FACE $sx,$sy,$dir $f1 -> $nx,$ny,$ndir $f2";
+ die if $map[$ny][$nx] eq ' ';
+ return ($nx, $ny, $ndir);
+}
+
+while (length $list) {
+ $list =~ s/^(\d+|[LR])//;
+ my $move = $1;
+ say "$x $y $dir $move";
+ if ($move =~ /\d+/) {
+ while ($move) {
+ my ($dx, $dy, $ddir) = move($x, $y, $dir);
+ last if $map[$dy][$dx] eq '#';
+ $x = $dx; $y = $dy; $dir = $ddir;
+ say " $x $y $dir $move";
+ $move--;
+ }
+ } elsif ($move eq 'L') {
+ $dir = 3 if --$dir < 0;
+ } elsif ($move eq 'R') {
+ $dir = 0 if ++$dir > 3;
+ }
+}
+
+say 1000*($y+1) + 4*($x+1) + $dir;
--- /dev/null
+#!/usr/bin/perl -w
+
+use v5.36;
+use strict;
+
+local $/ = "\n\n";
+my @map = map { chomp; [ split // ] } split /\n/, scalar <>;
+my $ymax = $#map;
+
+local $/ = "\n";
+chomp (my $list = <>);
+
+my $dir = 0;
+my $dim;
+my ($x, $y) = (0, 0);
+$x++ while $map[$y][$x] eq ' ';
+
+my %face_ndir = (
+ A => [ 1, 1, 1, 3],
+ B => [ 0, 0, 0, 0],
+ C => [ 0, 1, 2, 3],
+ D => [ 2, 2, 2, 2],
+ E => [ 3, 1, 3, 3],
+ F => [ 2, 1, 0, 3],
+);
+my %face_next = (
+ A => [ qw(D C B F) ],
+ B => [ qw(C E F A) ],
+ C => [ qw(D E B A) ],
+ D => [ qw(F E C A) ],
+ E => [ qw(D F B C) ],
+ F => [ qw(D A B E) ],
+);
+
+my %face_of;
+my %face_dir;
+if ($Y::AoC::Task::in_test) {
+ $dim = 4;
+ %face_of = (
+ '20' => 'A',
+ '11' => 'B',
+ '21' => 'C',
+ '32' => 'D',
+ '22' => 'E',
+ '01' => 'F',
+ );
+ %face_dir = (
+ A => 0,
+ B => 0,
+ C => 0,
+ D => 1,
+ E => 0,
+ F => 2,
+ );
+} else {
+ $dim = 50;
+ %face_of = (
+ '10' => 'A',
+ '02' => 'B',
+ '11' => 'C',
+ '20' => 'D',
+ '12' => 'E',
+ '03' => 'F',
+ );
+ %face_dir = (
+ A => 0,
+ B => 3,
+ C => 0,
+ D => 3,
+ E => 0,
+ F => 1,
+ );
+}
+
+
+my %pos_of = reverse %face_of;
+sub pos_of($face) {
+ return map { $dim * $_ } split //, $pos_of{$face};
+}
+
+sub face_of($x, $y) {
+ return undef if $x < 0 || $y < 0;
+ my $fx = int($x/$dim);
+ my $fy = int($y/$dim);
+ return $face_of{"$fx$fy"};
+}
+
+sub move($sx, $sy, $dir) {
+ my $f1 = face_of($sx, $sy);
+ my ($dx, $dy) = ($sx, $sy);
+ if ($dir == 0) {
+ $dx++;
+ } elsif ($dir == 1) {
+ $dy++;
+ } elsif ($dir == 2) {
+ $dx--;
+ } elsif ($dir == 3) {
+ $dy--;
+ }
+ my $f2 = face_of($dx, $dy);
+ if (defined($f2) && $f2 eq $f1) {
+ return ($dx, $dy, $dir);
+ }
+ my $ndir;
+ say "moving from $f1 $dir";
+ my $rdir = ($dir - $face_dir{$f1}) % 4;
+ say "rdir = $rdir";
+ $f2 = $face_next{$f1}[$rdir];
+ my $rdir2 = $face_ndir{$f1}[$rdir];
+ say "rdir2 = $rdir";
+ $ndir = ($rdir2 + $face_dir{$f2}) % 4;
+ my ($nx, $ny) = ($dx % $dim, $dy % $dim);
+ my $rot = ($ndir - $dir) % 4;
+ say "$sx,$sy $nx,$ny $f1 -> $f2 r$rot $dir -> $ndir";
+ while ($rot--) {
+ # ($nx, $ny) = ($ny, (-$nx % $dim));
+ ($nx, $ny) = ((($dim-1-$ny) % $dim), $nx);
+ say "rot -> $nx,$ny";
+ }
+ say " -> $nx $ny $ndir";
+ my ($ox, $oy) = pos_of($f2);
+ $nx += $ox;
+ $ny += $oy;
+ say " -> $nx $ny";
+ say "FACE $sx,$sy,$dir $f1 -> $nx,$ny,$ndir $f2";
+ die if $map[$ny][$nx] eq ' ';
+ return ($nx, $ny, $ndir);
+}
+
+while (length $list) {
+ $list =~ s/^(\d+|[LR])//;
+ my $move = $1;
+ say "$x $y $dir $move";
+ if ($move =~ /\d+/) {
+ while ($move) {
+ my ($dx, $dy, $ddir) = move($x, $y, $dir);
+ last if $map[$dy][$dx] eq '#';
+ $x = $dx; $y = $dy; $dir = $ddir;
+ say " $x $y $dir $move";
+ $move--;
+ }
+ } elsif ($move eq 'L') {
+ $dir = 3 if --$dir < 0;
+ } elsif ($move eq 'R') {
+ $dir = 0 if ++$dir > 3;
+ }
+}
+
+say 1000*($y+1) + 4*($x+1) + $dir;