10 #define MAX 2187 // precomputed for 18 iterations
11 #define OUT_2 6 // 2x2 transformations: 6 among 16 (others by flip/rotate)
12 #define OUT_3 102 // 3x3 transformations: 102 among 512 (others by flip/rotate)
13 static unsigned short in2
[1 << 4];
14 static int in3
[1 << 9];
15 static char buf
[4000]; // sized based on wc output
16 static bool grid
[MAX
][MAX
];
19 main (int argc
, char **argv
)
21 // initial pattern is fixed
23 grid
[0][1] = grid
[1][2] = grid
[2][0] = grid
[2][1] = grid
[2][2] = true;
24 memset(in2
, -1, sizeof in2
);
25 memset(in3
, -1, sizeof in3
);
26 int iter
= 5, read2
= OUT_2
, read3
= OUT_3
;
28 iter
= atoi (argv
[1]);
30 read2
= atoi (argv
[2]);
32 read3
= atoi (argv
[3]);
34 unsigned short p_in
, p_out
;
36 i
= fread (buf
, 1, sizeof buf
, stdin
);
37 assert (i
> 0 && i
< sizeof buf
);
40 assert (p
[6] == '=' && p
[7] == '>' && p
[20] == '\n');
41 p_in
= (((p
[0] == '#') << 3) |
42 ((p
[1] == '#') << 2) |
43 ((p
[3] == '#') << 1) |
44 ((p
[4] == '#') << 0));
45 p_out
= (((p
[9] == '#') << 8) |
46 ((p
[10] == '#') << 7) |
47 ((p
[11] == '#') << 6) |
48 ((p
[13] == '#') << 5) |
49 ((p
[14] == '#') << 4) |
50 ((p
[15] == '#') << 3) |
51 ((p
[17] == '#') << 2) |
52 ((p
[18] == '#') << 1) |
53 ((p
[19] == '#') << 0));
54 // For 2x2, rotations is sufficient to cover all flips
55 for (i
= 0; i
< 4; i
++) {
56 p_in
= ((((p_in
& (1 << 3)) != 0) << 2) |
57 (((p_in
& (1 << 2)) != 0) << 0) |
58 (((p_in
& (1 << 1)) != 0) << 3) |
59 (((p_in
& (1 << 0)) != 0) << 1));
60 if (in2
[p_in
] <= 0x1ff)
61 assert (in2
[p_in
] == p_out
);
67 assert (p
[12] == '=' && p
[13] == '>' && p
[34] == '\n');
68 p_in
= (((p
[0] == '#') << 8) |
69 ((p
[1] == '#') << 7) |
70 ((p
[2] == '#') << 6) |
71 ((p
[4] == '#') << 5) |
72 ((p
[5] == '#') << 4) |
73 ((p
[6] == '#') << 3) |
74 ((p
[8] == '#') << 2) |
75 ((p
[9] == '#') << 1) |
76 ((p
[10] == '#') << 0));
77 p_out
= (((p
[15] == '#') << 15) |
78 ((p
[16] == '#') << 14) |
79 ((p
[17] == '#') << 13) |
80 ((p
[18] == '#') << 12) |
81 ((p
[20] == '#') << 11) |
82 ((p
[21] == '#') << 10) |
83 ((p
[22] == '#') << 9) |
84 ((p
[23] == '#') << 8) |
85 ((p
[25] == '#') << 7) |
86 ((p
[26] == '#') << 6) |
87 ((p
[27] == '#') << 5) |
88 ((p
[28] == '#') << 4) |
89 ((p
[30] == '#') << 3) |
90 ((p
[31] == '#') << 2) |
91 ((p
[32] == '#') << 1) |
92 ((p
[33] == '#') << 0));
93 // For 3x3, need rotations + 1 flip
94 for (i
= 0; i
< 4; i
++) {
95 p_in
= ((((p_in
& (1 << 8)) != 0) << 6) |
96 (((p_in
& (1 << 7)) != 0) << 3) |
97 (((p_in
& (1 << 6)) != 0) << 0) |
98 (((p_in
& (1 << 5)) != 0) << 7) |
99 (((p_in
& (1 << 4)) != 0) << 4) |
100 (((p_in
& (1 << 3)) != 0) << 1) |
101 (((p_in
& (1 << 2)) != 0) << 8) |
102 (((p_in
& (1 << 1)) != 0) << 5) |
103 (((p_in
& (1 << 0)) != 0) << 2));
105 assert (in3
[p_in
] == p_out
);
108 p_in
= (((p_in
& (7 << 6)) >> 6) |
109 ((p_in
& (7 << 3)) >> 0) |
110 ((p_in
& (7 << 0)) << 6));
111 for (i
= 0; i
< 4; i
++) {
112 p_in
= ((((p_in
& (1 << 8)) != 0) << 6) |
113 (((p_in
& (1 << 7)) != 0) << 3) |
114 (((p_in
& (1 << 6)) != 0) << 0) |
115 (((p_in
& (1 << 5)) != 0) << 7) |
116 (((p_in
& (1 << 4)) != 0) << 4) |
117 (((p_in
& (1 << 3)) != 0) << 1) |
118 (((p_in
& (1 << 2)) != 0) << 8) |
119 (((p_in
& (1 << 1)) != 0) << 5) |
120 (((p_in
& (1 << 0)) != 0) << 2));
122 assert (in3
[p_in
] == p_out
);
127 // perform the expansions
128 for (i
= 0; i
< iter
; i
++) {
129 if (size
& 1) { // expand 3x3 into 4x4
130 for (y
= size
/ 3; y
--; )
131 for (x
= size
/ 3; x
--; ) {
132 p_in
= ((grid
[y
* 3 + 0][x
* 3 + 0] << 8) |
133 (grid
[y
* 3 + 0][x
* 3 + 1] << 7) |
134 (grid
[y
* 3 + 0][x
* 3 + 2] << 6) |
135 (grid
[y
* 3 + 1][x
* 3 + 0] << 5) |
136 (grid
[y
* 3 + 1][x
* 3 + 1] << 4) |
137 (grid
[y
* 3 + 1][x
* 3 + 2] << 3) |
138 (grid
[y
* 3 + 2][x
* 3 + 0] << 2) |
139 (grid
[y
* 3 + 2][x
* 3 + 1] << 1) |
140 (grid
[y
* 3 + 2][x
* 3 + 2]));
142 printf ("3x3 mapping for %x not found!\n", p_in
);
146 grid
[y
* 4 + 0][x
* 4 + 0] = p_out
& (1 << 15);
147 grid
[y
* 4 + 0][x
* 4 + 1] = p_out
& (1 << 14);
148 grid
[y
* 4 + 0][x
* 4 + 2] = p_out
& (1 << 13);
149 grid
[y
* 4 + 0][x
* 4 + 3] = p_out
& (1 << 12);
150 grid
[y
* 4 + 1][x
* 4 + 0] = p_out
& (1 << 11);
151 grid
[y
* 4 + 1][x
* 4 + 1] = p_out
& (1 << 10);
152 grid
[y
* 4 + 1][x
* 4 + 2] = p_out
& (1 << 9);
153 grid
[y
* 4 + 1][x
* 4 + 3] = p_out
& (1 << 8);
154 grid
[y
* 4 + 2][x
* 4 + 0] = p_out
& (1 << 7);
155 grid
[y
* 4 + 2][x
* 4 + 1] = p_out
& (1 << 6);
156 grid
[y
* 4 + 2][x
* 4 + 2] = p_out
& (1 << 5);
157 grid
[y
* 4 + 2][x
* 4 + 3] = p_out
& (1 << 4);
158 grid
[y
* 4 + 3][x
* 4 + 0] = p_out
& (1 << 3);
159 grid
[y
* 4 + 3][x
* 4 + 1] = p_out
& (1 << 2);
160 grid
[y
* 4 + 3][x
* 4 + 2] = p_out
& (1 << 1);
161 grid
[y
* 4 + 3][x
* 4 + 3] = p_out
& (1 << 0);
164 } else { // expand 2x2 into 3x3
165 for (y
= size
/ 2; y
--; )
166 for (x
= size
/ 2; x
--; ) {
167 p_in
= ((grid
[y
* 2 + 0][x
* 2 + 0] << 3) |
168 (grid
[y
* 2 + 0][x
* 2 + 1] << 2) |
169 (grid
[y
* 2 + 1][x
* 2 + 0] << 1) |
170 (grid
[y
* 2 + 1][x
* 2 + 1]));
171 if (in2
[p_in
] > 0x1ff) {
172 printf ("2x2 mapping for %x not found!\n", p_in
);
176 grid
[y
* 3 + 0][x
* 3 + 0] = p_out
& (1 << 8);
177 grid
[y
* 3 + 0][x
* 3 + 1] = p_out
& (1 << 7);
178 grid
[y
* 3 + 0][x
* 3 + 2] = p_out
& (1 << 6);
179 grid
[y
* 3 + 1][x
* 3 + 0] = p_out
& (1 << 5);
180 grid
[y
* 3 + 1][x
* 3 + 1] = p_out
& (1 << 4);
181 grid
[y
* 3 + 1][x
* 3 + 2] = p_out
& (1 << 3);
182 grid
[y
* 3 + 2][x
* 3 + 0] = p_out
& (1 << 2);
183 grid
[y
* 3 + 2][x
* 3 + 1] = p_out
& (1 << 1);
184 grid
[y
* 3 + 2][x
* 3 + 2] = p_out
& (1 << 0);
189 // describe the result
191 for (y
= 0; y
< size
; y
++)
192 for (x
= 0; x
< size
; x
++)
195 printf ("after %d cycles, image size %d, %d pixels are on\n", iter
, size
, on
);