X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?p=aoc2020.git;a=blobdiff_plain;f=39.pl;h=40f98aba42571768747e64f5b655efb383fdacf3;hp=2b88a89ba862f94b3b7d1267bd36299596503aa5;hb=HEAD;hpb=3dcbc8cbbed0a020192974ba29b73f0164b49ce2 diff --git a/39.pl b/39.pl index 2b88a89..40f98ab 100755 --- 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";