--- /dev/null
+#!/usr/bin/perl -w
+
+use strict;
+
+local $/ = "\n\n";
+
+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);
+}
+
+my %tiles;
+my %sides;
+my %side2tiles;
+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 %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]}++;
+ }
+
+}
+
+my @corners = grep { $single_ids{$_} == 4 } keys %single_ids;
+print join('*', @corners), '=', eval join('*', @corners), "\n"
+
--- /dev/null
+#!/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";
+
+}
+
+
+
+