#!/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";

}

		


