]> www.fi.muni.cz Git - aoc2020.git/blob - 40.pl
Day 20: manual coding, coding, coding
[aoc2020.git] / 40.pl
1 #!/usr/bin/perl -w
2
3 use strict;
4
5 local $/ = "\n\n";
6
7 sub rev {
8         my ($in) = @_;
9         return join('', reverse split //, $in);
10 }
11
12
13 my %tiles;
14 my %sides;
15 my %side2tiles;
16 while (<>) {
17         my ($id, @rows) = split /\n/;
18         $id =~ s/Tile //;
19         $id =~ s/://;
20         $tiles{$id} = \@rows;
21         $sides{$id} = [
22                 $rows[0],
23                 join('', map { substr($_, -1, 1) } @rows),
24                 rev($rows[-1]),
25                 rev(join('', map { substr($_, 0, 1) } @rows)),
26         ];
27         print "Tile <$id> sides ", join(' ', @{ $sides{$id} }), "\n";
28         my $i = 0;
29         for my $side (@{ $sides{$id} }) {
30                 $side2tiles{$side}->{$id} = $i;
31                 $side2tiles{rev($side)}->{$id} = $i+4;
32                 $i++;
33         }
34 }
35
36 my $dim = 12;
37 my $next = '###.#.#...';
38
39 # my $dim = 3;
40 # my $next = '#...##.#..';
41 my $next_id = -1;
42 my $map;
43 my %seen;
44
45 for my $y (0 .. $dim-1) {
46         my ($id) = grep { $_ != $next_id } keys %{ $side2tiles{$next} };
47         my $side = $side2tiles{$next}->{$id};
48         $map->[$y][0] = [ $id, $side ];
49         die "$id seen again\n"
50                 if $seen{$id};
51         $seen{$id} = 1;
52         my $next_side = $side > 3
53                 ? (($side - 1) & 3)
54                 : ($side + 1) & 3;
55         $next = $sides{$id}->[$next_side];
56         $next = rev($next) if $side > 3;
57         my $top_side = $side;
58         print "id=$id, side=$side, next_side=$next_side, top_side=$top_side, next=|$next|\n";
59         $next_id = $id;
60         
61         for my $x (1 .. $dim-1) {
62                 ($id) = grep { $_ != $next_id } keys %{ $side2tiles{$next} };
63                 $side = $side2tiles{$next}->{$id};
64                 die "$id seen again\n"
65                         if $seen{$id};
66                 $seen{$id} = 1;
67                 my $top_side = ((($side & 3) + (($side >> 2) ? 1 : -1)) & 3) | (($side & 4) ^ 4);
68                 $map->[$y][$x] = [ $id, $top_side ];
69                 $next_side = (($side + 2) & 3);
70                 $next = $sides{$id}->[$next_side];
71                 $next = rev($next) if $side < 4;
72                 $next_id = $id;
73                 print "id=$id, side=$side, next_side=$next_side, top_side=$top_side, next=|$next|\n";
74         }
75
76         print "\n";
77
78         ($next_id, $next_side) = @{ $map->[$y][0] };
79         $next = $sides{$next_id}->[($next_side + 2) & 3];
80         $next = rev($next) if $next_side < 4;
81         print "bottom side of $next_id = |$next|\n";
82 }
83
84 my $shortmap = '';
85 for my $y (0 .. 8*$dim-1) {
86         my $y1 = 1 + ($y % 8);
87         for my $x (0 .. 8*$dim-1) {
88                 my $x1 = 1 + ($x % 8);
89                 my ($id, $or) = @{ $map->[int($y/8)][int($x/8)] };
90                 my ($x2, $y2) = ($x1, $y1);
91                 if ($or == 1) {
92                         ($x2, $y2) = (9-$y1, $x1);
93                 } elsif ($or == 2) {
94                         ($x2, $y2) = (9-$x1, 9-$y1);
95                 } elsif ($or == 3) {
96                         ($x2, $y2) = ($y1, 9-$x1);
97                 } elsif ($or == 4) {
98                         ($x2, $y2) = (9-$x1, $y1);
99                 } elsif ($or == 5) {
100                         ($x2, $y2) = (9-$y1, 9-$x1);
101                 } elsif ($or == 6) {
102                         ($x2, $y2) = ($x1, 9-$y1);
103                 } elsif ($or == 7) {
104                         ($x2, $y2) = ($y1, $x1);
105                 }
106                 $shortmap .= substr($tiles{$id}->[$y2], $x2, 1);
107         }
108         $shortmap .= "\n";
109 }
110
111 print join("\n", $shortmap), "\n";
112
113 my $monster = join('[\.#\n]' x ($dim * 8 - 20 + 1), map { $a=$_; $a=~ s/\./[\.#]/g; $a } 
114          '..................#.',
115         '#....##....##....###',
116         '.#..#..#..#..#..#...'
117 );
118
119 $monster = ".(?=$monster)";
120 print "monster=$monster\n";
121
122 for (1 .. 2) {
123         for (1 .. 4) {
124                 my $count;
125                 if (my $count =()= $shortmap =~ /($monster)/g) {
126                         print "$count matches\n";
127                         my $hashes =()= $shortmap =~ /#/g;
128                         print "$hashes-$count*15=", $hashes-$count*15, "\n";
129                         exit 0;
130                 }
131                 my $newmap = '';
132                 for my $y (0 .. 8*$dim-1) {
133                         for my $x (0 .. 8*$dim-1) {
134                                 print "$x,$y\n";
135                                 $newmap .= substr($shortmap,
136                                         $y + (8*$dim+1)*(8*$dim-$x-1), 1);
137                         }
138                         $newmap .= "\n";
139                 }
140                 print "\nRotate:\n$newmap\n";
141                 $shortmap = $newmap;
142         }
143         my $newmap;
144         for my $y (0 .. 8*$dim-1) {
145                 for my $x (0 .. 8*$dim-1) {
146                         $newmap .= substr($shortmap,
147                                 $x + (8*$dim+1)*(8*$dim-$y-1), 1);
148                 }
149                 $newmap .= "\n";
150         }
151         $shortmap = $newmap;
152         print "\nFlip:\n$newmap\n";
153
154 }
155
156                 
157
158