From c20162af8a801503e9810bfbd0bea6c64272c3d6 Mon Sep 17 00:00:00 2001 From: "Jan \"Yenya\" Kasprzak" Date: Sat, 24 Dec 2022 07:23:56 +0100 Subject: [PATCH] Day 22: cube --- 2022/43.pl | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2022/44.pl | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 298 insertions(+) create mode 100755 2022/43.pl create mode 100755 2022/44.pl diff --git a/2022/43.pl b/2022/43.pl new file mode 100755 index 0000000..ee6ade3 --- /dev/null +++ b/2022/43.pl @@ -0,0 +1,149 @@ +#!/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; diff --git a/2022/44.pl b/2022/44.pl new file mode 100755 index 0000000..ee6ade3 --- /dev/null +++ b/2022/44.pl @@ -0,0 +1,149 @@ +#!/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; -- 2.43.0