1
+ /*
2
+ input: string, lines: string[], dblines: string[][]
3
+ copy(text: string) → clipboard
4
+ error(message: string) → thrown error
5
+ -5..mod(3) → @mod(-5, 3)
6
+ */
7
+
8
+ // Cardinals:
9
+ // [[1,0],[-1,0],[0,1],[0,-1]]
10
+ // +Diagonals:
11
+ // [[1,0],[-1,0],[0,1],[0,-1],[-1,-1],[-1,1],[1,-1],[1,1]]
12
+
13
+ export { } ;
14
+
15
+ const instrs = `sesenwnenenewseeswwswswwnenewsewsw
16
+ neeenesenwnwwswnenewnwwsewnenwseswesw
17
+ seswneswswsenwwnwse
18
+ nwnwneseeswswnenewneswwnewseswneseene
19
+ swweswneswnenwsewnwneneseenw
20
+ eesenwseswswnenwswnwnwsewwnwsene
21
+ sewnenenenesenwsewnenwwwse
22
+ wenwwweseeeweswwwnwwe
23
+ wsweesenenewnwwnwsenewsenwwsesesenwne
24
+ neeswseenwwswnwswswnw
25
+ nenwswwsewswnenenewsenwsenwnesesenew
26
+ enewnwewneswsewnwswenweswnenwsenwsw
27
+ sweneswneswneneenwnewenewwneswswnese
28
+ swwesenesewenwneswnwwneseswwne
29
+ enesenwswwswneneswsenwnewswseenwsese
30
+ wnwnesenesenenwwnenwsewesewsesesew
31
+ nenewswnwewswnenesenwnesewesw
32
+ eneswnwswnwsenenwnwnwwseeswneewsenese
33
+ neswnwewnwnwseenwseesewsenwsweewe
34
+ wseweeenwnesenwwwswnew` . split ( "\n" ) ;
35
+
36
+ let settiles = { } ;
37
+
38
+ // 0 2 4
39
+ // 0 o o o o o
40
+ // o o o o o
41
+ // o o o o o
42
+
43
+ for ( let line of instrs ) {
44
+ let x = 0 ;
45
+ let y = 0 ;
46
+ let linev = [ ...line ] ;
47
+ while ( linev . length ) {
48
+ let c0 = linev . shift ( ) ! ;
49
+ if ( c0 == "s" ) {
50
+ let c1 = linev . shift ( ) ! ;
51
+ if ( c1 == "e" ) {
52
+ // down and right
53
+ x += 1 ;
54
+ y += 1 ;
55
+ } else if ( c1 == "w" ) {
56
+ // down and left
57
+ x -= 1 ;
58
+ y += 1 ;
59
+ }
60
+ } else if ( c0 == "w" ) {
61
+ x -= 2 ;
62
+ } else if ( c0 == "e" ) {
63
+ x += 2 ;
64
+ } else if ( c0 == "n" ) {
65
+ let c1 = linev . shift ( ) ! ;
66
+ if ( c1 == "e" ) {
67
+ x += 1 ;
68
+ y -= 1 ;
69
+ } else if ( c1 == "w" ) {
70
+ x -= 1 ;
71
+ y -= 1 ;
72
+ }
73
+ }
74
+ }
75
+ const resp = `${ x } ,${ y } ` ;
76
+ if ( settiles [ resp ] === undefined ) settiles [ resp ] = false ;
77
+ settiles [ resp ] = ! settiles [ resp ] ;
78
+ }
79
+
80
+ function cleanup ( ) {
81
+ for ( let [ key , value ] of Object . entries ( settiles ) ) {
82
+ if ( ! value ) delete settiles [ key ] ;
83
+ }
84
+ }
85
+
86
+ function applyeven ( ) {
87
+ let newup = { } ;
88
+ cleanup ( ) ;
89
+
90
+ const dotile = ( x , y ) => {
91
+ let hasv = ( x , y ) => ! ! settiles [ `${ x } ,${ y } ` ] ;
92
+ let count = 0 ;
93
+ count += + hasv ( x + 2 , y ) ;
94
+ count += + hasv ( x - 2 , y ) ;
95
+ count += + hasv ( x + 1 , y + 1 ) ;
96
+ count += + hasv ( x + 1 , y - 1 ) ;
97
+ count += + hasv ( x - 1 , y + 1 ) ;
98
+ count += + hasv ( x - 1 , y - 1 ) ;
99
+
100
+ // true = black
101
+ // false = white
102
+ // count = number of black tiles
103
+
104
+ let thist = hasv ( x , y ) ;
105
+
106
+ print ( "the tile at " , x , y , " has" , count , " surrounding it and is" , thist ) ;
107
+
108
+ if ( thist == true ) { // black
109
+ if ( count > 2 || count == 0 ) {
110
+ // white
111
+ newup [ [ x , y ] . join ( "," ) ] = "white" ;
112
+ } else {
113
+ // black
114
+ }
115
+ } else {
116
+ if ( count == 2 ) {
117
+ // black;
118
+ } else {
119
+ newup [ [ x , y ] . join ( "," ) ] = "white;"
120
+ }
121
+ }
122
+ }
123
+ for ( let [ key , value ] of Object . entries ( settiles ) ) {
124
+ let [ x , y ] = key . split ( "," ) . map ( v => + v ) ;
125
+ dotile ( x + 2 , y ) ; dotile ( x - 2 , y ) ; dotile ( x + 1 , y + 1 ) ;
126
+ dotile ( x + 1 , y - 1 ) ;
127
+ dotile ( x - 1 , y + 1 ) ; dotile ( x - 1 , y - 1 ) ; dotile ( x , y ) ;
128
+ }
129
+ // print(settiles, newup);
130
+ settiles = newup ;
131
+ }
132
+
133
+ function applyodd ( ) {
134
+ // unknown tiles are black
135
+
136
+ let newup = { } ;
137
+ cleanup ( ) ;
138
+
139
+ const dotile = ( x , y ) => {
140
+ let hasv = ( x , y ) => ! ! settiles [ `${ x } ,${ y } ` ] ;
141
+ let count = 0 ;
142
+ count += + ! hasv ( x + 2 , y ) ;
143
+ count += + ! hasv ( x - 2 , y ) ;
144
+ count += + ! hasv ( x + 1 , y + 1 ) ;
145
+ count += + ! hasv ( x + 1 , y - 1 ) ;
146
+ count += + ! hasv ( x - 1 , y + 1 ) ;
147
+ count += + ! hasv ( x - 1 , y - 1 ) ;
148
+ // true = white
149
+ // false = black
150
+ // count = number of black tiles
151
+
152
+ let thist = hasv ( x , y ) ;
153
+ // print("tile ",x,y,", is",thist,"has",count,"black tiles surrounding");
154
+
155
+ if ( thist == false ) {
156
+ // this tile is black
157
+ if ( count > 2 || count == 0 ) {
158
+ // change to white
159
+ } else {
160
+ // keep black
161
+ newup [ [ x , y ] . join ( "," ) ] = "black" ;
162
+ }
163
+ } else {
164
+ // this tile is white
165
+ // print("this tile is white and count is",count);
166
+ if ( count == 2 ) {
167
+ // change to black
168
+ newup [ [ x , y ] . join ( "," ) ] = "black;"
169
+ } else {
170
+ // keep white
171
+ }
172
+ // print("newup is now", newup);
173
+ }
174
+ }
175
+ for ( let [ key , value ] of Object . entries ( settiles ) ) {
176
+ let [ x , y ] = key . split ( "," ) . map ( v => + v ) ;
177
+ dotile ( x + 2 , y ) ; dotile ( x - 2 , y ) ; dotile ( x + 1 , y + 1 ) ;
178
+ dotile ( x + 1 , y - 1 ) ;
179
+ dotile ( x - 1 , y + 1 ) ; dotile ( x - 1 , y - 1 ) ; dotile ( x , y ) ;
180
+ }
181
+ // print(settiles, newup);
182
+ settiles = newup ;
183
+
184
+ // now unknown tiles are white
185
+ }
186
+
187
+ function printboard ( a ) {
188
+ const bhx = "⬡" ;
189
+ const whx = "⬢" ;
190
+ let board = makeBoard ( a ? whx : bhx ) ;
191
+ for ( let [ key , value ] of Object . entries ( settiles ) ) {
192
+ let [ x , y ] = key . split ( "," ) . map ( v => + v ) ;
193
+
194
+ board . set ( x , y , a ? bhx : whx ) ;
195
+ }
196
+ board . print ( ( v , x , y ) => {
197
+ if ( y . mod ( 2 ) == ( x + 1 ) . mod ( 2 ) ) {
198
+ return " " ;
199
+ }
200
+ return v ;
201
+ } ) ;
202
+ }
203
+
204
+ for ( let i = 1 ; i <= 5 ; i ++ ) {
205
+ printboard ( i % 2 == 0 ) ;
206
+ console . log ( Object . entries ( settiles ) . length ) ;
207
+ if ( i % 2 == 0 ) applyeven ( ) ;
208
+ else applyodd ( ) ;
209
+ } ;
210
+
211
+
212
+ console . log ( Object . entries ( settiles ) . length ) ;
213
+
214
+ // I guess I could precreate a 100x100 grid and do that idk
215
+
216
+
217
+ type nobi = number | number ;
218
+ type Board < T > = {
219
+ get ( x : nobi , y : nobi ) : T ;
220
+ set ( x : nobi , y : nobi , t : T ) : void ;
221
+ clear ( ) : void ;
222
+ forEach ( visitor : ( v : T , x : number , y : number ) => void ) : void ;
223
+ print ( printer ?: ( v : T , x : number , y : number ) => string | nobi ) : void ;
224
+ copy ( ) : Board < T > ;
225
+ } ;
226
+ function makeBoard < T > ( fill : T ) : Board < T > {
227
+ // it would be useful if board could center at 0,0 and expand infinitely
228
+ let board : T [ ] [ ] = [ ] ;
229
+ let limits :
230
+ | { xmin : number ; xmax : number ; ymin : number ; ymax : number }
231
+ | undefined ;
232
+ let reso : Board < T > = {
233
+ clear : ( ) => {
234
+ board = [ ] ;
235
+ } ,
236
+ get : ( x , y ) => {
237
+ if ( ! limits ) return fill ;
238
+ if (
239
+ x < limits . xmin ||
240
+ x > limits . xmax ||
241
+ y < limits . ymin ||
242
+ y > limits . ymax
243
+ )
244
+ return fill ;
245
+ if ( ! board [ Number ( y ) ] ) return fill ;
246
+ let bval = board [ Number ( y ) ] [ Number ( x ) ] ;
247
+ return bval === undefined ? fill : bval ;
248
+ } ,
249
+ set : ( x , y , v ) => {
250
+ if ( ! limits )
251
+ limits = {
252
+ xmin : Number ( x ) ,
253
+ ymin : Number ( y ) ,
254
+ xmax : Number ( x ) ,
255
+ ymax : Number ( y ) ,
256
+ } ;
257
+ if ( x < limits . xmin ) limits . xmin = Number ( x ) ;
258
+ if ( y < limits . ymin ) limits . ymin = Number ( y ) ;
259
+ if ( x > limits . xmax ) limits . xmax = Number ( x ) ;
260
+ if ( y > limits . ymax ) limits . ymax = Number ( y ) ;
261
+ if ( ! board [ Number ( y ) ] ) board [ Number ( y ) ] = [ ] ;
262
+ board [ Number ( y ) ] [ Number ( x ) ] = v ;
263
+ } ,
264
+ forEach : visitor => {
265
+ if ( ! limits ) return ;
266
+ let ym = limits . ymin ;
267
+ let yma = limits . ymax ;
268
+ let xm = limits . xmin ;
269
+ let xma = limits . xmax ;
270
+ for ( let y = ym ; y <= yma ; y ++ ) {
271
+ for ( let x = xm ; x <= xma ; x ++ ) {
272
+ visitor ( reso . get ( x , y ) , x , y ) ;
273
+ }
274
+ }
275
+ } ,
276
+ copy : ( ) => {
277
+ let nb = makeBoard < T > ( fill ) ;
278
+ reso . forEach ( ( v , x , y ) => nb . set ( x , y , v ) ) ;
279
+ return nb ;
280
+ } ,
281
+ print : ( printer = v => v as any ) => {
282
+ // ratelimit print
283
+ if ( ! limits ) return console . log ( "*no board to print*" ) ;
284
+ let ylength = 0 ;
285
+ for ( let y = limits . ymin - 1 ; y <= limits . ymax + 1 ; y ++ ) {
286
+ ylength = Math . max ( y . toString ( ) . length , ylength ) ;
287
+ }
288
+ console . log (
289
+ " " . repeat ( ylength ) +
290
+ " .-" +
291
+ "-" . repeat ( limits . xmax - limits . xmin + 5 ) +
292
+ "-." ,
293
+ ) ;
294
+ for ( let y = limits . ymin - 1 ; y <= limits . ymax + 1 ; y ++ ) {
295
+ let line = "" ;
296
+ for ( let x = limits . xmin - 2 ; x <= limits . xmax + 2 ; x ++ ) {
297
+ line += printer ( reso . get ( x , y ) , x , y ) ;
298
+ }
299
+ console . log ( y . toString ( ) . padStart ( ylength , " " ) + " | " + line + " |" ) ;
300
+ }
301
+ console . log (
302
+ " " . repeat ( ylength ) +
303
+ " '-" +
304
+ "-" . repeat ( limits . xmax - limits . xmin + 5 ) +
305
+ "-'" ,
306
+ ) ;
307
+ } ,
308
+ } ;
309
+ return reso ;
310
+ }
0 commit comments