-
Notifications
You must be signed in to change notification settings - Fork 0
/
20.rs
179 lines (156 loc) · 24.7 KB
/
20.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
use std::collections::*;
use itertools::Itertools;
static IMAGES: [(usize, [&str;10]); 144] = [(3583,[".##..#..#.","....##....","##..#..#..",".....#....",".#..#.....","#.#.......","#.....#..#","....#....#","...#.##.#.",".#....##.#"]),(3967,["..###..#..","#.........",".........#","#...#....#","....#....#","#...#....#","#..#...#.#","##....##..","#....#....","##.###.#.."]),(3307,[".#.#...#..","......#..#",".........#","##.....##.","..#.....#.",".#...####.","#....#.#.#","......##.#","#.##.#..##",".....#.##."]),(1741,[".##..#.#..","#..##.#...",".#.....#..","...####.##","#.#..###..","####.#....","..#.##.#..","#.....#.#.","#.###.....","####...###"]),(3821,[".#######.#","...#......","#.##.#...#",".#...#####","....#.##..","#.#.#.....","##......##","#..#.....#","##..#..#.#","###..#.#.."]),(1787,["..##.#.###","...##..#.#","#..#.###.#","..#.##..#.","#.#.....##","...#...#.#","#..##..#.#","##.#.##..#","...#..#...","..#..##..."]),(2281,["..#.#.##.#",".......##.","..#..#..#.","....#.#..#","#...#.##.#","#..#.##.#.","#.#....#.#","#....##...",".....#..##","...#.#...#"]),(3593,["...#..#..#",".........#",".........#","#.#..#...#","##......##","##........","...#.#...#","#...#...##","...#.#.#..","#..#......"]),(3259,[".####.....","....#.#.##","#....#..##","#........#",".....#....",".#.....#.#","...##....#","#.....#.#.","#.#..#....","#.#..##.#."]),(2663,[".####..###","#.#..##...","#..#...#..","#..#....#.","..#.##...#",".#....#.#.","#..#....#.","#.#.......",".#.#......","..#..#####"]),(3833,["####....#.",".......#.#",".#........","#...#.##.#","#.##.#.#.#","...#.....#","##...#...#","#.#.##...#","##.#.#.##.",".##.###.##"]),(3373,["#.....##.#","#...###..#","..#.#..#..","####..#.##","#...#.##.#","#..##.#...","#..##...##","#.####....","##..#...#.","##.##.#.##"]),(1511,[".#.###...#","#....#...#",".##.#.....","...##.###.","#.##.##..#","####.#..##","#..#.#....","#.......#.","#......#.#","###...#..."]),(1723,["...##..#.#","..#..#...#",".##.....#.","#..#......",".#..#.#..#",".#........","...#.#..##","##.......#","..#..###..","#####...##"]),(1543,["#..#.##.##","#.....#..#",".....#.#.#","###.......","...##....#","..#..#...#","#.....##.#","#.#..##.##","...###....","###.#...#."]),(1433,["##.##..##.","###....#.#","..#.....##",".#.##..#..",".#.#...###","#.#.....#.","..##.....#","#....#....","..#.#...#.",".#...#####"]),(1949,["#.#..##..#",".........#",".#.......#","#..##..###","........##","#........#",".....#...#","...####.#.",".#...##...","###.#.#..#"]),(3889,["###...####","#....##..#",".#.###...#","##..#.....",".....#....","....#.#.#.",".........#","#....##..#","##.##..##.","#.###.####"]),(2477,[".....#..##","#.##.###..","###..#...#",".#....#.#.","#..#......","...#.....#","##.....#..","..##.....#",".##.#....#","#####.####"]),(2137,["..########","#..#......","...#.##..#","#.#..#...#",".#..#...##","##.....#.#",".#....##..",".##.......",".#..####..","#..###...#"]),(3313,["..####.#.#","#..#.....#","#....#....","..##..##..","#....##...","..........","#.........",".......###","##........",".###...###"]),(1493,["#..####.##","##.#..#...","#.#.....##",".##......#",".##...#..#","#..##....#","#.#.#.#.#.","#.#...#..#","#.#.#....#","#.####...#"]),(1579,[".##..##.##","#.#.......",".......#..","..#...##..","#..####...",".#.#.##.##","###.#.....","#....##.##","....#...##","##....#.#."]),(2221,[".#.#......",".......##.","#..#.#...#","..###.###.","....#...##","##.#..##..","..##.#.#..","......####","..##.#.#..",".###..#.##"]),(3643,["..###...#.","#..#..#..#",".##.......","#..###....","##...##.##","#...#...#.","###......#","....#..#.#",".#.#.....#","..#..#.#.."]),(3881,["###.##.##.",".####..###","#.###..##.","....#...#.","##...#..#.","#........#","....#...#.","...#.....#",".#.....##.",".####..#.#"]),(3823,["..#.##..##","#...#....#","..#...#...","#.#.##...#",".####....#",".#...#...#","..........",".........#","...#..#...","....#..#.#"]),(3181,["####..##.#","#.....##.#","#.......##",".......#.#","..#..##.#.","##..#..#..","...##.....",".........#","....#.##..",".##.###.#."]),(2837,[".###.#.###","#.##..#.##",".....##...","###......#","##.......#","........##","##.##..#..","....###...","..........","#......#.#"]),(2063,["..#####...","..........","........#.","..##.....#","###...#.#.","#.#.....#.",".....#..##","#.......#.","##....##..","#.##.###.#"]),(1187,["#...##..##","#........#","#.#.......","...#.#....",".....#.#.#","#....#....","..###.....",".#........","..#...###.","####.#.#.#"]),(3137,["...###..#.","#.##.....#","..#...#..#","#..#.....#","......#...","#.....##.#","...#......","#.#.#.####","..#....#..",".#..#.#.##"]),(2411,["#.....##..",".......#.#",".....##...","#.#.......","#..##....#",".##.##....",".##...##..","#.#.......","##.....#.#",".##.###..."]),(2713,["..#.#.####","...####.#.","##..#...#.","#..##.....","#...#.....",".#...#.###","..........","#.#.##..#.","#.#..#..#.",".#..##.#.#"]),(1103,["##.#...##.","#.....##..","...###..#.","..##.....#",".####..#..","..#.###.#.","##.....#..",".#..#....#","#........#","####...##."]),(3943,[".###......","#...#.#...","..##..#..#",".##..#.#.#","..........","##...#....","#..#...#..","#..###...#","###....###","#.#....###"]),(1871,["##.#...##.","#......#..",".#.##.....",".#####.#..","#.#....#..","#..#....##","#..####.#.","#....#....","...#.....#","...#.##.#."]),(3407,["#.#.#####.","##.#..#..#",".###.#.#.#","..#.......","##.###.#..",".....#.###","#.#.......","##..#.#..#","#.#.##.#.#","#..#..###."]),(2441,["#####.#..#","...#.#....","..#...#..#",".##....#..","#.##..#...",".##.#..#.#","##.......#",".##..#....",".......#..",".#..#.###."]),(3637,[".#..##.#.#","...##..#..","#.#.###...","#....#...#","..#.....##","#....#...#","#..#.#.#..","....#..#.#","....#.#..#",".#.###.##."]),(1549,["....##.##.",".#....#...","..####.#..","....#.#..#","#........#","..#.......",".#.#....##","...######.","#...##....",".#...##..."]),(1481,["...##.##..","#...#.##..","#..#..#.#.","#.#.#...#.","#...#.##..",".##....#..","#........#","....#.#...","#.#.....##","#.....####"]),(1559,["#..#....#.","..#.##.#.#","#.....#.##",".###.#...#","..####..##","#..#.#..#.","#.#...###.","#.....#.#.",".#.....#..","#..####.#."]),(2251,["#..#.....#",".#..#.....","#.#....#..","#....##..#","##....#..#","..#..#....","#.#.#.#...","#...#....#","###..#.##.","##..#.####"]),(2897,["...###....","##..#....#",".........#",".#.......#","...#.....#","..#..#...#",".#...#...#","#....#....",".#......##","..##...##."]),(2239,["#..###..#.",".#.......#",".#..#..#..","#.##....##","#....#.#.#","##..#.....","#........#","...##.#..#","#...###..#","...#.#.###"]),(2593,[".#....##.#","##......##","..#..##...",".#..#.....","...#.#...#","#.#..#.#..","......#.#.","#...##...#","###..##..#","#.#####.##"]),(3697,["##.######.","###....#..","#.....##.#","##...#..##","#.....#..#",".#.#..#...","#......##.","#.#.#.#.#.",".........#","....####.."]),(3739,["##.#......",".#.....#.#","..#.....##","#....##...","##.#...#..","###.#...##",".#...#.###",".#..#.##.#","..#..#..#.","...#.##..."]),(2459,[".#.####...","#..#...#..",".....#.##.","..#....##.","#......##.","##...#..##","#....#....","###...#..#","###.##.###",".....##..."]),(2939,["##.#.#....","#..#.#####","#...###.#.","..#...#.##",".#.....##.","###....#..",".##...#..#",".....#.#..","..#..#....","..##..#.##"]),(2347,[".###..#..#","##......#.","#......#..","#...#....#","#......#..","##.......#","..#.......","#.##..#...","#..#..###.","#....##..#"]),(2381,["######....","##.......#",".#....###.","#.##.##.#.","#.#..#....",".........#","....#..#.#","#####.....","..##....##","#..###...#"]),(2503,["#.#...###.","#...#..#..",".##.#.#.##",".#.....#..","#...##....","##.#.....#","...#..#..#","..#.##...#","......#...","##..#..##."]),(3023,[".#...#....","#.##...#..","##....#...",".#..#.....",".#.#.....#","#.#.......","##..#.#.#.","#...#.#...","...#..#.##","#...##.###"]),(3851,["#..##.#.#.","#...#....#","###..#....","#.#.#...##","..#.#..#.#","#.......#.","..#.....##","..........","#.#.#.#..#","..#.##..#."]),(1009,[".####.##..","#.........",".#.#......","..#.#.....","#......##.","###.......","#.#.......",".......#.#",".#....#.##","#.####.#.#"]),(1151,[".#.##..#..","..#......#","##....##.#","#......###","##.....#..","##..#.#..#","...#......",".##...##..","##..###..#","######.###"]),(2683,["#..#.#..##",".#....#.#.","#...##....","....###...","...#..#...","..#.......","...#...#..","....#.#...","..#..#...#","..#.#.##.."]),(3323,["#.#..##.##","#.#....###","#.##.###.#","##....#...","##..#.....","###.#.#.##","#......#.#","..#....##.","#......#.#",".##...#..#"]),(2333,["##.#..#..#","#..##.....",".........#",".#.#.#....","#...##...#","#.#.#....#","..#.###..#","....###.#.","#...#....#","..#.....#."]),(2543,["#..###.#..","....#..#.#","..#...#.#.","#...##...#",".#.....###","..........","#..#....#.","#....#..#.","#.#..##..#","##...#..##"]),(1483,["###..##..#",".#......#.",".......#.#","#........#","...#...#.#","#.#.#.....","#......#.#","#...#.#...","#...####..","#.##..#..#"]),(2027,[".#..#....#","....##....","....#...##","#.#..#....","#.#.....##",".......#.#","#...#.....",".##....#.#","###.#.##.#",".###.#.###"]),(1699,["#.###..##.","..#.###...",".........#",".#.#..#..#","...##.##..","#........#",".......#.#","##..#...##",".....#....","#########."]),(2843,["#...#.####","....#.##..","...#....#.",".....#....","#..##.....",".....#....","###.#.....","......#..#","#.#.#...##","#...##.##."]),(1597,["#..#######","..........",".#........","#..##.#...","##.....#..","##.###...#",".....###.#","...##.#..#","#....#...#","##.#.#####"]),(2311,[".#.#.#.###",".#.......#","..#...#.##","#..#....##","#...#.....",".........#",".#.#...##.",".#.##....#","..#..#...#","...##.#.#."]),(1889,["#.###.###.",".#...#...#","#........#","#......#.#","..#......#","#......###",".....#.##.","#.....#..#","........##","####...#.#"]),(3581,["........##",".#...#...#","###.....#.","..........","#.#......#","......#..#","##........","..#...####","#..#......",".##.###.##"]),(1499,["##.#.#....",".##...##..","##.....##.","###.#...##","..##....#.",".#....#...","#..#...##.","..#....##.",".#.....#..","..#.####.#"]),(2999,[".#.###..#.","#.#...#...","##.#......","...#..#...","..###..###","...#.#..#.","#..##.#..#",".........#","..#....##.","..#.###.#."]),(1487,["#....#....",".#.....#..",".#.#.....#","#.#......#","#.#.##....","#.....#...",".....#....","##........","##..##...#","#.#..#...#"]),(2969,["#..#.#..##","###..#...#",".#..#.....","...####.#.","#.#.##..#.","...###...#","#...#.....","..#...##..","##..#.#..#","#..#.###.#"]),(1873,["..###.#.#.","..#.###.#.","#.#.##...#",".#...#...#","....#.....","##.....##.",".....#.#..","..#..#..#.","..##..#..#","##...#...."]),(2029,["#.#...####","#....##...",".#.#...##.","#####.#.#.","#..#......","#...#..#..","#.#.#..#.#","#......#.#","...####.#.","..##.#.###"]),(3517,[".##...##..",".#......#.","....##....","#.##..#..#",".......##.","#..#......","...##...#.","........##","#...#....#","..######.#"]),(2803,["#.##.###..",".#..##...#","...##.....",".#.#.#.#..","#.......#.",".##.#.#..#",".#.###.#..",".#..#...##","#...###...",".###..#.##"]),(1237,[".######.##","#.#.......","....#....#",".....#...#","#.###.#.##","#...####..","#.#......#","#.#.##.#.#","#..#..#...",".#..#....#"]),(3877,["..#.#.#.##","..##...#..","#..#...#..","#.......#.","#.......#.","#...#.##..",".#.......#","....#..###","##.......#",".#.##.#.#."]),(2081,["####.#####","....#..##.","........##","....#..##.","#..#....#.",".##...##..","......#...",".#....#..#","#.#.#...##",".##...##.#"]),(2789,[".#.##..#.#",".......#..","##.......#","..#..#..##","..#.......",".#........","#..##.#.#.","###.#..###","##..#...##","..#..#...."]),(3989,["##.##...##","#....#..#.",".#....#.##","#......#.#","#.#..#....","#....#.#.#","...#...#..","#........#",".......#.#","##.##.##.."]),(1933,[".....###.#","#...#.#..#",".#....#..#",".#........","#####.##..","#..#.#...#","#..#.#...#","....##....","#....#..#.","##..#..##."]),(1601,["##.#..##..",".#.###.#.#","..#.###..#","##.#.#....",".....###.#","##.##.####","#.#...#..#","#...##....","...#......",".####..###"]),(1117,["#..##..##.","......##.#","....##.#..","#....#....",".#.#.....#",".....#.##.","#....##...","#.....#...","..#..##.#.",".#.###.#.."]),(1409,["#...###...","#......#..","........#.",".#........","##....#...","#.......##","#......#..","......##.#","#..###.#..",".####.##.."]),(3359,["##.##....#","#..#...#.#","#....#####","...##..#..","..#..#...#","........##","...#...#.#",".........#","...#.#.#.#","##.#....##"]),(2539,["...##.##.#","#.##.#...#","...##.#...","..#.#..#..","#.#..#.###","......##.#","#.......#.",".#.......#","#...####..","..#...###."]),(1607,["##..###.#.","#...#....#","#.#.#..#..","#..#....##","#.#......#","....##....","#..###...#","..#.##..##","##....##.#","...##..###"]),(2971,["#....#..##",".##......#","#..##.....","#...##.##.","#...#.##..","....##...#","..#.###...","##.#.#..##","#..#..###.","#...###.##"]),(2447,["#..#..##.#","#....##..#",".....##...","..#.###..#","#..#.##...","#.#.#...##","#.#..###.#","####..#...","#.#...###.","#..###..##"]),(1709,[".....#..##","##....#...",".........#","...###..#.","###......#","..#..#...#","#.###.#..#","###....##.","...#..##.#","##.#...#.."]),(3109,[".#..###.##","....#.#.##","..#...#..#","#...#.....","####.#....",".#.#...###","###....#..","#..###....","..........","##.##...##"]),(2089,["..####..#.",".###.....#","....#..###",".#.......#","..##.....#","#.###....#","#.#.##.#.#","#.......#.","...#.##.#.","...#..#.##"]),(1619,["#...#.#.#.","#.........","#....##.##","##....#...","#####.....","##.#..#..#","###...#..#","...#......","##..#....#",".##.##...#"]),(3319,["###.#.#.#.",".#....#..#","#.#.#...##","...#.....#","..........","........#.","..........","...#.##..#","#.#.#....#","##......#."]),(1621,["#.###.###.",".#...#...#","#.#......#","#....#....","#..#.....#","##..#..#..",".###..#.#.","#.#.#.####","#.......##","##.##...#."]),(2857,["##.#.#.#..","...#...##.","#......#..","......#...",".#.#..#...",".##..#...#","..###....#","#.##......","#.###...##","..#..##.#."]),(2143,["#.#.......","#...#.##..","#..#.....#","...#.....#","#...#....#","........##","##....#.##","##..##..#.","#..#.....#","#..##....#"]),(3037,["........##","#....#..#.","......#...","....#.#...","...###.###","...###...#","..........","#.....#..#","##..#.....","#....#...."]),(1733,["#.#..#.#..",".#....##..","#..#.#...#","........#.",".........#","##....#...","#.....#..#","#..####.#.","#...##....","..#....##."]),(2657,[".##...#..#","#...#.##..","##........",".##......#",".#...#...#","..##...#..",".........#","....#...#.","..#.##...#","#..######."]),(1451,["#.....#..#",".....#.##.","......##..","..#.......","..........","#..##....#","###......#","##.#.....#","#...##.###","###.#....."]),(3191,["####.#.#.#",".........#","###.#####.","#.....##..","...#....#.","##..#....#",".#..#.#..#","#........#","######..#.",".####.####"]),(3163,[".#.##.#..#","##.##.#.#.","##..#....#",".#....#.#.","##.#.....#",".#........","#.#......#","#.......##","#........#","###...###."]),(3067,[".#...##...","..###.....","##.#..#..#","##.##..#..",".......#..","#...##.#..","####....#.","#.#....#..","........#.",".##.#....#"]),(3203,["##...#.#.#",".##..#####","#.......##",".#....#...",".#....#..#","..#.#....#","#....#.#..","#....#####","#...####..","....##.###"]),(3229,["...#......","#...#.....","..##.#.##.","#.#...#...","#.##.#..##","##....##..","..#.###..#",".....#...#","...#.....#","..#.#....."]),(2083,["....#.###.","..........",".........#","...##..#.#",".##..#....","#..#..#...","......#.#.","#........#","#.##......","###..#.###"]),(3253,[".##..#.#..",".#.#...#.#","#.#....#..","...#.....#","#.........","#.........",".##......#","......###.","#.........",".....#...#"]),(1381,["###...##.#","#.#####.#.","###..#..##","#.........","..#..#...#","..#.#...##",".#.#.....#","..#...##.#","##.#..#..#","######...."]),(2113,[".....##..#",".....###..","...#.....#","##.#..#...","....#.....","...#......","#..###.#.#","..........","#.#.......","..#..#.#.."]),(1087,["###..#.##.","#....#....","..#......#","###.#....#",".#.......#","..#....##.","#...#....#","....#...##","....#.#.#.","#.#..#.###"]),(2833,[".....#...#","#...#.#.#.","#.......#.","#......#.#",".#.##.#...","........##","....#.#.##","........##","......#.#.","######.#.."]),(1063,[".....###.#","#####.#..#","..###....#","...#.##...","###....#.#",".....##...","####.....#","..##.#....","#...#...#.","...##.###."]),(3049,["#.#.#..###","...##....#","#..#..#.#.","##.##..#..","###.....##","#.#..#.#..","#..##....#","#.#...#..#","##..#..#.#","....#####."]),(1657,["#..####...","........##",".........#","#...#.#...","#.#......#",".#.#....#.","#....###.#","#..####.#.","#..#..####","...###..#."]),(3863,["##.#######","..#.#.#...","#....#..#.","........##","#.##......","....#.....","#.#..##...","#.#......#","..#..#.#..","##.####..#"]),(3083,["##.#...###",".#..#..#..","#.#####...","#..#.#....","##.....#..","#..##..###",".#.#.....#","#.#..#..##",".#.#..#.##","...#......"]),(3853,["#.###..###","##..#..##.",".....##.##","......#..#","...#.#..#.","###....#..","##.....#..","##........","...#..#..#","###.###..#"]),(2129,["..#....#.#","#...#.....","##...##..#","#.#.......","....#.....","##......##","#..#......","#..#..#...","..........","...#.#.#.."]),(1759,["..##..###.",".......#..",".#.#.....#",".....#....","#......#.#","#.#......#","#..#.#.#.#","#..#.#...#","#.#...#..#",".##....#.#"]),(3617,["..#.#..###","..###....#","##.#.....#","#.##....##",".....#..#.",".........#","..........",".####..#.#","#.#...#.#.","....##.##."]),(2017,["..#.##.#.#","....#...##","..........",".#........","#.....#...","#.....#...","#.........","....#.#.#.","..#.......","..#...#.##"]),(1277,["..##...#.#",".##..#..#.",".#....##.#","#....##...","#..#.##..#","###..##..#",".........#",".##.#.....","..#.......","##.###.#.."]),(2617,["###.......","......#...","##.##..#..","#.#....#..",".###....##","..###..#.#","##...##..#","#..#......","#..#..####","#.##..#..."]),(2719,["..#.#.##.#","........##","...#.#....","...##....#",".#.##.#...","..#.##.###","##.#.....#",".........#","..#.#...##","###.#..###"]),(3671,["#..##..###","#...#...##","..........","...##.....",".#..#.#..#","#.#..#....","#..###.###","..##..####","#.........",".#..#.#..#"]),(3389,[".#....#.##",".#..##.#.#","#...##....","##....#..#","##......##",".#...#....","..#....#..","....##....","#.#...#.#.","#.#.#..###"]),(3457,[".#########","#..#......","..##......","#.........",".#...#....",".###.....#",".......#.#",".........#","###....#..","#.......##"]),(1777,["###.#.####","#..#...###",".#.#..#..#",".......#..","#.#..##.##","..###.....","###......#",".#........","#.####....","##..######"]),(3613,["####.#...#","##.......#",".......##.","#....#...#","......##.#","...#.#..##","#......#..","...#...#..",".##..##...",".#...#..#."]),(3529,[".#.##.#...","##.....#.#","#...#..#..","......##.#","##..#.##.#","##........","#.....#...","...#...#..","...##.#...","..###....."]),(1153,["##.##.##..","..#####..#","##...#..#.",".......###",".#.......#","..#.#.....",".......#.#","#...#..###",".....#.#..",".#.##....#"]),(2467,["####....##","#..###...#","#####....#",".#......#.","###.......","##.......#",".##.#.#..#","....#.#...","#........#",".#..#.####"]),(3947,["#.##.##.#.","##.......#","......#..#","#...#..###",".....#.###","##..#..#..","...#.#...#","#...#....#",".......#.#","#...#..#.#"]),(1399,[".##.#..###","#.......#.","#.......#.",".....#..#.","#........#","##..#..#.#",".##..##..#","#..#......","#.....#..#","#.##..##.."]),(2879,["....###..#","..#.......","#...#.....","...#.#....",".........#",".##..#.##.",".#...###.#",".#.....#.#","..##.....#","##...#.#.."]),(1039,["#......#.#","##.##.###.",".....##..#","#........#","..#.......","#.........",".#..#.#.#.",".....###..","#....#####",".#.....###"]),(2777,["#..##...#.","....#....#","........#.","##.#....#.","..#.##...#",".#....#.#.","#....#....","#..#.#...#","#...##.#.#","#.......#."]),(1097,["##...###..","..#..####.","##....#.##","#.....##..","...#....##",".##..#....","#.##..###.","##...#....","#.###....#",".#.#.###.."]),(3793,["####.....#","..........",".#.##.#...","....#....#","#.....#...","..###..##.","##..#.#...","##........","#........#",".###......"]),(2689,["####...#..","..##....##","#.#....#.#",".....##..#","#.......##","#.........","#.....#..#","##........",".......#.#","#.###..#.#"])];
const MONSTER: [&str; 3] = [
" # ",
"# ## ## ###",
" # # # # # # ",
];
type BorderMatches = HashMap<String, Vec<usize>>;
#[derive(Clone, Debug, Default)]
struct Tile {
v: Vec<Vec<char>>,
id: usize
}
impl Tile {
fn from_input(tile: &[&str], id: usize) -> Self {
Self {
v: tile.iter().map(|s| s.chars().collect()).collect(),
id,
}
}
fn get_edges(&self) -> (String,String) {
let (mut b1, mut b2) = (String::new(), String::new());
for i in 0..10 {
b1.push(self.v[i][0]);
b2.push(self.v[i][9]);
}
(b1,b2)
}
fn get_neighbour(&self, matches: &BorderMatches, n: usize) -> Option<usize> {
let matches = match n {
0 => &matches[&self.v[0].iter().copied().collect::<String>()],
1 => &matches[&self.get_edges().1],
2 => &matches[&self.v[9].iter().copied().collect::<String>()],
3 => &matches[&self.get_edges().0],
_ => unreachable!()
};
matches.iter().find(|&&id| id != self.id).copied()
}
fn rotate(&mut self) { self.v = rotate(&self.v) }
fn match_right(&self, matches: &BorderMatches, images: &HashMap<usize, [&str;10]>) -> Self {
let id = self.get_neighbour(matches, 1).unwrap();
let mut tile = Tile::from_input(&images[&id], id);
// rotate it to the correct position
while tile.get_neighbour(matches, 3) != Some(self.id) { tile.rotate() }
// if the edges match but aren't equal it must be flipped!
if (0..10).any(|i| self.v[i][9] != tile.v[i][0]) {
for i in 0..5 { tile.v.swap(i, 9 - i) }
}
tile
}
fn match_down(&self, matches: &BorderMatches, images: &HashMap<usize, [&str;10]>) -> Self {
let id = self.get_neighbour(matches, 2).unwrap();
let mut tile = Tile::from_input(&images[&id], id);
// rotate it to the correct position
while tile.get_neighbour(matches, 0) != Some(self.id) { tile.rotate() }
// if the edges match but aren't equal it must be flipped!
if self.v[9] != tile.v[0] {
for s in &mut tile.v { s.reverse() }
}
tile
}
}
fn rotate(v: &[Vec<char>]) -> Vec<Vec<char>> {
let (h,w) = (v.len(), v[0].len());
let mut rot = vec![vec!['\0'; w]; h];
for (i,j) in (0..h).cartesian_product(0..w) {
rot[j][w-1-i] = v[i][j];
}
rot
}
fn build_image(matches: &BorderMatches, corner: usize) -> Vec<Vec<char>> {
let images = IMAGES.iter().copied().collect::<HashMap<_,_>>();
// align the corner to fit in the top-left
let mut starting_corner = Tile::from_input(&images[&corner], corner);
while [0,3].iter().any(|&d| starting_corner.get_neighbour(matches, d).is_some()) {
starting_corner.rotate();
}
let mut image = vec![vec![Tile::default(); 12]; 12];
image[0][0] = starting_corner;
// match the first tile in each row to the one above
for i in 1..12 {
image[i][0] = image[i-1][0].match_down(matches, &images);
}
// for all other tiles match to the previous tile in the row
for (i,j) in (0..12).cartesian_product(1..12) {
image[i][j] = image[i][j-1].match_right(matches, &images);
}
// tiles are placed and rotated correctly, now build the actual image
let mut actual_image = vec![Vec::new(); 8 * 12];
for (i,j) in (0..12).cartesian_product(0..12) {
let tile = &image[i][j];
for k in 1..9 {
actual_image[i * 8 + (k-1)].extend(&tile.v[k][1..9]);
}
}
actual_image
}
fn find_monsters(image: &[Vec<char>], monster_coords: &HashSet<(isize,isize)>) -> usize {
let positions = image.iter()
.enumerate()
.flat_map(|(i,row)| row.iter()
.enumerate()
.filter(|&(_,&c)| c == '#')
.map(move |(j,_)| (i as isize, j as isize))
)
.collect::<HashSet<_>>();
positions.iter()
.filter(|(i,j)| monster_coords.iter()
.map(|(di,dj)| (i+di,j+dj))
.all(|pos| positions.contains(&pos))
)
.count()
}
fn part_two(matches: &BorderMatches, corner: usize) -> usize {
let monster_coords = MONSTER.iter()
.enumerate()
.flat_map(|(i,row)| row.chars()
.enumerate()
.filter(|&(_,c)| c == '#')
.map(move |(j,_)| (i as isize - 1, j as isize))
)
.collect::<HashSet<_>>();
let mut image = build_image(matches, corner);
let total = image.iter()
.flatten()
.filter(|&&c| c == '#')
.count();
loop {
match find_monsters(&image, &monster_coords) {
0 => image = rotate(&image),
m => return total - m * monster_coords.len(),
}
}
}
fn part_one(matches: &BorderMatches) -> usize {
let mut count_map = HashMap::new();
for ids in matches.values().filter(|ids| ids.len() == 1) {
*count_map.entry(ids[0]).or_insert(0) += 1;
}
count_map.iter()
.filter(|&(_, &c)| c == 4)
.map(|(id,_)| id)
.product()
}
aoc2020::main! {
let mut matches = HashMap::new();
for &(id,tile) in &IMAGES {
let (b1,b2) = Tile::from_input(&tile,id).get_edges();
for edge in &[tile[0], tile[9], &b1, &b2] {
matches.entry(edge.to_string()).or_insert(Vec::new()).push(id);
matches.entry(edge.chars().rev().collect()).or_insert(Vec::new()).push(id);
}
}
(part_one(&matches), part_two(&matches, 3833))
}