#!/usr/bin/perl

use v5.30;
use strict;

my $start = '.#...####';

sub rotate2 {
	my ($x) = @_;
	my @x = split //, $x;
	my $rv = join('', @x[2, 0, 3, 1]);
	return $rv;
}

sub rev {
	my ($str) = @_;
	my $rlen = length($str) == 4 ? 2 : 3;
	my (@comps) = $str =~ /(.{$rlen})/g;
	return join('', map { join('', reverse split(//, $_)) } @comps);
}

say "rev(.#.#) = ", rev('.#.#');

sub rotate3 {
	my ($x) = @_;
	my @x = split //, $x;
	my $rv = join('', @x[qw(6 3 0 7 4 1 8 5 2)]);
	return $rv;
}

sub split4 {
	my ($x) = @_;
	my @x = split //, $x;
	my @rv;
	for my $str (
		join('', @x[qw(0 1 4 5)]),
		join('', @x[qw(2 3 6 7)]),
		join('', @x[qw(8 9 12 13)]),
		join('', @x[qw(10 11 14 15)]),
	) {
		push @rv, $str;
	}
	return @rv;
}

sub join6 {
	my ($s1, $s2, $s3, $s4) = @_;
	return    substr($s1, 0, 3) . substr($s2, 0, 3)
		. substr($s1, 3, 3) . substr($s2, 3, 3)
		. substr($s1, 6, 3) . substr($s2, 6, 3)
		. substr($s3, 0, 3) . substr($s4, 0, 3)
		. substr($s3, 3, 3) . substr($s4, 3, 3)
		. substr($s3, 6, 3) . substr($s4, 6, 3)
}

sub split6 {
	my ($x) = @_;
	my @x = split //, $x;
	return (
		join('', @x[qw(0 1 6 7)]),
		join('', @x[qw(2 3 8 9)]),
		join('', @x[qw(4 5 10 11)]),
		join('', @x[qw(12 13 18 19)]),
		join('', @x[qw(14 15 20 21)]),
		join('', @x[qw(16 17 22 23)]),
		join('', @x[qw(24 25 30 31)]),
		join('', @x[qw(26 27 32 33)]),
		join('', @x[qw(28 29 34 35)]),
	);
}

my %rules;
while (<>) {
	chomp;
	my ($src, $dst) = split / => /;
	$src =~ s/\///g;
	$dst =~ s/\///g;
	for (0 .. 3) {
		$rules{$src} = $dst;
		my $rev = rev($src);
		$rules{$rev} = $dst;
		if (length $src == 4) {
			$src = rotate2($src);
		} else {
			$src = rotate3($src);
		}
	}
}

my %state = ($start => 1);
my $size = 3;
for my $step (0 .. 4) {
	my %nstate;
	my $part = $step % 3;
	$size = ($part == 0) ? 4*$size/3 : 3*$size/2;
	for my $str (keys %state) {
		if ($part == 0) { # 3 to 4
			my $nstr = $rules{$str};
			$nstate{$nstr} += $state{$str};
		} elsif ($part == 1) { # 4 to 6
			my @rs;
			for my $ns (split4($str)) {
				push @rs, $rules{$ns};
			}
			my $nstr = join6(@rs);
			$nstate{$nstr} += $state{$str};
		} else { # 6 to 3x3 x 2x2 to 3x3 x 3x3
			for my $ns (split6($str)) {
				my $ns1 = $rules{$ns};
				say "--> $ns => $ns1";
				$nstate{$ns1} += $state{$str};
			}
		}
	}
	say "$step/$part $size";
	for my $str (keys %nstate) {
		say $str, ' ', length($str), ' ', $nstate{$str};
	}
	say "";
	%state = %nstate;
}

my $sum;
for my $str (keys %state) {
	my $count = () = $str =~ /#/g;
	say "$str $state{$str} $count";
	$sum += $state{$str}*$count;
}

say $sum;


