]> www.fi.muni.cz Git - aoc2020.git/blobdiff - 40.pl
Day 20: manual coding, coding, coding
[aoc2020.git] / 40.pl
diff --git a/40.pl b/40.pl
new file mode 100755 (executable)
index 0000000..df479d9
--- /dev/null
+++ b/40.pl
@@ -0,0 +1,158 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+local $/ = "\n\n";
+
+sub rev {
+       my ($in) = @_;
+       return join('', reverse split //, $in);
+}
+
+
+my %tiles;
+my %sides;
+my %side2tiles;
+while (<>) {
+       my ($id, @rows) = split /\n/;
+       $id =~ s/Tile //;
+       $id =~ s/://;
+       $tiles{$id} = \@rows;
+       $sides{$id} = [
+               $rows[0],
+               join('', map { substr($_, -1, 1) } @rows),
+               rev($rows[-1]),
+               rev(join('', map { substr($_, 0, 1) } @rows)),
+       ];
+       print "Tile <$id> sides ", join(' ', @{ $sides{$id} }), "\n";
+       my $i = 0;
+       for my $side (@{ $sides{$id} }) {
+               $side2tiles{$side}->{$id} = $i;
+               $side2tiles{rev($side)}->{$id} = $i+4;
+               $i++;
+       }
+}
+
+my $dim = 12;
+my $next = '###.#.#...';
+
+# my $dim = 3;
+# my $next = '#...##.#..';
+my $next_id = -1;
+my $map;
+my %seen;
+
+for my $y (0 .. $dim-1) {
+       my ($id) = grep { $_ != $next_id } keys %{ $side2tiles{$next} };
+       my $side = $side2tiles{$next}->{$id};
+       $map->[$y][0] = [ $id, $side ];
+       die "$id seen again\n"
+               if $seen{$id};
+       $seen{$id} = 1;
+       my $next_side = $side > 3
+               ? (($side - 1) & 3)
+               : ($side + 1) & 3;
+       $next = $sides{$id}->[$next_side];
+       $next = rev($next) if $side > 3;
+       my $top_side = $side;
+       print "id=$id, side=$side, next_side=$next_side, top_side=$top_side, next=|$next|\n";
+       $next_id = $id;
+       
+       for my $x (1 .. $dim-1) {
+               ($id) = grep { $_ != $next_id } keys %{ $side2tiles{$next} };
+               $side = $side2tiles{$next}->{$id};
+               die "$id seen again\n"
+                       if $seen{$id};
+               $seen{$id} = 1;
+               my $top_side = ((($side & 3) + (($side >> 2) ? 1 : -1)) & 3) | (($side & 4) ^ 4);
+               $map->[$y][$x] = [ $id, $top_side ];
+               $next_side = (($side + 2) & 3);
+               $next = $sides{$id}->[$next_side];
+               $next = rev($next) if $side < 4;
+               $next_id = $id;
+               print "id=$id, side=$side, next_side=$next_side, top_side=$top_side, next=|$next|\n";
+       }
+
+       print "\n";
+
+       ($next_id, $next_side) = @{ $map->[$y][0] };
+       $next = $sides{$next_id}->[($next_side + 2) & 3];
+       $next = rev($next) if $next_side < 4;
+       print "bottom side of $next_id = |$next|\n";
+}
+
+my $shortmap = '';
+for my $y (0 .. 8*$dim-1) {
+       my $y1 = 1 + ($y % 8);
+       for my $x (0 .. 8*$dim-1) {
+               my $x1 = 1 + ($x % 8);
+               my ($id, $or) = @{ $map->[int($y/8)][int($x/8)] };
+               my ($x2, $y2) = ($x1, $y1);
+               if ($or == 1) {
+                       ($x2, $y2) = (9-$y1, $x1);
+               } elsif ($or == 2) {
+                       ($x2, $y2) = (9-$x1, 9-$y1);
+               } elsif ($or == 3) {
+                       ($x2, $y2) = ($y1, 9-$x1);
+               } elsif ($or == 4) {
+                       ($x2, $y2) = (9-$x1, $y1);
+               } elsif ($or == 5) {
+                       ($x2, $y2) = (9-$y1, 9-$x1);
+               } elsif ($or == 6) {
+                       ($x2, $y2) = ($x1, 9-$y1);
+               } elsif ($or == 7) {
+                       ($x2, $y2) = ($y1, $x1);
+               }
+               $shortmap .= substr($tiles{$id}->[$y2], $x2, 1);
+       }
+       $shortmap .= "\n";
+}
+
+print join("\n", $shortmap), "\n";
+
+my $monster = join('[\.#\n]' x ($dim * 8 - 20 + 1), map { $a=$_; $a=~ s/\./[\.#]/g; $a } 
+        '..................#.',
+       '#....##....##....###',
+       '.#..#..#..#..#..#...'
+);
+
+$monster = ".(?=$monster)";
+print "monster=$monster\n";
+
+for (1 .. 2) {
+       for (1 .. 4) {
+               my $count;
+               if (my $count =()= $shortmap =~ /($monster)/g) {
+                       print "$count matches\n";
+                       my $hashes =()= $shortmap =~ /#/g;
+                       print "$hashes-$count*15=", $hashes-$count*15, "\n";
+                       exit 0;
+               }
+               my $newmap = '';
+               for my $y (0 .. 8*$dim-1) {
+                       for my $x (0 .. 8*$dim-1) {
+                               print "$x,$y\n";
+                               $newmap .= substr($shortmap,
+                                       $y + (8*$dim+1)*(8*$dim-$x-1), 1);
+                       }
+                       $newmap .= "\n";
+               }
+               print "\nRotate:\n$newmap\n";
+               $shortmap = $newmap;
+       }
+       my $newmap;
+       for my $y (0 .. 8*$dim-1) {
+               for my $x (0 .. 8*$dim-1) {
+                       $newmap .= substr($shortmap,
+                               $x + (8*$dim+1)*(8*$dim-$y-1), 1);
+               }
+               $newmap .= "\n";
+       }
+       $shortmap = $newmap;
+       print "\nFlip:\n$newmap\n";
+
+}
+
+               
+
+