]> www.fi.muni.cz Git - aoc.git/blob - 2017/42.pl
Day 25: examining the input
[aoc.git] / 2017 / 42.pl
1 #!/usr/bin/perl
2
3 use v5.30;
4 use strict;
5
6 my $start = '.#...####';
7
8 sub rotate2 {
9         my ($x) = @_;
10         my @x = split //, $x;
11         my $rv = join('', @x[2, 0, 3, 1]);
12         return $rv;
13 }
14
15 sub rev {
16         my ($str) = @_;
17         my $rlen = length($str) == 4 ? 2 : 3;
18         my (@comps) = $str =~ /(.{$rlen})/g;
19         return join('', map { join('', reverse split(//, $_)) } @comps);
20 }
21
22 say "rev(.#.#) = ", rev('.#.#');
23
24 sub rotate3 {
25         my ($x) = @_;
26         my @x = split //, $x;
27         my $rv = join('', @x[qw(6 3 0 7 4 1 8 5 2)]);
28         return $rv;
29 }
30
31 sub split4 {
32         my ($x) = @_;
33         my @x = split //, $x;
34         my @rv;
35         for my $str (
36                 join('', @x[qw(0 1 4 5)]),
37                 join('', @x[qw(2 3 6 7)]),
38                 join('', @x[qw(8 9 12 13)]),
39                 join('', @x[qw(10 11 14 15)]),
40         ) {
41                 push @rv, $str;
42         }
43         return @rv;
44 }
45
46 sub join6 {
47         my ($s1, $s2, $s3, $s4) = @_;
48         return    substr($s1, 0, 3) . substr($s2, 0, 3)
49                 . substr($s1, 3, 3) . substr($s2, 3, 3)
50                 . substr($s1, 6, 3) . substr($s2, 6, 3)
51                 . substr($s3, 0, 3) . substr($s4, 0, 3)
52                 . substr($s3, 3, 3) . substr($s4, 3, 3)
53                 . substr($s3, 6, 3) . substr($s4, 6, 3)
54 }
55
56 sub split6 {
57         my ($x) = @_;
58         my @x = split //, $x;
59         return (
60                 join('', @x[qw(0 1 6 7)]),
61                 join('', @x[qw(2 3 8 9)]),
62                 join('', @x[qw(4 5 10 11)]),
63                 join('', @x[qw(12 13 18 19)]),
64                 join('', @x[qw(14 15 20 21)]),
65                 join('', @x[qw(16 17 22 23)]),
66                 join('', @x[qw(24 25 30 31)]),
67                 join('', @x[qw(26 27 32 33)]),
68                 join('', @x[qw(28 29 34 35)]),
69         );
70 }
71
72 my %rules;
73 while (<>) {
74         chomp;
75         my ($src, $dst) = split / => /;
76         $src =~ s/\///g;
77         $dst =~ s/\///g;
78         for (0 .. 3) {
79                 $rules{$src} = $dst;
80                 my $rev = rev($src);
81                 $rules{$rev} = $dst;
82                 if (length $src == 4) {
83                         $src = rotate2($src);
84                 } else {
85                         $src = rotate3($src);
86                 }
87         }
88 }
89
90 my %state = ($start => 1);
91 my $size = 3;
92 for my $step (0 .. 17) {
93         my %nstate;
94         my $part = $step % 3;
95         $size = ($part == 0) ? 4*$size/3 : 3*$size/2;
96         for my $str (keys %state) {
97                 if ($part == 0) { # 3 to 4
98                         my $nstr = $rules{$str};
99                         $nstate{$nstr} += $state{$str};
100                 } elsif ($part == 1) { # 4 to 6
101                         my @rs;
102                         for my $ns (split4($str)) {
103                                 push @rs, $rules{$ns};
104                         }
105                         my $nstr = join6(@rs);
106                         $nstate{$nstr} += $state{$str};
107                 } else { # 6 to 3x3 x 2x2 to 3x3 x 3x3
108                         for my $ns (split6($str)) {
109                                 my $ns1 = $rules{$ns};
110                                 say "--> $ns => $ns1";
111                                 $nstate{$ns1} += $state{$str};
112                         }
113                 }
114         }
115         say "$step/$part $size";
116         for my $str (keys %nstate) {
117                 say $str, ' ', length($str), ' ', $nstate{$str};
118         }
119         say "";
120         %state = %nstate;
121 }
122
123 my $sum;
124 for my $str (keys %state) {
125         my $count = () = $str =~ /#/g;
126         say "$str $state{$str} $count";
127         $sum += $state{$str}*$count;
128 }
129
130 say $sum;
131
132