]> www.fi.muni.cz Git - aoc2020.git/commitdiff
39.pl cleaner version
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Sun, 20 Dec 2020 16:29:40 +0000 (17:29 +0100)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Sun, 20 Dec 2020 16:29:40 +0000 (17:29 +0100)
39.pl

diff --git a/39.pl b/39.pl
index 2b88a89ba862f94b3b7d1267bd36299596503aa5..40f98aba42571768747e64f5b655efb383fdacf3 100755 (executable)
--- a/39.pl
+++ b/39.pl
@@ -2,74 +2,56 @@
 
 use strict;
 
-local $/ = "\n\n";
+sub rows2str {
+       my (@rows) = @_;
+       return join("\n", @rows) . "\n";
+}
+
+sub rotate {
+       my ($str) = (@_);
+       my $dim =()= $str =~ /(\n)/g;
+       my $newstr = '';
+       for my $y (0 .. $dim-1) {
+               for my $x (0 .. $dim-1) {
+                       $newstr .= substr($str, $y + ($dim+1)*($dim - $x - 1), 1);
+               }
+               $newstr .= "\n";
+       }
+       return $newstr;
+}
+
+sub flip {
+       my ($str) = @_;
+       return rows2str(map { join('', reverse split //) } split /\n/, $str);
+}
 
-sub invbits {
-       my ($in) = @_;
-       return (($in & 1) << 9)
-               | (($in & 2) << 7)
-               | (($in & 4) << 5)
-               | (($in & 8) << 3)
-               | (($in & 16) << 1)
-               | (($in & 32) >> 1)
-               | (($in & 64) >> 3)
-               | (($in & 128) >> 5)
-               | (($in & 256) >> 7)
-               | (($in & 512) >> 9);
+sub rotate_or_flip {
+       my ($str, $count) = @_;
+       return $count == 4 ? flip($str) : rotate($str);
 }
 
-my %tiles;
-my %sides;
-my %side2tiles;
+sub top_side {
+       $_[0] =~ /\A(.*?)\n/xms;
+       return $1;
+}
+
+my %top2tile;
+
+local $/ = "\n\n";
+
 while (<>) {
-       my ($id, @rows) = split /\n/;
-       $id =~ s/Tile //;
-       $id =~ s/://;
-       @rows = map { y/#./10/; oct "0b$_" } @rows;
-       $tiles{$id} = \@rows;
-       $sides{$id} = [
-               $rows[0],
-               (($rows[0] & 1) << 9)
-               | (($rows[1] & 1) << 8)
-               | (($rows[2] & 1) << 7)
-               | (($rows[3] & 1) << 6)
-               | (($rows[4] & 1) << 5)
-               | (($rows[5] & 1) << 4)
-               | (($rows[6] & 1) << 3)
-               | (($rows[7] & 1) << 2)
-               | (($rows[8] & 1) << 1)
-               | (($rows[9] & 1) << 0),
-               $rows[9],
-               (($rows[0] & 512) >> 0)
-               | (($rows[1] & 512) >> 1)
-               | (($rows[2] & 512) >> 2)
-               | (($rows[3] & 512) >> 3)
-               | (($rows[4] & 512) >> 4)
-               | (($rows[5] & 512) >> 5)
-               | (($rows[6] & 512) >> 6)
-               | (($rows[7] & 512) >> 7)
-               | (($rows[8] & 512) >> 8)
-               | (($rows[9] & 512) >> 9),
-       ];
-       print "Tile <$id> sides ", join(',', @{ $sides{$id} }), "\n";
-       for my $side (@{ $sides{$id} }) {
-               push @{ $side2tiles{$side} }, $id;
-               push @{ $side2tiles{invbits($side)} }, $id;
+       my ($id, $data) = /\ATile\s+(\d+):\n(.*?\n)\n?\z/xms;
+       for (1 .. 8) {
+               push @{ $top2tile{top_side($data)} }, $id;
+               $data = rotate_or_flip($data, $_);
        }
 }
 
 my %single_ids;
-for my $side (keys %side2tiles) {
-       print "side $side: ", join(',', @{ $side2tiles{$side} }), "\n";
-       # print "inv  ", invbits($side), "\n";
-       if (scalar @{ $side2tiles{$side} } == 1
-               && scalar @{ $side2tiles{invbits($side)} } == 1) {
-               print "side $side of tile $side2tiles{$side}->[0] is single\n";
-               $single_ids{$side2tiles{$side}->[0]}++;
-       }
-       
+for my $row (keys %top2tile) {
+       next if @{ $top2tile{$row} } != 1;
+       $single_ids{ $top2tile{$row}->[0] }++;
 }
 
 my @corners = grep { $single_ids{$_} == 4 } keys %single_ids;
-print join('*', @corners), '=', eval join('*', @corners), "\n"
-
+print join('*', @corners), '=', eval join('*', @corners), "\n";