]> www.fi.muni.cz Git - aoc.git/blobdiff - 2017/41.pl
The rest of Year 2017
[aoc.git] / 2017 / 41.pl
diff --git a/2017/41.pl b/2017/41.pl
new file mode 100755 (executable)
index 0000000..c197c2b
--- /dev/null
@@ -0,0 +1,132 @@
+#!/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;
+
+