all stats

kimapr's stats

guessed the most

namecorrect guessesgames togetherratio
olive340.750
Palaiologos340.750
LyricLy8180.444
luatic6140.429
essaie370.429
theqwertiest250.400
olus20005140.357
moshikoi260.333
kotnen3100.300
soup girl140.250
JJRubes140.250
Dolphy280.250
Olivia280.250
taswelll290.222
yui150.200
vspf040.000
razetime070.000

were guessed the most by

namecorrect guessesgames togetherratio
olive340.750
luatic10140.714
Dolphy580.625
vspf240.500
razetime370.429
yui250.400
moshikoi250.400
LyricLy7180.389
Olivia380.375
essaie270.286
olus20004140.286
JJRubes140.250
kotnen290.222
taswelll290.222
theqwertiest150.200
Palaiologos040.000

entries

round #60

submitted at
3 likes

guesses
comments 0

post a comment


inyourwalls.exe PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows, 3 sections

round #59

submitted at
3 likes

guesses
comments 5
kotnen

meow


kimapr *known at the time as [author of #4] replying to kotnen

meow!


kotnen

i know who you are now.


kotnen

meowmeowmeow


kimapr *known at the time as [author of #4] replying to kotnen

nyo you don't nyaa :3


post a comment


entry.py ASCII text
  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
def encourage(bottom, pleading=[]):
    bottom = [squirm for squirm in bottom]

    def lap(top):
        try:
            top.hard.append (
                top.soft [
                    top.hard.pop()])
        except (IndexError, KeyError):
            reduce(0)

    def reduce(item):
        item.hard.append(0)

    def induce(current):
        try:
            golden = current.hard.pop()
        except IndexError:
            golden = 0
        try:
            retriever = current.hard.pop()
        except IndexError:
            retriever = 0
        current.soft [
            golden ]= retriever

    def seduce(victim):
        try:
            victim.hard.append (
                victim.hard.pop() + 1)
        except IndexError:
            victim.hard.append(1)

    def deduce(crime):
        try:
            crime.hard.append (
                crime.random (
                    crime.hard.pop()))
        except IndexError:
            crime.hard.append(0)
            return

    def genetic(spawn):
        try:
            insistence = spawn.hard.pop()
        except IndexError:
            insistence = 0
        spawn.crows.append(insistence)

    def stochastic(crow):
        relativity = crow.monads [
            crow.monadic]
        crow.monadic = crow.monadic + 1
        try:
            questionable = crow.hard.pop()
        except IndexError:
            questionable = 0
        try:
            dogmatic = crow.crows[-1:][0]
            sabotage = 42
            sabotage /= questionable
            sabotage /= dogmatic
        except ZeroDivisionError:
            crow.monadic = relativity
            crow.crows.pop()

    def deterministic(pickle):
        relativity = pickle.monads [
            pickle.monadic]
        pickle.monadic = relativity
        pickle.crows.append (
            pickle.crows.pop() - 1)

    class constructor:
        genetic = None
        stochastic = None
        deterministic = None

    clone = __import__("copy").deepcopy
    copy = __import__("copy").copy

    class objection:
        soft = {}
        hard = []
        crows = []
        monads = []
        monadic = 0
        constructural = []
        random = None
        def __deepcopy__(self, memo):
            obj = objection()
            obj.monads = self.monads
            obj.monadic = self.monadic
            obj.random = self.random
            obj.hard = clone(self.hard,memo)
            obj.soft = clone(self.soft,memo)
            obj.crows = clone(self.crows,memo)
            return obj

    def std__forward_inserter(iterator,iterant,functor):
        def fungus(objection):
            objection.monads.append(functor)
        iterator[iterant] = fungus

    def std__genetic_inserter(iterator,iterant):
        def fungus(objection):
            const = constructor()
            const.genetic = len(objection.monads)
            objection.constructural.append(const)
            objection.monads.append(genetic)
        iterator[iterant] = fungus

    def std__stochastic_inserter(iterator,iterant):
        def fungus(objection):
            const = objection.constructural[-1:][0]
            const.stochastic = (len(objection.monads)
                if const.stochastic == None
                else 1/0)
            objection.monads.append(stochastic)
            objection.monads.append(None)
        iterator[iterant] = fungus

    def std__deterministic_inserter(iterator,iterant):
        def fungus(objection):
            const = objection.constructural.pop()
            const.deterministic = len(objection.monads)
            objection.monads [
                const.stochastic + 1 ]= const.deterministic + 2
            objection.monads.append(deterministic)
            objection.monads.append(const.genetic + 1)
        iterator[iterant] = fungus

    npcs = {}
    std__forward_inserter(npcs,"@",lap)
    std__forward_inserter(npcs,"#",reduce)
    std__forward_inserter(npcs,"!",induce)
    std__forward_inserter(npcs,"+",seduce)
    std__forward_inserter(npcs,"?",deduce)
    std__genetic_inserter(npcs,"[")
    std__stochastic_inserter(npcs,"|")
    std__deterministic_inserter(npcs,"]")

    world = objection()
    for sans_undertale in bottom:
        try:
            excited = npcs[sans_undertale]
        except:
            continue
        excited(objection)

    outputs = {}

    def excite(objection):
        while objection.monadic < len(objection.monads):
            monad = objection.monads[objection.monadic]
            if monad == deduce and objection.random == None:
                for i in range(0,([0] + objection.hard[-1:]).pop() + 1):
                    __objection__ = clone(objection)
                    def random(n):
                        return i
                    __objection__.random = random
                    excite(__objection__)
                return
            objection.monadic = objection.monadic + 1
            monad(objection)
            objection.random = None
        output = tuple(objection.hard)
        outputs[output] = (outputs.get(output) or 0) + 1

    world.hard = clone(pleading)
    excite(world)

    return list(sorted(outputs.items(), key=lambda key:key[1]).pop()[0])

round #58

submitted at
1 like

guesses
comments 0

post a comment


curlIng.sh ASCII text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/bin/sh
curl -sS https://cg.esolangs.gay/58/|
# parse html with regex
perl -p0e 's/\n/ /g'                                       |
perl -pe 's/^.*(<p id="spec">.*<script>).*$/\1/'           |
perl -pe 's/<\/p>/\n\n/g'                                  |
perl -pe 's/<br *\/>/\n/g'                                 |
perl -pe 's/<p.*>|<script>| *$|^( )*|(?<c> )  *|/$+{c}/g'  |
perl -pe 's/&quot;/"/g'
                                                           #

round #57

submitted at
3 likes

guesses
comments 0

post a comment


dir code
guesser.js ASCII text
  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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
                                        (async function(a,b,c,d,just,f){a=0;b=[]
"your".mom; with(("massive".size
                                        ,d=0,((p)=>(p=new Proxy(globalThis,{has(
cant, fit,/*in*/ the_Void
                               ){return!(fit in cant)},call(){eval(b.join(''))},
"don't":``.cry,
                        get(t,k,r){return this[k]??(k==Symbol.unscopables?{}:(([
just
                              ]=[0],k in r)?(c(k),p):Reflect.get(t,k,r)))}}),"".
come_here,
                             c=c=>c.match(/^[Aa][Aa]*$/)&&[...c].forEach(_=>("".
and
                                           ,a+=(_<'a')<<d,d++>6&&(d=0,b.push((p.
listen.
                                      _,String.fromCharCode(a))),a=0))),p))())){

aaaAaAaaaaaAaAaaAaaAaAaaaaaaaAaaAaAAAAaaaAAAAAaaaaaaaAaaAAaAAAAaaAaAaaaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaAAAAaAaaAAAAaAaaaaaaaAaaAAaaaaAaaaaAaAAaAaAaaAAaAAaaaAAa
AAaAaAAaaaaaaAaaAaaAaAAaaAAaaAAaaaaaaAaaaaAaAAAaaaaAaAAaAaAaaAAaaaaaaAaaAAAaaAaa
AAAaAAAaAaaAaAAaaAAAaAAaaaAaaAAaAAAAaAAaAAAaAAAaAAAaaAaaaaaaaAaaAAAAaAAaaAaaaAAa
aAaAaAAaAaAaaAAaAAaaaAAaaaAaAAAaaaaaaAaaAaaAaAAaAAaaAAAaaaaaaAaaaaaaAAAaaAaaAAAa
AaAaaAAaAAaaAAAaAaAaaAAaaAAAaAAaaaAaAAAaaaaaaAaaAaaAaAAaaAAAaAAaaaaaaAaaaaAaAAAa
aaaAaAAaAaAaaAAaaaaaaAaaAAAaaAAaaaAAaAAaAAAAaAAaaAaaaAAaAaaaaAAaaaAAaAAaaaaaaAaa
AAaaAAAaAAaaaAAaAAAAaAAaaaaaAAAaAaAaaAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
AaaAaAAaaAAaaAAaaaaaaAaaaaaAaAaaAaaaaAaaaaaAaAaaAAAaaAaaAAAaAAAaAaaAaAAaaAAAaAAa
aaAaaAAaAAAAaAAaAAAaAAAaAAAaaAaaaaaaaAaaAaaAaAAaaAAAaAAaaaaaaAaaAAAaaAAaaaAAaAAa
AAAAaAAaaAaaaAAaAaaaaAAaaaAAaAAaaaAaAaAaaaaAaAAaAaaAaAAaAAaaAAAaAaaAaAaaAaaAaAaa
aaaaaAaaAAaAAAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaAAAAaAaaAAAAaAaaaaaaaAaaaaAaaaAaAaaAaAAaAAaaAAAaaaaaAAAaaaAAaAAaAaaaaAAa
AaaAAAAaaaaaaAaaAaaAaAAaaAAAaAAaAAaaAAAaaaAaAAAaaAaaAAAaAaAaAAAaAAaaaAAaaaAaAAAa
AaaAaAAaAAAAaAAaaAAAaAAaAAaaAAAaaaaaaAaaAaaAaAAaaAAaaAAaaaaaaAaaAAAaaAaaAAAaAAAa
AaaAaAAaaAAAaAAaaaAaaAAaAAAAaAAaAAAaAAAaAAAaaAaaaaaaaAaaAaaAaAAaAAaaAAAaaaaaaAaa
aAAAaAAaAAAAaAAaaaAaAAAaaaaaaAaaaaaaAAAaaAaaAAAaAaAaaAAaAAaaAAAaAaAaaAAaaAAAaAAa
aaAaAAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
AAaaaAAaAAAAaAAaaAAAaAAaAAaaAAAaAAAAaAAaaaAAaAAaAaAaaAAaaAAAaAaaaaAAaAAaAAAAaAAa
AAAaaAAaaaaAaAaaaaaaaAAaaaAAAaAaaAaAaaaaAAAAaaAaaaaaAAAaAaAaaAAaaAAAaAAaaaaaaAaa
aaaAaAAaaaAaAAAaaaAaAAAaaaaaAAAaAAaaAAAaaAaAAAaaAAAAaAaaAAAAaAaaAAaaaAAaAAAaaAAa
aAAAaAaaAaAaaAAaAAaaAAAaAAAAaAAaaaAAaAAaAaaaaAAaaAAAaAAaAAAaaAAaAAaaAAAaaAAAaAaa
AAAaaAAaAaaaaAAaAaaAAAAaAAAAaAaaaaAAAAaaAAaaaAAaAaAaAAAaaAaaAAAaaAaaAAAaAaAaaAAa
aAAAaAAaaaAaAAAaaaaaaAaaaAaaAAAaAAAAaAAaAaAaAAAaaAAAaAAaaaAaaAAaaAAAAAaaAAAAaAaa
aaaaaAaaAaaaaAAaaAAAaAAaaaAaaAAaaaaaaAaaaaaaAAAaAaaaaAAaAAaaAAAaaaAaAAAaAaAaaAAa
aaaaaAaaaaAaAAAaaaaAaAAaAaaAaAAaAAaaAAAaaaaaaAaaaaaaAAAaaAaaAAAaAAAAaAAaAAAaaAAa
aAaaAAAaAaaaaAAaAaAAaAAaaaaaaAaaAaaAaAAaaAAAaAAaaaaaaAaaaaAaaaAaAaAaaAAaaAAaAAAa
aaAaAaAaAAAAaAAaAAAAaAAaaaAAaAAaAAaaAAAaaAAAaAaaaAaAaaaaaAaAaaaaAAaaaaAaAAAAaAAa
aaaaAAAaAaaAAAAaaAaaAAAaAaaAaAAaAAAaaAAaaaaAaAAaaaAaAAAaaaaaaAaaaaaAaAaaAAaaaaAa
AaaAaAaaaAaaAAaaaaaaAAaaaAaaAAaaaaAaAAaaaaaaaAaaAaaaaaAaAaaAaaAaaaaaaAaaAAaaaaAa
AAAAaAAaaaAaaAAaAaAaaAAaaaaaaAaaAAAaaaAaAaAaAAAaAaAaaAAaAAaaAAAaAAaaAAAaAaAaaAAa
aAaaAAAaAAaaAAAaaaaaaAaaAaaaaaAaAAaaAAAaAAaaAAAaAAAAaAAaAAaaaAAaAaaAaAAaAaaaaAAa
aaAaAAAaAaaAaAAaAAAAaAAaaAAAaAAaaAaAaaaaAaaaaaAaaaAAaAAaaaAAaAAaaaaaaAaaaAaaAAAa
AaaAaAAaAAAaaAAaaaaAaAAaaaAaAAAaAAaaAAAaaaaaaAaaaAaaAAAaAaAaaAAaAAaaAAAaAaAaaAAa
aAaaAAAaaAAaAAAaAaAaaAAaaaAaaAAaaAAAaAaaaaaaaAaaaaaAaAAaaaAaAAAaaaAaAAAaaaaaAAAa
AAaaAAAaaAaAAAaaAAAAaAaaAAAAaAaaAaaaaAAaAaaAaAAaAAaaaAAaAAAaaAAaAaaaaAAaaAAAaAaa
AAAaaAAaaAaaAAAaAaAaaAAaAaaaaAAaaaAaAAAaAaAAaAaaAAaaAAAaAaaAaAAaaaAaAAAaAaAaaAAa
aAAAaAaaaAAAaAAaAaAaaAAaaaAaAAAaAAAAaAaaaaAAAaAaaAaAaaaaaaaaaAAaAaaAaAaaAAaAAAaa
aAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaAaaAAAa
AaAaaAAaaaAaAAAaAaAaAAAaaAaaAAAaaAAAaAAaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaAaAAAAAaaAaAaaaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAAAaAaaAAAAaAaa
aaaaaAaaaAAaaaAaAaaAaAAaaAAAaAAaaaAaaAAaaaaaaAaaaaAaAAAaaaaAaAAaAaAaaAAaaaaaaAaa
aAaaaAAaAaAaAAAaaaAaAAAaaaAaAAAaAAAAaAAaaAAAaAAaaaaaaAaaAaAaAAAaAAaaAAAaAaAaaAAa
aaAaaAAaaaaaaAaaaaAaAAAaAAAAaAAaaaaaaAaaaAAaaAAaAaaAaAAaaAAAaAAaAaaAaAAaAAaaAAAa
aaaAaAAaaaaaaAaaaaAaAAAaaaaAaAAaAaAaaAAaaaaaaAaaaAaaAAAaAAAAaAAaAaAaAAAaaAAAaAAa
aaAaaAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaAAaAAaAaAaaAAaaaAaAAAaaaaaaAaa
AAaAAaAaaAAaaAAaAaaAaAAaaAAAaAAaAaaAaAAaAAaaAAAaaaaAaAAaaAaaaaAaaaAaAAAaaAAAaAAa
AaAAAaAaaaaaaAaaAaAAAAaaaaaaaAaaAAaAAaAaaAAAaAaaaAAAaAaaaAAAaAaaaaAaaAAaAAAAaAAa
AAaaaAAaAaAaAAAaAaAAaAAaAaAaaAAaaAAAaAAaaaAaAAAaaAAAaAaaAaaaAAAaAaAaAAAaAaAaaAAa
aAaaAAAaAaaAAAAaAAaaAaAaAaAaaAAaaaAAaAAaAaAaaAAaAAaaaAAaaaAaAAAaAAAAaAAaaAaaAAAa
AaaaaaAaaaAAaAAaaaAAaAAaaaaAaAaaaAaaaAaaaAaaaAAaAaAaAAAaaaAaAAAaaaAaAAAaAAAAaAAa
aAAAaAAaaAaaaAaaAaaAaAaaAaAAAaAaaAAAaAaaaAAaaAAaAaaAaAAaaaAAaAAaaaAaAAAaAaAaaAAa
aAaaAAAaaaaAaAaaAaAaaAAaaaaaaAaaAaAAAAaaaAAAAAaaaaaaaAaaAaAaaAAaaAAAaAaaAAAaaAAa
AaAaaAAaaaAaAAAaAaaaaaAaaaAaAAAaaaAaAAAaaAaaAAAaAaaAaAAaaAaaaAAaAaAaAAAaaaAaAAAa
AaAaaAAaaaaAaAaaaAaaaAaaAAAAaAAaaAAAaAAaaaAaAAAaAAAAaAAaAAAaaAAaAAAaaAAaaaAAaAAa
AaAaaAAaaAaaaAaaAaaAaAaaaaaaaAaaAaAAAAaaAaAAAAaaaaaaaAaaaAaaaAaaaAAaaAAaAaaAaAAa
aAAAaAAaAaaAaAAaAAaaAAAaaaaAaAAaaaaAaAaaaaAaAAAaaaaAaAAaAaaAaAAaAAaaAAAaAaaAaAaa
aAaaaAaaAaaAaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaAAaAAaAaAaaAAa
aaAaAAAaaaaaaAaaAAAaaAAaAaAaAAAaAaAaaAAaAAaaAAAaAAaaAAAaaAaaaaAaaaAaAAAaaAAAaAAa
AAaAAAaaaAaAaaaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAAAaAaaAAAAaAaaaaaaaAaa
AaaAaaAaaAAAaAAaAAaaAAAaAaAaaAAaaAaaAAAaaaAaAAAaaaaaaAaaAaaaaAAaaaaaaAaaaAAAaAAa
AaAaaAAaAAAaAAAaaaaaaAaaaAaaaAAaAaAaAAAaaaAaAAAaaaAaAAAaAAAAaAAaaAAAaAAaaaaaaAaa
aaAAaAAaAaaaaAAaaAaaaAAaAaAaaAAaaaAAaAAaAaAaaAAaaaAaaAAaaaaaaAaaAaaaaAAaAAaaAAAa
aaaaaAaaAaaaaaAaAaaAaaAaaaaaaAaaaAaaaAAaAaAaaAAaaAAaaAAaAAAAaAAaaAaaAAAaAaAaaAAa
aaaaaAaaaaAaAAAaaaaAaAAaAaAaaAAaaaaaaAaaaAAaaAAaAaaAaAAaaAAAaAAaAaaAaAAaAAaaAAAa
aaaAaAAaaaaaaAaaaAaaaAAaAaAaAAAaaaAaAAAaaaAaAAAaAAAAaAAaaAAAaAAaaAaAaaaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaAAaaAAaAaaAaAAaaAAAaAAaAaaAaAAaAAaaAAAaaaaAaAAaaAaaaaAa
aaAaAAAaaAAAaAAaaAAAaAaaaaaaAAAaAaaaaAAaaAaaAAAaAaAaaAAaaAAAaAAaaaAaAAAaAaAaaaAa
aaAAaAAaAaAaaAAaAaAAaAAaAaAaaAAaaAAAaAAaaaAaAAAaaAAAaAaaAaaAaAAaaAAAaAAaAAaaAAAa
AaAaaAAaaAaaAAAaaaAaAAAaaAaaaaAaAaAaaAAaaAAaaAAaAAAAaAAaaAaaAAAaAaAaaAAaaaaAaAaa
aaaAaAaaAAAAAaAaaaaaaAaaAaAAAAaaaAAAAAaaaaaaaAaaaaaAaAaaAAAAAaAaaAAAaAaaAaaAaAAa
aAAAaAAaaAAAaAAaAaAaaAAaaAaaAAAaaaaAaaAaaaAaAaAaAaAAaaAaaaAAaaAaaaaaaAaaAaAAAAaa
aaaaaAaaaAaaaAaaaaAAAAaaAaaAaAAaaAAAAAaaAaaaaaAaAaaAaaAaaaAAAAaaAAAAaAaaAaaAaAAa
aAAAAAaaaAaaaAaaaaAAaAaaaaaaaAaaAAAaaAAaAaAaAAAaAaAaaAAaAAaaAAAaAAaaAAAaaAaaaaAa
aaAaAAAaaAAAaAAaaaaaaAaaAaAAAAaaaaaaaAaaAAAAAaAaAaaAaAaaAaaAaAaaaaaAaAaaaaAaaAAa
AAAAaAAaAAaaaAAaAaAaAAAaAaAAaAAaAaAaaAAaaAAAaAAaaaAaAAAaaAAAaAaaAAaaaAAaaAaaAAAa
AaAaaAAaAaaaaAAaaaAaAAAaAaAaaAAaAaAaaaAaaaAAaAAaAaAaaAAaAaAAaAAaAaAaaAAaaAAAaAAa
aaAaAAAaaaaAaAaaaAaaaAaaaAaaaAAaAaAaAAAaaaAaAAAaaaAaAAAaAAAAaAAaaAAAaAAaaAaaaAaa
AaaAaAaaAaaAaAaaaaAAaAaaaaaaaAaaaAAaaAAaAaaAaAAaaAAAaAAaAaaAaAAaAAaaAAAaaaaAaAAa
aAaaaaAaaaAaAAAaaAAAaAAaAaaAaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aAAaaAAaAaaAaAAaaAAAaAAaAaaAaAAaAAaaAAAaaaaAaAAaaAaaaaAaaaAaAAAaaAAAaAAaaAAAaAaa
aaaaAAAaAaaaaAAaaAaaAAAaAaAaaAAaaAAAaAAaaaAaAAAaAaAaaaAaaaAAaAAaAaAaaAAaAaAAaAAa
AaAaaAAaaAAAaAAaaaAaAAAaaAAAaAaaAaaAaAAaaAAAaAAaAAaaAAAaAaAaaAAaaAaaAAAaaaAaAAAa
aAaaaaAaAaAaaAAaaAAaaAAaAAAAaAAaaAaaAAAaAaAaaAAaaaaAaAaaaaAaaAAaAAAAaAAaAAaaaAAa
AaAaAAAaAaAAaAAaAaAaaAAaaAAAaAAaaaAaAAAaaAAAaAaaAAaaaAAaaAaaAAAaAaAaaAAaAaaaaAAa
aaAaAAAaAaAaaAAaaaAaAaAaAaAaaAAaaaaAAAAaaaAaAAAaaAAAaaAaAAAAaAAaaaAaaAAaAaAaaAAa
aaaAaAaaaAaaaAaaaaaaaAaaaAaaaAaaAaaAaAaaaaAAaAaaaaaaaAaaaAAaaAAaAaaAaAAaaAAAaAAa
AaaAaAAaAAaaAAAaaaaAaAAaaAaaaaAaaaAaAAAaaAAAaAAaAaaAaAaaAAaAAAaaaAaAaaaaaAaAaaaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAAAaAaaAAAAaAaaaaaaaAaaAaAaaaAaaAAaAAAaAaAaaAAa
aAAAaAAaaaAaAAAaaaaaaAaaaaaAaAAaAaaaaAAaaAAAaAAaaaAaaAAaaaAAaAAaAaAaaAAaaAaaAAAa
aaaaaAaaaAAaaAAaAAAAaAAaaAaaAAAaaaaaaAaaaaAaAAAaaaaAaAAaAaAaaAAaaaaaaAaaAaaaaaAa
AaaAaaAaaaaaaAaaaAaaaAAaAaAaAAAaaaAaAAAaaaAaAAAaAAAAaAAaaAAAaAAaaaaaaAaaAAaaaAAa
aaAAaAAaAaaAaAAaAAaaaAAaAAaAaAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAAaaAAa
AaAaAAAaAaAaaAAaAAaaAAAaAAaaAAAaaAaaaaAaaaAaAAAaaAAAaAAaaAAAaAaaAAAAaAAaaAAAaAAa
AAaaaAAaaaAAaAAaAaaAaAAaAAaaaAAaAAaAaAAaaaaaaAaaAaAAAAaaaaaaaAaaAaaaaAAaAAaaAAAa
AaaAAAAaaAAAaAAaAAaaaAAaaaaaaAaaaAAaaAAaAaAaAAAaaAAAaAAaAAaaaAAaaaAaAAAaAaaAaAAa
AAAAaAAaaAAAaAAaaaaAaAaaAaaAaAaaaaaaaAaaAAaAAAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAAAaAaaAAAAaAaaaaaaaAaaAAaaaaAaaAaaAAAa
AaAaaAAaAaaaaAAaaaAaAAAaAaAaaAAaaaaaaAaaAaAaaAAaaaAAaAAaAaAaaAAaAaAAaAAaAaAaaAAa
aAAAaAAaaaAaAAAaAAaaAAAaaaaaaAaaaAAaaAAaAAAAaAAaaAaaAAAaaaaaaAaaaaAaaAAaAaaAaAAa
AAaaAAAaaaaaAAAaaaAAaAAaAaaaaAAaAaaAAAAaAaaAaAAaaAAAaAAaAAAaaAAaaaaaaAaaAAAAaAAa
AaAaAAAaaaAaAAAaaaaaAAAaAaAaAAAaaaAaAAAaaaaaaAaaAaaaaAAaaAAAaAAaaaAaaAAaaaaaaAaa
AAAAaAAaaAAaAAAaAaAaaAAaaAaaAAAaaaAAaAAaAaaaaAAaAaaAAAAaaAaAaaaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaAAaAAaAaAaaAAaaaAaAAAaaaaaaAaa
AAAAaAAaAaAaAAAaaaAaAAAaaaaaAAAaAaAaAAAaaaAaAAAaaaAaaaAaAaaAaAAaaAAaAAAaaaaaaAaa
AaAAAAaaaaaaaAaaaaAaaAAaAAAAaAAaAAaaaAAaAaAaAAAaAaAAaAAaAaAaaAAaaAAAaAAaaaAaAAAa
aAAAaAaaAAaaaAAaaAaaAAAaAaAaaAAaAaaaaAAaaaAaAAAaAaAaaAAaAaAaaaAaaaAAaAAaAaAaaAAa
AaAAaAAaAaAaaAAaaAAAaAAaaaAaAAAaaaaAaAaaaAaaaAaaaaAaaAAaAaaAaAAaaAAaAAAaaAaaaAaa
AaaAaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaAAAAaAAaAaAaAAAaaaAaAAAaaaaaAAAaAaAaAAAaaaAaAAAaaaAaaaAaAaaAaAAaaAAaAAAa
aAAAaAaaAAaaAAAaaaAaAAAaAaaAAAAaaaAAaAAaAaAaaAAaaaaaaAaaAaAAAAaaaaaaaAaaaAaaaAaa
aAaaaAAaAaaaaAAaAAaaaAAaAAaAaAAaAAAaaAAaaAaaAAAaAAAAaAAaAaAaAAAaaAAAaAAaaaAaaAAa
AaAAaAaaAAaaaAAaAAAAaAAaaaAAaAAaAAAAaAAaaAaaAAAaaAaAAAaaAAaaaAaaaAAaaAAaaAAaaAAa
aAAaaAAaAAaAAAaaAAaaaAAaAAAAaAAaaaAAaAAaAAAAaAAaaAaaAAAaaAaAAAaaAAaaaAaaaaaaAAaa
aaaaAAaaaaaaAAaaAAaAAAaaaaaaAAAaAaaaaAAaaaAaaAAaaaAaaAAaAaaAaAAaaAAAaAAaAAAaaAAa
aAaAAAaaAaaaAAaaAaAaaAAaAaAAaAAaAAaAAAaaaAaaaAAaAAAAaAAaaAaaAAAaaaAaaAAaAaAaaAAa
aAaaAAAaAaAAaAaaaAaaAAAaAaaaaAAaaaAaaAAaAaaAaAAaAaAaAAAaAAaaAAAaaAaAAAaaaaaaAAaa
aAAAaAaaAAAaAAaaAaAaaAAaAaAAaAAaAAaAAAaaaAaaaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaAAaAAaAaAaaAAaaaAaAAAaaaaaaAaa
AAAAaAAaaAAaAAAaAaAaaAAaaAaaAAAaaaAAaAAaAaaaaAAaAaaAAAAaaaAaaaAaAaaAaAAaaAAaAAAa
aaaaaAaaAaAAAAaaaaaaaAaaaaAaaAAaAAAAaAAaAAaaaAAaAaAaAAAaAaAAaAAaAaAaaAAaaAAAaAAa
aaAaAAAaaAAAaAaaAAaaaAAaaAaaAAAaAaAaaAAaAaaaaAAaaaAaAAAaAaAaaAAaAaAaaaAaaaAAaAAa
AaAaaAAaAaAAaAAaAaAaaAAaaAAAaAAaaaAaAAAaaaaAaAaaaAaaaAaaaaAaaAAaAaaAaAAaaAAaAAAa
aAaaaAaaAaaAaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaAAAAaAAaaAAaAAAaAaAaaAAaaAaaAAAaaaAAaAAaAaaaaAAaAaaAAAAaaaAaaaAa
AaaAaAAaaAAaAAAaaAAAaAaaAAaaAAAaaaAaAAAaAaaAAAAaaaAAaAAaAaAaaAAaaaaaaAaaAaAAAAaa
aaaaaAaaaAaaaAaaaAaaaAAaAaaaaAAaAAaaaAAaAAaAaAAaAAAaaAAaaAaaAAAaAAAAaAAaAaAaAAAa
aAAAaAAaaaAaaAAaAaAAaAaaAAaaaAAaAAAAaAAaaaAAaAAaAAAAaAAaaAaaAAAaaAaAAAaaAAaaaAaa
aaaaAAaaaaaaAAaaaaaaAAaaaAaaaAAaAAaAAAaaaaaaAAAaAAAAaAAaAAaaAAAaAaaAaAAaaaAaAAAa
AaaAaAAaAAAAaAAaaAAAaAAaaAaAAAaaaAAaaAAaAaaAaAAaaaaAAAAaAaAaaAAaaaAaaAAaAAaAAAaa
AaaAaAAaaAAAaAAaAAaaAAAaAaAaaAAaaaAaAAAaaAaAAAaaaaaaAAaaAAaAAAaaaaAaaAAaAaaAaAAa
AAaaAAAaaaaaAAAaaaAAaAAaAaaaaAAaAaaAAAAaaAaAAAaaaAAaaAAaaaAAaAAaAaAaaAAaaaaAAAAa
AAaAAAaaAaaaaAAaaaAAaAAaAaaAaAAaAAAaaAAaaAAAaAAaAaAAaAaaAaaAaAAaaaAaAAAaAaAaaAAa
AaAAaAAaAAaaAAAaaAaAAAaaAAaaaAAaAaAaaAAaaAAAaAAaaaAaAAAaAaAaaAAaaAaaAAAaAAaAAAaa
aAaAaAAaAaAaAAAaAAaaAAAaaaAaAAAaAaaAaAAaaAAaaAAaAaaAAAAaAaAAaAaaAAaaaAAaAAAAaAAa
aAAAaAAaaaAaAAAaAaAaaAAaaAAAaAAaaaAaAAAaaAaAAAaaAAaaaAAaAaAaaAAaaAAAaAAaaaAaAAAa
AaAaaAAaaAaaAAAaAAaAAAaaaAaaaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAAAaAAaaAAaAAAaAaAaaAAaaAaaAAAaaaAAaAAaAaaaaAAa
AaaAAAAaaaAaaaAaAaaAaAAaaAAaAAAaaAAAaAaaAaaaaAAaaaaaAAAaaaaaAAAaAaAaaAAaaAAAaAAa
aaAaaAAaaaaAaAaaAAAAaAAaAaAaAAAaaaAaAAAaaaaaAAAaAaAaAAAaaaAaAAAaaaAaaaAaAaaAaAAa
aAAaAAAaAaaAaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaAaaAAaAAAAaAAaAAaaaAAaAaAaAAAaAaAAaAAaAaAaaAAaaAAAaAAaaaAaAAAa
aAAAaAaaaAaaaAAaAAAAaAAaaaAaaAAaAaaAAAAaaAAAaAaaaaaaAAAaAaaaaAAaaAaaAAAaAaAaaAAa
aAAAaAAaaaAaAAAaAaAaaaAaaaAAaAAaAaAaaAAaAaAAaAAaAaAaaAAaaAAAaAAaaaAaAAAaaAAAaAaa
AaaaaAAaaaaaAAAaaaaaAAAaAaAaaAAaaAAAaAAaaaAaaAAaaaaAaAaaAAAAaAAaaAAaAAAaAaAaaAAa
aAaaAAAaaaAAaAAaAaaaaAAaAaaAAAAaaaAaaaAaAaaAaAAaaAAaAAAaAaaAaAaaAAaAAAaaaAaAaaaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAAAaAAaAaAaAAAa
aaAaAAAaaaaaAAAaAaAaAAAaaaAaAAAaaaAaaaAaAaaAaAAaaAAaAAAaaAAAaAaaAaaAaAAaaAAAaAAa
aAAAaAAaAaAaaAAaaAaaAAAaaaaAaaAaaaAaAaAaAaAAaaAaaaAAaaAaaaaaaAaaAaAAAAaaaaaaaAaa
aAaaaAaaAAAaaaAaAaAaAAAaAaAaaAAaAAaaAAAaAAaaAAAaAaaAaAAaaAAAaAAaAAAaaAAaaaaaaAaa
AaaAaAAaaAAAaAAaaaaaaAaaaaaaAAAaaAaaAAAaAAAAaAAaAAAaaAAaaAaaAAAaAaAaaAAaAAaaAAAa
AAaaAAAaaAaaaAaaAAaAAAaaaAaAaaaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaAAAAaAaaAAAAaAaaaaaaaAaaAAaaaaAaaAaaAAAaAaAaaAAaAaaaaAAa
aaAaAAAaAaAaaAAaaaaaaAaaAaAaaAAaaaAAaAAaAaAaaAAaAaAAaAAaAaAaaAAaaAAAaAAaaaAaAAAa
AAaaAAAaaaaaaAaaaAAaaAAaAAAAaAAaaAaaAAAaaaaaaAaaAAaaaAAaaaAAaAAaAAAAaAAaAAaaAAAa
AaAaaAAaaaaaaAaaaAaaaAAaAaAaAAAaaaAaAAAaaaAaAAAaAAAAaAAaaAAAaAAaaaaaaAaaAaaaaAAa
aAAAaAAaaaAaaAAaaaaaaAaaAaaAaAAaaAAaaAAaaAaaAAAaAaaaaAAaAaAAaAAaAaAaaAAaaAaAaaaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaAAaAAaAaAaaAAa
aaAaAAAaaaaaaAaaAAaaaAAaaaAAaAAaAAAAaAAaAAaaAAAaAaAaaAAaaAaaaaAaaaAaAAAaaAAAaAAa
aaAaaaAaAaaAaAAaaAAaAAAaaaaaaAaaAaAAAAaaaaaaaAaaaaAaaAAaAAAAaAAaAAaaaAAaAaAaAAAa
AaAAaAAaAaAaaAAaaAAAaAAaaaAaAAAaaAAAaAaaAAaaaAAaaAaaAAAaAaAaaAAaAaaaaAAaaaAaAAAa
AaAaaAAaAaAaaaAaaaAAaAAaAaAaaAAaAaAAaAAaAaAaaAAaaAAAaAAaaaAaAAAaaaaAaAaaaAaaaAaa
aaAaaAAaAaaAaAAaaAAaAAAaaAaaaAaaAaaAaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaAAaAAaAaAaaAAaaaAaAAAaaaaaaAaaAAaaaAAa
aaAAaAAaAAAAaAAaAAaaAAAaAaAaaAAaaAaaaaAaaaAaAAAaaAAAaAAaaaaaaAaaAaAAAAaaaaaaaAaa
aaAaaAAaAAAAaAAaAAaaaAAaAaAaAAAaAaAAaAAaAaAaaAAaaAAAaAAaaaAaAAAaaAAAaAaaAAaaaAAa
aAaaAAAaAaAaaAAaAaaaaAAaaaAaAAAaAaAaaAAaAaAaaaAaaaAAaAAaAaAaaAAaAaAAaAAaAaAaaAAa
aAAAaAAaaaAaAAAaaaaAaAaaaAaaaAaaaAaaaAAaAaAaAAAaaaAaAAAaaaAaAAAaAAAAaAAaaAAAaAAa
aAaaaAaaAaaAaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaAAaaaAAaaaAAaAAaAAAAaAAaAAaaAAAaAaAaaAAaaAaaaaAaaaAaAAAaaAAAaAAa
aAAAaAaaAaaAaAAaaAAAaAAaaAAAaAAaAaAaaAAaaAaaAAAaaaaAaaAaaaAaAaAaAaAAaaAaaaAAaaAa
aaaaaAaaAaAAAAaaaaaaaAaaaAaaaAaaAAAAaAAaAAaAaAAaaAaaaAaaAAaAAAaaaAaAaaaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAaaaAAaaaAAaAAaAAAAaAAa
AAaaAAAaAaAaaAAaaAaaaaAaaaAaAAAaaAAAaAAaaaAaaaAaAaaAaAAaaAAaAAAaaAAAaAaaAaaaaAAa
aaaaAAAaaaaaAAAaAaAaaAAaaAAAaAAaaaAaaAAaaaaAaAaaAAaaaAAaaaAAaAAaAAAAaAAaAAaaAAAa
AaAaaAAaaAaaaaAaaaAaAAAaaAAAaAAaAaaAaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAaaaAAaaaAAaAAaAAAAaAAaAAaaAAAaAaAaaAAa
aAaaaaAaaaAaAAAaaAAAaAAaaAAAaAaaAAAAaAAaaAAAaAAaAAaaaAAaaaAAaAAaAaaAaAAaAAaaaAAa
AAaAaAAaaaaaaAaaAaAAAAaaaaaaaAaaAAAAAaAaaaaaaAaaAaAAAAaaaAAAAAaaaaaaaAaaAAAAaAAa
aAAaAAAaAaAaaAAaaAaaAAAaaaAAaAAaAaaaaAAaAaaAAAAaaaAaaaAaAaaAaAAaaAAaAAAaaAAAaAaa
aAaaAAAaAaAaaAAaAaAAaAAaAAAAaAAaaAAaAAAaAaAaaAAaaaaAaAaaAaaAaAaaAAaAAAaaaAaAaaaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaAAaAAaAaAaaAAa
aaAaAAAaaaaaaAaaAaaAaAAaaAAaaAAaaAaaAAAaAaaaaAAaAaAAaAAaAaAaaAAaaaaaaAaaAaAAAAaa
aaaaaAaaaaAaaAAaAAAAaAAaAAaaaAAaAaAaAAAaAaAAaAAaAaAaaAAaaAAAaAAaaaAaAAAaaAAAaAaa
AAaaaAAaaAaaAAAaAaAaaAAaAaaaaAAaaaAaAAAaAaAaaAAaAaAaaaAaaaAAaAAaAaAaaAAaAaAAaAAa
AaAaaAAaaAAAaAAaaaAaAAAaaaaAaAaaaAaaaAaaAaaAaAAaaAAaaAAaaAaaAAAaAaaaaAAaAaAAaAAa
AaAaaAAaaAaaaAaaAaaAaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaAaaAaAAaaAAaaAAaaAaaAAAaAaaaaAAaAaAAaAAaAaAaaAAaaAAAaAaa
AAaaAAAaaaAaAAAaAaaAAAAaaaAAaAAaAaAaaAAaaAAAaAaaaaAaaAAaAaaAaAAaAAaaAAAaaaaaAAAa
aaAAaAAaAaaaaAAaAaaAAAAaaaaaaAaaAaAAAAaaaaaaaAaaaAaaaAaaaAAAaAAaAAAAaAAaaAAAaAAa
AaAaaAAaaAaaaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaAaaAaAAaaAAaaAAaaAaaAAAaAaaaaAAaAaAAaAAaAaAaaAAaaAAAaAaaAAaaAAAa
AaAaaAAaaaAaAAAaAaaaaaAaaaAaAAAaaaAaAAAaaAaaAAAaAaaAaAAaaAaaaAAaAaAaAAAaaaAaAAAa
AaAaaAAaaaaAaAaaaAaaaAaaAAaaAAAaaAaaAAAaAAaaaAAaaAaaaAaaaaAAaAaaaaaaaAaaaAaaaAaa
aaaAaAAaaaAaAAAaaaAaAAAaaaaaAAAaAAaaAAAaaAaAAAaaAAAAaAaaAAAAaAaaAaaaaAAaAaaAaAAa
AAaaaAAaAAAaaAAaAaaaaAAaaAAAaAaaAAAaaAAaaAaaAAAaAaAaaAAaAaaaaAAaaaAaAAAaAaAAaAaa
AAaaAAAaAaaAaAAaaaAaAAAaAaAaaAAaaAAAaAaaaAAAaAAaAaAaaAAaaaAaAAAaAAAAaAaaAAAaaAAa
AaAaAAAaAaAaaAAaAAaaAAAaAAaaAAAaAAAaaAAaaaaaAAAaaaAaAAAaAAAAaAaaaAaaaAAaaAaaAAAa
AaaAaAAaaaAaaAAaAAAaaAAaAaAaaAAaaAAAaAaaaaaAaAAaaaAaAAAaAaAAaAAaaaAAaAAaaAaaaAaa
AaaAaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaAAAAaAAaAaAaAAAaaaAaAAAaaaaaAAAaAaAaAAAaaaAaAAAaaaAaaaAaAaaAaAAaaAAaAAAa
aAAAaAaaAaaaaAAaaaaaAAAaaaaaAAAaAaAaaAAaaAAAaAAaaaAaaAAaaaaAaAaaAaaAaAAaaAAaaAAa
aAaaAAAaAaaaaAAaAaAAaAAaAaAaaAAaAaaAaAaaAAaAAAaaaAaAaaaaaAaAaaaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAAAaAaaAAAAaAaaaaaaaAaaAAAaAaAa
AaaaaAAaAaaAaAAaaaAaAAAaaaaaaAaaaAAaaAAaAAAAaAAaaAaaAAAaaaaaaAaaaaAaAAAaaaaAaAAa
AaAaaAAaaaaaaAaaAaaAaAAaaAAaaAAaaAaaAAAaAaaaaAAaAaAAaAAaAaAaaAAaaaaaaAaaaaAaAAAa
AAAAaAAaaaaaaAaaaaAAaAAaAAAAaAAaAaaaaAAaaaAaaAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAaaaaAAaAAAaAAAaAaaaaAAaAaaAaAAaaaAaAAAa
aaaaaAaaaaaAaAaaaAAAaAAaAaAaaAAaAAAaAAAaaaaaaAaaaaaaAaAaaAaaAAAaAAAAaAAaAaAAaAAa
AaaAaAAaAAaaAAAaAaAaaAAaaaaAaAaaaaaAaAaaaAaaAAAaAaAaaAAaAAaaAAAaAAAAaAAaaaAAaAAa
aAAaAAAaAaAaaAAaAaaAaAaaaaaaaAaaAaAAAAaaaAAAAAaaaaaaaAaaAAaAAAAaaAaAaaaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaAaaAaAAaaAAaaAAaaAaaAAAaAaaaaAAaAaAAaAAaAaAaaAAaaAAAaAaaAAAAaAAaaAAAaAAa
aaAAaAAaAAAAaAAaAaaaaAAaaaAaaAAaaaaaaAaaAaAAAAaaaaaaaAaaaaaAaAaaAaaAaAaaaaaaaAaa
AaAAAAaaaAAAAAaaaaaaaAaaAAaAAAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaAaaAAAaAaAaaAAaAAaaAAAaAAAAaAAaaaAAaAAaaAAaAAAaAaAaaAAaaaaAaAaaAaaAaAaa
AAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAaAAAAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAaAAAAAaAaaAaAaaAaaAaAaaAAaAAAaaaAaAaaaaaAaAaaaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaAaAAAaaAaaAAAa
AaaAAAAaaaaaaAaaAAaAAAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAAAaAaaAAAAaAaaaaaaaAaaAAaaAaAa
AaAaaAAaaAAAaAAaaaAaaAAaaaaaaAaaAaaaaAAaaaaaaAaaAaAAaAAaAaAaaAAaAAaaAAAaAAaaAAAa
AaaaaAAaAAAaaAAaAaAaaAAaaaaaaAaaaaAaAAAaAAAAaAAaaaaaaAaaaaAaAAAaaaaAaAAaAaAaaAAa
aaaaaAaaAaaAaAAaaAAaaAAaaAaaAAAaAaaaaAAaAaAAaAAaAaAaaAAaaaaaaAaaAAAaAAAaAaaAaAAa
aaAaAAAaaaaAaAAaaaaaaAaaaAAAaAAaAaAaaAAaAAaaaAAaAaAaaAAaAAaaAAAaAAaaAAAaAaaaaAAa
aAaaAAAaAaaAAAAaaaaaaAaaaaAaaAAaAaaaaAAaaaAaAAAaAaaaaAAaaAaAaaaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaAAaAAaAaAaaAAaaaAaAAAaaaaaaAaaAaAAaAAaAaAaaAAaAAaaAAAaAAaaAAAaAaaaaAAaAAAaaAAa
AaAaaAAaAAaaaaAaaaaAaAAaAaaaaAAaaAAAaAAaaAAAaAAaAaAaaAAaaaAAaAAaaaaaaAaaAaAAAAaa
aaaaaAaaaAAAaAAaAaAaaAAaAAAaAAAaaaaaaAaaAaAAaaAaAaAaaAAaAAaaAAAaAAaaAAAaAaaaaAAa
AAAaaAAaAaAaaAAaAAaaaaAaaaaAaAAaAaaaaAAaaAAAaAAaaAAAaAAaAaAaaAAaaaAAaAAaaaaAaAaa
AaaAaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAaaAaAAaaAAaaAAaaAaaAAAaAaaaaAAaAaAAaAAa
AaAaaAAaaAAAaAaaAAaaaAAaAAAAaAAaaAAAaAAaaaAaAAAaAaAaaAAaaAAAaAAaaaAaAAAaAAAaAaAa
AaaAaAAaaAAAaAAaaaAaaAAaAAAAaAAaAAAaAAAaaAAAaAaaaaaaAAAaAAAAaAAaAAaaAAAaaaAaAAAa
AaAAaaAaAaAaaAAaAAaaAAAaAAaaAAAaAaaaaAAaAAAaaAAaAaAaaAAaaaaAaAaaAAaAAAAaaaAaAAAa
AaaAAAAaaaaaAAAaAaAaaAAaaAaAAAaaaaaaaAaaaAaaaAaaAaaaaAAaAaaAaAAaAaAAaAaaaAaaAAAa
AaAaaAAaAaaaAAAaAaAaAAAaAaAaaAAaAAaaAAAaaaAaAAAaaAaaaAaaaaAAaAaaaaaaaAaaAaAAaAAa
AAaaAAAaAAAaaAAaaAaAAAaaaaaaaAaaAAaAAAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaAAAAaAAaaAaaAAAaAaaAaAAaAAAaaAAaAaaAaAAaaAAAaAAaaAaAAAaaaaaaaAaa
aaAaaAAaAAAAaAAaAAaaaAAaAaAaAAAaAaAAaAAaAaAaaAAaaAAAaAAaaaAaAAAaaAAAaAaaaaAAaAAa
AAAAaAAaAAaaaAAaAaaaaAAaaaAaAAAaAaaAaAAaAAAAaAAaaAAAaAAaaAAAaAaaAAAAaAAaaAaaAAAa
AaaAaAAaAAAaaAAaAaaAaAAaaAAAaAAaaaAAaAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaAaaAAAaAAAAaAAaAaAaAAAaaAAAaAAaaaAaaAAaaAaAAAaaaaaaaAaaaaAaaAAa
AAAAaAAaAAaaaAAaAaAaAAAaAaAAaAAaAaAaaAAaaAAAaAAaaaAaAAAaaAAAaAaaaaAAaAAaAAAAaAAa
AAaaaAAaAaaaaAAaaaAaAAAaAaaAaAAaAAAAaAAaaAAAaAAaaAAAaAaaaaaaAAAaAaaaaAAaaaAaAAAa
aaaAaAAaaAAAaAAaAaaaaAAaAaAAaAAaAaAaaAAaaAAAaAaaAaAAaAAaAaaaaAAaaaAaAAAaAAaaaAAa
aaaAaAAaaaaAaAaaAAAAaAaaaaaAaAaaAAaAAaAaaaaaAAaaAaAAaAaaAaaAAAaaAaAAAaAaAAaAaAaa
AaaAaAaaAAAAaAaaAaaAaAaaAAaAAaAaaaaaAAaaAaAAAaAaaaaaaAaaAaAAaAaaaaaaaAaaaaaaAAaa
aaAAaAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAAaaAAaAaAaAAAa
AaAaaAAaAAaaAAAaAAaaAAAaAaAaaAAaAAaaAAAaaAaAAAaaaaaaaAaaAAaAAaAaaAAAaAaaaAAAaAaa
aAAAaAaaaaaaAAAaaaAAaAAaAaaaaAAaAaaAAAAaAaAaaAAaaAaaAAAaAAaaAAAaaAAAaAaaAAaaaAAa
aaaAaAAaAaaAaAAaaaAAaAAaaaAaaAAaaAaaAAAaAaAaaAAaaAAAaAAaAaAAAaAaaAAAaAaaAaAAaAAa
AaaaaAAaaaaaAAAaaaaAaAaaAaAaaAAaaaaaaAaaAaAAAAaaaAAAAAaaaaaaaAaaaaaAaAaaAAaAAAAa
aAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaAaaAaAAaaaAaaAAaaAaAAAaaaaaaaAaaAaAaaAAaaAAAaAaaAAAaaAAaAaAaaAAaaaAaAAAa
AaaaaaAaaaAaAAAaaaAaAAAaaAaaAAAaAaaAaAAaaAaaaAAaAaAaAAAaaaAaAAAaAaAaaAAaaaaAaAaa
AAAaaAaaaaAaaAAaAaaaaAAaaaAaAAAaAaaaaAAaAaAAaAaaAaaAaAAaaaAaaAAaAAAaaAaaAaaAaAaa
aaAAaAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaAAaAAaAaaaaAAaaAaaaAAaAaAaaAAaaaAAaAAaaAaAAAaaaaaaaAaaAaAaaAAa
aAAAaAaaAAAaaAAaAaAaaAAaaaAaAAAaAaaaaaAaaaAaAAAaaaAaAAAaaAaaAAAaAaaAaAAaaAaaaAAa
AaAaAAAaaaAaAAAaAaAaaAAaaaaAaAaaAAAaaAaaaaAaaAAaAaaaaAAaaaAaAAAaAaaaaAAaAaAAaAaa
AaaAaAAaaaAaaAAaAAAaaAaaAaaAaAaaaaaaaAaaAaAAAAaaAaAAAAaaaaaaaAaaAAAaaAaaAaAAaAAa
AaAaaAAaAAAaaAaaaaaaaAaaAAAAAAaaaaaaaAaaAaAaaAAaaAAAaAaaAaaAaAAaaAAAaAAaaAAAaAAa
AaAaaAAaaAaaAAAaaaAaAaAaAaAaaAAaaaaAAAAaaaAaAAAaaAAAaAaaAaAAaAAaAaaaaAAaaaAaAAAa
AAaaaAAaaaaAaAAaaaaAaAaaAAAAaAaaaAAAAaAaaaaAaAaaaAAAaAaaaAaAaAaaAaaAaAaaaaaaaAaa
aaAAAaAaaaaAaAaaAaaAAAAaAAAAaAAaAaAaAAAaAaaaaAaaaaAAAaAaAaaAaAaaaaAaaAaaAAAAaAaa
AaaAaAaaAAaAAaAaAaaaAAaaAaAAAaAaaaaaaAaaaAaAAAaaaaaaaAaaAaAaaAAaaAAAaAaaAaaaAAAa
AaAaAAAaAaAaaAAaaAaaAAAaAaaAAAAaAAaaAaAaAaAaaAAaaaAAaAAaAaAaaAAaAAaaaAAaaaAaAAAa
AAAAaAAaaAaaAAAaaaaAaAaaaAaaaAaaAaaaaAAaaAaaaAaaAaaAaAaaaAAAaAaaAaaAaAAaaAAAaAAa
aAAAaAAaAaAaaAAaaAaaAAAaaaAaAaAaAaAaaAAaaaaAAAAaaaAaAAAaaaAAaAaaaAaAaaaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaAAaAAa
AAAAaAAaAAaaaAAaAAaAaAAaAaAaaAAaaaAaaAAaaAaAAAaaaaaaaAaaAaAaaAAaaAAAaAaaAAaaaAAa
aaAAaAAaAaaaaAAaAAaaAAAaAAaaAAAaaaAAaaAaAaaAaAAaAAaaAAAaaaAaAAAaaAAAaAaaAAaaaAAa
AAAAaAAaaAAAaAAaaaAaAAAaAaaaaAAaAaaAaAAaaAAAaAAaAAaaAAAaaaaAaAaaaAaaaAaaaaAAaAAa
AAAAaAAaAAaaaAAaAAaAaAAaAaAaaAAaaaAaaAAaaAaaaAaaAaaAaAaaaAaAaaaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAaAAAAAaAaaAaAaaAaaAaAaaaaAAaAaaaAaAaaaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAaaaaAAaaAAAaAAaAaaaaAAaaaAAaAAaAaaAAAAa
aaAaAAAaAaaAaAAaAAaaaAAaAAaaAAAaaAaAAAaaaaaaaAaaaaAaaAAaAAAAaAAaAAaaaAAaAaAaAAAa
AaAAaAAaAaAaaAAaaAAAaAAaaaAaAAAaaAAAaAaaaAaaaAAaAAAAaAAaaaAaaAAaAaaAAAAaaAAAaAaa
aaaaAAAaAaaaaAAaaAaaAAAaAaAaaAAaaAAAaAAaaaAaAAAaAaAaaaAaaaAAaAAaAaAaaAAaAaAAaAAa
AaAaaAAaaAAAaAAaaaAaAAAaaAAAaAaaAaaAaAAaaAAAaAAaaAAAaAAaAaAaaAAaaAaaAAAaaaaAaaAa
aaAaAaAaAaAAaaAaaaAAaaAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAaAAAAAaAaAAAAAaaaAAaAaaaaaaaAaa
aAaaaAaaaAaAaAaaaAaaaAaaaaAAaAaaaaaaaAaaAAaAAaAaAaAAaAAaAaAaaAAaAAaaAAAaAAaaAAAa
AaaaaAAaAAAaaAAaAaAaaAAaAAaaaaAaaaaAaAAaAaaaaAAaaAAAaAAaaAAAaAAaAaAaaAAaaaAAaAAa
aAAAaAaaaaaaAAAaAAAAaAAaaAaaAAAaaaAaAAAaaAaaAAaaAaAAAaAaAaaAaAaaAAaAAAaaaAaAaaaa
aAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaAAAAaAaaAAAAaAaaaaaaaAaaaaaAaaAaAaaaaAAaaAAAaAAaaaAaaAAa
aaAAaAAaAaAaaAAaaaaaaAaaaaAaAAAaaaaAaAAaAaAaaAAaaaaaaAaaaAaaAAAaAaAaaAAaAAaaAAAa
aaaaAAAaAAAAaAAaaAAAaAAaAAaaAAAaAaAaaAAaaaaaaAaaaAAaaAAaaAaaAAAaAAAAaAAaAaAAaAAa
aaaaaAaaaaAaAAAaaaaAaAAaAaAaaAAaaaaaaAaaAaaAaAAaaAAaaAAaaAaaAAAaAaaaaAAaAaAAaAAa
AaAaaAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaAAaAAaAaAaaAAaaaAaAAAaaaaaaAaaAaAAaAAaAAaaAAAa
AAAaaAAaaaaaaAaaAaAAAAaaaaaaaAaaAaaaaAAaAAAaAAAaAaaaaAAaAaaAaAAaaaAaAAAaaaaaaAaa
aaaAaAaaaAAAaAAaAaAaaAAaAAAaAAAaaaaaaAaaaaaaAaAaaAaaAAAaAAAAaAAaAaAAaAAaAaaAaAAa
AAaaAAAaAaAaaAAaaaaAaAaaaaaAaAaaaAaaAAAaAaAaaAAaAAaaAAAaAAAAaAAaaaAAaAAaaAAaAAAa
AaAaaAAaaaAAaAaaaaaaaAaaaAaaAAAaAaAaaAAaaAaAaAAaAaAaaAAaAAaaaAAaaaAaAAAaAaaAaAaa
aaaaaAaaAaAAAAaaaAAAAAaaaaaaaAaaAAaAAAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaAaAAaAAaAaAaaAAaAAaaAAAaAAaaAAAaAaaaaAAaAAAaaAAaAaAaaAAaAAaaaaAa
aaaAaAAaAaaaaAAaaAAAaAAaaAAAaAAaAaAaaAAaaaAAaAAaaAAAaAaaaaaaAAAaAAAAaAAaaAaaAAAa
aaAaAAAaAaaaAAaaaAAAaAaaAAAAaAAaaAAAaAAaAaAAaAAaAaAaaAAaAAaaAAAaAAaaAAAaAaaaaAAa
AAAaaAAaAaAaaAAaaaaaaAaaAaAAAAaaaaaaaAaaaaaAaAaaAaAaaAAaAaaAaAaaaaaaaAaaAaAAAAaa
aAAAAAaaaaaaaAaaAAaAAAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAaaAaAAaaAAaaAAaaaaaaAaaaaaAaAaaAaAaaAAaaAAAaAaa
aaAaaAAaAaaaaAAaaaAaAAAaAaaaaAAaaAAAaAaaAAaaAAAaaaAaAAAaAaaaaAAaaaAaAAAaAaAaAAAa
AAaaAAAaAaaAaAaaaaaaaAaaAAaAAAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaAaaAAAa
AaAaaAAaAAaaAAAaAAAAaAAaaaAAaAAaaAAaAAAaAaAaaAAaaaaAaAaaAaAaaAAaaAAAaAaaaaAaaAAa
AaaaaAAaaaAaAAAaAaaaaAAaaAAAaAaaAaAAaAAaAAaaAAAaAAAaaAAaAaaAaAaaAAaAAAaaaAaAaaaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
AaAAAAAaaaaaaAaaAaAaaAAaaaAAaAAaAAaaAAAaAaAaaAAaaaaaaAaaAAaAAAAaaAaAaaaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaAaaAAAaAaAaaAAaaAaAaAAaAaAaaAAaAAaaaAAaaaAaAAAaaaaAaAaa
aAaaaAaaAAAAaAAaAAAAaAAaaaaaAAAaAAaaAAAaaAaaaAaaAaaAaAaaAAaAAAaaaAaAaaaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAaAAAAAa
aAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAaAAAAAaaAaAaaaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaAaAAAAAaAaaAaAaaAaaAaAaaAAaAAAaaaAaAaaaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAAAaAaa
AAAAaAaaaaaaaAaaaaaaAaAaaAaaAAAaAAAAaAAaAAaaaAAaAaAaaAAaAAaaAAAaAAaaAAAaaaaaaAaa
aaAaAAAaaaaAaAAaAaAaaAAaaaaaaAaaaAaaAAAaAaAaaAAaAAaaAAAaaaaaAAAaAAAAaAAaaAAAaAAa
AAaaAAAaAaAaaAAaaaaaaAaaAaaaaAAaaAAAaAAaaaAaaAAaaaaaaAaaAaAaAAAaaaaaAAAaaaAaaAAa
AaaaaAAaaaAaAAAaAaAaaAAaaaaaaAaaaaAaAAAaaaaAaAAaAaAaaAAaaaaaaAaaAAAAaAAaAaAaAAAa
aaAaAAAaaaaaAAAaAaAaAAAaaaAaAAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAaaAAAaAAAAaAAaaAaaAAAa
aaAaAAAaAaaaaAAaaAaaaAAaaaAAaAAaAaAaaAAaaAAAaAaaAAaaAAAaAAAAaAAaaAaaAAAaaaAaAAAa
aaaAaAaaAaAAaAAaAAaaAAAaAAAaaAAaaaAAaAaaaaaaaAaaaaAaAAAaaAaaAAAaAaAaAAAaAaAaaAAa
AaaAaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAaaAAAaAAAAaAAaaAaaAAAaaaAaAAAaAaaaaAAa
aAaaaAAaaaAAaAAaAaAaaAAaaAAAaAaaAAAAaAAaaaaaAAAaaaAaAAAaAaaAaAAaAAAAaAAaaAAAaAAa
aaaAaAaaaAaaaAaaAAAAaAAaaAAAaAAaAAaaAaAaAAAAaAAaaAaaAAAaaaAaAAAaaAaaaAaaAaaAaAaa
aaaAaAaaAaaAaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAAAaAAaAaAaAAAaaaAaAAAaaaaaAAAa
AaAaAAAaaaAaAAAaaaAaaaAaAaaAaAAaaAAaAAAaaAAAaAaaAaaAaAAaaAAAaAAaaAAAaAAaAaAaaAAa
aAaaAAAaaaaAaaAaaaAaAaAaAaAAaaAaaaAAaaAaaaaaaAaaAaAAAAaaaaaaaAaaaAaaaAaaAAaaAaAa
AaAaAAAaAAaaaAAaAAaaaAAaAaAaaAAaAAaaAAAaAAaaAAAaaAAAaAaaaAaaaAaaAAaAAAaaaAaAaaaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaAAAAaAAaAaAaAAAaaaAaAAAaaaaaAAAaAaAaAAAaaaAaAAAaaaAaaaAaAaaAaAAa
aAAaAAAaaAAAaAaaAaaaaAAaaaaaAAAaaaaaAAAaAaAaaAAaaAAAaAAaaaAaaAAaaaaAaAaaAAaaaAAa
aaAAaAAaAAAAaAAaAAaaAAAaAaAaaAAaaAaaaaAaaaAaAAAaaAAAaAAaaaAaaaAaAaaAaAAaaAAaAAAa
AaaAaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAAAaAAaAaAaAAAaaaAaAAAaaaaaAAAaAaAaAAAa
aaAaAAAaaaAaaaAaAaaAaAAaaAAaAAAaaAAAaAaaAaaaaAAaaaaaAAAaaaaaAAAaAaAaaAAaaAAAaAAa
aaAaaAAaaaaAaAaaAaaAaAAaaAAaaAAaaAaaAAAaAaaaaAAaAaAAaAAaAaAaaAAaAaaAaAaaAAaAAAaa
aAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAaAAAAAa
aaaaaAaaAAaaaAAaAaaaaAAaaaAaAAAaAAaaaAAaaaaAaAAaaaaaaAaaaaaAaAaaAaAaaAAaAaaAaAaa
aaaaaAaaAAaAAAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAAAaAaaAAAAaAaaaaaaaAaaaaaAaaAaAaaaaAAa
aAAAaAAaaaAaaAAaaaAAaAAaAaAaaAAaaaaaaAaaAaAaaAAaaAaaAAAaaAaaAAAaAAAAaAAaaAaaAAAa
AAaaAAAaaaaaaAaaAaaaaAAaaAAAaAAaaaAaaAAaaaaaaAaaAaAaAAAaaaaaAAAaaaAaaAAaAaaaaAAa
aaAaAAAaAaAaaAAaaaaaaAaaaaAaAAAaaaaAaAAaAaAaaAAaaaaaaAaaAAAAaAAaAaAaAAAaaaAaAAAa
aaaaAAAaAaAaAAAaaaAaAAAaaaaaaAaaAaaaaAAaAAaaaAAaAAaaaAAaAAAAaAAaaAaaAAAaaaAaaAAa
AaaAaAAaaAAAaAAaAAAaaAAaaaAAaAAaAaaAAAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAAAaAAaAaAaAAAa
aaAaAAAaaaaaAAAaAaAaAAAaaaAaAAAaaaAaaaAaAaaAaAAaaAAaAAAaaAAAaAaaAaaAaAAaaAAAaAAa
aAAAaAAaAaAaaAAaaAaaAAAaaaaAaaAaaaAaAaAaAaAAaaAaaaAAaaAaaaaaaAaaAaAAAAaaaaaaaAaa
aAaaaAaaaAAaaaAaAaaaaAAaAaaAaAAaaaAAaAAaAaAaaAAaaaAaaAAaaAAAaAaaaAaaaAaaAAaAAAaa
aAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaAAAAaAAaAaAaAAAaaaAaAAAaaaaaAAAaAaAaAAAaaaAaAAAaaaAaaaAa
AaaAaAAaaAAaAAAaaAAAaAaaAaaaaAAaaaaaAAAaaaaaAAAaAaAaaAAaaAAAaAAaaaAaaAAaaaaAaAaa
AAaaaAAaaaAAaAAaAAAAaAAaAAaaAAAaAaAaaAAaaAaaaaAaaaAaAAAaaAAAaAAaaaAaaaAaAaaAaAAa
aAAaAAAaAaaAaAaaAAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
aaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAAAAaAAaAaAaAAAaaaAaAAAaaaaaAAAa
AaAaAAAaaaAaAAAaaaAaaaAaAaaAaAAaaAAaAAAaaAAAaAaaAaaaaAAaaaaaAAAaaaaaAAAaAaAaaAAa
aAAAaAAaaaAaaAAaaaaAaAaaAaaAaAAaaAAaaAAaaAaaAAAaAaaaaAAaAaAAaAAaAaAaaAAaAaaAaAaa
AAaAAAaaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaa
AaAAAAAaaAaAaaaaaaaaaAaaaaaaaAaaaaaaaAaaaaaaaAaaAaAAAAAaaAaAaaaaAaAAAAAaAaaAaAaa
aaaAaAaaAaaAaAaaAAaAAAaaaAaAaaaaaAaAaaaaaAaAaaaaaAaAaaaaaAaAaaaaaAaAaaaaaAaAaaaa
  await await await await await await await await await await await call()}})()

round #56

submitted at
0 likes

guesses
comments 0

post a comment


amogus ELF 64-bit LSB shared object, x86-64, version 1 (SYSV)
amogus.h ASCII text
1
2
typedef void(entry_callback)(char *match, int size, void *data);
int entry(const char *regex, entry_callback *callback, void *data);
amogus.png PNG image data, 720 x 720, 8-bit colormap, non-interlaced

round #55

submitted at
1 like

guesses
comments 0

post a comment


entry.fs ASCII text
  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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
( // Code by olus2000 (UID: 339009650592710656)

FALSE VALUE ENABLE-BUG

BEGIN-STRUCTURE grid
  FIELD: grid.addr
  FIELD: grid.width
  FIELD: grid.height
END-STRUCTURE

BEGIN-STRUCTURE grid-cell
  CFIELD: grid-cell.type
  CFIELD: grid-cell.wseen
  CFIELD: grid-cell.rseen
  CFIELD: grid-cell.invert
END-STRUCTURE

0 CONSTANT GRID-0
1 CONSTANT GRID-/
2 CONSTANT GRID-\
3 CONSTANT GRID-+

CREATE NULL-GRID-CELL grid-cell ALLOT
GRID-0 NULL-GRID-CELL grid-cell.type C!
FALSE NULL-GRID-CELL grid-cell.wseen C!
FALSE NULL-GRID-CELL grid-cell.rseen C!

: grid[] ( n n grid -- grid-cell )
  >R 2DUP 2DUP
  0< 0= SWAP 0< 0= AND SWAP
  R@ grid.height @ < AND SWAP
  R@ grid.width @ < AND 0= R> SWAP
  IF DROP 2DROP NULL-GRID-CELL EXIT THEN
  >R R@ grid.width @ * + grid-cell *
  R> grid.addr @ + ;

10 CONSTANT CHAR-LF

0 VALUE PARSED-GRID
0 VALUE PARSED-STR-ADDR
0 VALUE PARSED-STR-LEN
0 VALUE PARSED-WIDTH
0 VALUE PARSED-HEIGHT
0 VALUE PARSED-MINX
0 VALUE PARSED-MINY

: PARSED-GRID-CELL-TYPE! ( char -- )
  PARSED-WIDTH PARSED-MINX -
  PARSED-HEIGHT PARSED-MINY -
  PARSED-GRID grid[] DUP
  NULL-GRID-CELL = IF 1 ABORT" BONDAGE" THEN
  grid-cell.type C! ;

: ENSURE-UNCHARA ( char -- char )
  DUP CASE
    CHAR-LF OF ENDOF [CHAR] / OF ENDOF
    [CHAR] \ OF ENDOF [CHAR] + OF ENDOF
    BL OF ENDOF 1 ABORT" CHARA"
  ENDCASE ;

: PARSE-GRID ( c-addr u grid -- )
  TO PARSED-GRID TO PARSED-STR-LEN TO PARSED-STR-ADDR
  0 PARSED-GRID grid.height !
  0 PARSED-GRID grid.width !
  0 TO PARSED-WIDTH
  0 TO PARSED-HEIGHT
  PARSED-STR-LEN 0 ?DO
    PARSED-STR-ADDR I CHARS + C@ ENSURE-UNCHARA CASE
      CHAR-LF OF 0 TO PARSED-WIDTH PARSED-HEIGHT 1+ TO PARSED-HEIGHT ENDOF
      BL OF PARSED-WIDTH 1+ TO PARSED-WIDTH ENDOF
      PARSED-WIDTH 1+ DUP TO PARSED-WIDTH
      PARSED-GRID grid.width @ MAX PARSED-GRID grid.width !
      PARSED-HEIGHT 1+ PARSED-GRID grid.height @ MAX PARSED-GRID grid.height !
    ENDCASE
  LOOP
  PARSED-WIDTH TO PARSED-MINX
  PARSED-HEIGHT TO PARSED-MINY
  PARSED-GRID grid.width @ PARSED-GRID grid.height @ 2DROP
  0 TO PARSED-WIDTH
  0 TO PARSED-HEIGHT
  PARSED-STR-LEN 0 ?DO
    PARSED-STR-ADDR I CHARS + C@ CASE
      CHAR-LF OF 0 TO PARSED-WIDTH PARSED-HEIGHT 1+ TO PARSED-HEIGHT ENDOF
      BL OF PARSED-WIDTH 1+ TO PARSED-WIDTH ENDOF
      PARSED-WIDTH PARSED-HEIGHT PARSED-MINX PARSED-MINY 2DROP 2DROP
      PARSED-WIDTH PARSED-MINX MIN TO PARSED-MINX
      PARSED-HEIGHT PARSED-MINY MIN TO PARSED-MINY
      PARSED-WIDTH 1+ TO PARSED-WIDTH
    ENDCASE
  LOOP
  PARSED-MINX NEGATE PARSED-GRID grid.width +!
  PARSED-MINY NEGATE PARSED-GRID grid.height +!
  0 TO PARSED-WIDTH
  0 TO PARSED-HEIGHT
  ALIGN HERE
  PARSED-GRID grid.height @
  PARSED-GRID grid.width @ * >R
  R@ grid-cell * ALLOT
  PARSED-GRID grid.addr !
  R> 0 ?DO
    PARSED-GRID grid.addr @ I grid-cell * + >R
    GRID-0 R@ grid-cell.type C!
    FALSE R@ grid-cell.wseen C!
    FALSE R@ grid-cell.rseen C!
    2 R> grid-cell.invert C!
  LOOP
  PARSED-STR-LEN 0 ?DO
    PARSED-STR-ADDR I CHARS + C@ ENSURE-UNCHARA CASE
      CHAR-LF OF
        0 TO PARSED-WIDTH PARSED-HEIGHT 1+ TO PARSED-HEIGHT FALSE
      ENDOF
      [CHAR] / OF GRID-/ PARSED-GRID-CELL-TYPE! TRUE ENDOF
      [CHAR] \ OF GRID-\ PARSED-GRID-CELL-TYPE! TRUE ENDOF
      [CHAR] + OF GRID-+ PARSED-GRID-CELL-TYPE! TRUE ENDOF
      TRUE
    ENDCASE IF PARSED-WIDTH 1+ TO PARSED-WIDTH THEN
  LOOP ;

BEGIN-STRUCTURE point
  FIELD: point.x
  FIELD: point.y
END-STRUCTURE

CREATE POINT-ZERO point ALLOT 0 0 POINT-ZERO 2!

BEGIN-STRUCTURE grid-cell-def
  point +FIELD grid-cell-def.begin-white-up
  point +FIELD grid-cell-def.begin-white-down
  point +FIELD grid-cell-def.begin-red-up
  point +FIELD grid-cell-def.begin-red-down
  point +FIELD grid-cell-def[0,1]
  point +FIELD grid-cell-def[1,0]
  point +FIELD grid-cell-def[0,-1]
  point +FIELD grid-cell-def[-1,0]
END-STRUCTURE

BEGIN-STRUCTURE grid-cell-defs-t
  grid-cell-def +FIELD grid-cell-defs./
  grid-cell-def +FIELD grid-cell-defs.\
  grid-cell-def +FIELD grid-cell-defs.+
END-STRUCTURE

CREATE GRID-CELL-DEFS grid-cell-defs-t ALLOT

: DIR-FLAT ( n n -- u )
  1+ 3 * SWAP 1+ + ;

: grid-cell-def[] ( n n grid-cell-def -- point )
  >R DIR-FLAT CASE
    0 0 DIR-FLAT OF 0 ENDOF
    0 1 DIR-FLAT OF 4 ENDOF
    1 0 DIR-FLAT OF 5 ENDOF
    0 -1 DIR-FLAT OF 6 ENDOF
    -1 0 DIR-FLAT OF 7 ENDOF
    1 THROW
  ENDCASE point * R> + ;

: 4DUP 2>R 2>R 2R@ 2R> 2R@ 2SWAP 2R> ;

: DEFINE-CELL-CONNECTION ( n n n n grid-cell-def -- )
  >R 4DUP NEGATE SWAP NEGATE SWAP 2SWAP R@ grid-cell-def[] 2!
  2SWAP NEGATE SWAP NEGATE SWAP 2SWAP R> grid-cell-def[] 2! ;

0 1 1 0 GRID-CELL-DEFS grid-cell-defs./ DEFINE-CELL-CONNECTION
0 -1 -1 0 GRID-CELL-DEFS grid-cell-defs./ DEFINE-CELL-CONNECTION
0 -1 SWAP GRID-CELL-DEFS grid-cell-defs./ grid-cell-def.begin-white-up 2!
-1 0 SWAP GRID-CELL-DEFS grid-cell-defs./ grid-cell-def.begin-white-down 2!
0 1 SWAP GRID-CELL-DEFS grid-cell-defs./ grid-cell-def.begin-red-up 2!
1 0 SWAP GRID-CELL-DEFS grid-cell-defs./ grid-cell-def.begin-red-down 2!

0 1 -1 0 GRID-CELL-DEFS grid-cell-defs.\ DEFINE-CELL-CONNECTION
0 -1 1 0 GRID-CELL-DEFS grid-cell-defs.\ DEFINE-CELL-CONNECTION
0 -1 SWAP GRID-CELL-DEFS grid-cell-defs.\ grid-cell-def.begin-white-up 2!
1 0 SWAP GRID-CELL-DEFS grid-cell-defs.\ grid-cell-def.begin-white-down 2!
0 1 SWAP GRID-CELL-DEFS grid-cell-defs.\ grid-cell-def.begin-red-up 2!
-1 0 SWAP GRID-CELL-DEFS grid-cell-defs.\ grid-cell-def.begin-red-down 2!

0 1 0 -1 GRID-CELL-DEFS grid-cell-defs.+ DEFINE-CELL-CONNECTION
1 0 -1 0 GRID-CELL-DEFS grid-cell-defs.+ DEFINE-CELL-CONNECTION
0 -1 SWAP GRID-CELL-DEFS grid-cell-defs.+ grid-cell-def.begin-white-up 2!
0 1 SWAP GRID-CELL-DEFS grid-cell-defs.+ grid-cell-def.begin-white-down 2!
-1 0 SWAP GRID-CELL-DEFS grid-cell-defs.+ grid-cell-def.begin-red-up 2!
1 0 SWAP GRID-CELL-DEFS grid-cell-defs.+ grid-cell-def.begin-red-down 2!

: GRID-CELL-DEF-BEGINS ( u grid-cell -- point[2] grid-cell-def )
  >R R@ grid-cell.invert C@ 1 = IF 1 SWAP - THEN
  GRID-CELL-DEFS R> grid-cell.type C@ 1- grid-cell-def * + >R
  point 2* * R@ + R> ;

BEGIN-STRUCTURE traxer-state
  point +FIELD traxer-state.pos
  point +FIELD traxer-state.prev-pos
  CFIELD: traxer-state.go?
  CFIELD: traxer-state.first
  CFIELD: traxer-state.colour
  CFIELD: traxer-state.dir
  CFIELD: traxer-state.bump
  ALIGNED
END-STRUCTURE

CREATE TRAXER-STATES traxer-state 4 * ALLOT

0 TRAXER-STATES traxer-state 0 * + traxer-state.colour C!
0 TRAXER-STATES traxer-state 1 * + traxer-state.colour C!
1 TRAXER-STATES traxer-state 2 * + traxer-state.colour C!
1 TRAXER-STATES traxer-state 3 * + traxer-state.colour C!
0 TRAXER-STATES traxer-state 0 * + traxer-state.dir C!
1 TRAXER-STATES traxer-state 1 * + traxer-state.dir C!
0 TRAXER-STATES traxer-state 2 * + traxer-state.dir C!
1 TRAXER-STATES traxer-state 3 * + traxer-state.dir C!

0 VALUE CURRENT-TRAXER
CREATE TRAXER-OLDPOS point ALLOT
0 VALUE CURRENT-GRID-CELL
0 VALUE CURRENT-GRID-CELL-DEF
0 VALUE CURRENT-GRID-CELL-BEGINS
0 VALUE NEXT-GRID-CELL
0 VALUE NEXT-GRID-CELL-DEF
0 VALUE NEXT-GRID-CELL-BEGINS
0 VALUE FOUND-LOOP

: COLOUR-MISMATCH ( n n -- flag )
  ENABLE-BUG IF
    ."    diff "
    2DUP SWAP . . CR
  THEN
  DIR-FLAT 2 0 DO
    DUP NEXT-GRID-CELL-BEGINS I point * +
    DUP point.x @ SWAP point.y @ DIR-FLAT = IF
      DROP FALSE UNLOOP EXIT
    THEN
  LOOP DROP TRUE ;

: FIND-DIRECTION ( -- )
  2 0 DO
    CURRENT-GRID-CELL-BEGINS I
    CURRENT-TRAXER traxer-state.dir C@ 1 = IF 1 SWAP - THEN
    point * + >R
    CURRENT-TRAXER traxer-state.pos point.x @ R@ point.x @ +
    CURRENT-TRAXER traxer-state.pos point.y @ R> point.y @ +
    2DUP TRAXER-OLDPOS point.y @ =
    SWAP TRAXER-OLDPOS point.x @ =
    AND 0= IF
      CURRENT-TRAXER traxer-state.pos point.y !
      CURRENT-TRAXER traxer-state.pos point.x !
      UNLOOP EXIT
    THEN 2DROP
  LOOP ;

: FORWARD-TRAXER ( traxer-state -- flag )
  TO CURRENT-TRAXER
  CURRENT-TRAXER traxer-state.go? C@ 0= IF FALSE EXIT THEN
  ENABLE-BUG IF
    CR ." >> color "
    CURRENT-TRAXER traxer-state.colour C@ . CR
    ."    dir "
    CURRENT-TRAXER traxer-state.dir C@ . CR
    ."    from "
    CURRENT-TRAXER traxer-state.prev-pos DUP point.y @ SWAP point.x @ . . CR
    ."    at "
    CURRENT-TRAXER traxer-state.pos DUP point.y @ SWAP point.x @ . . CR
  THEN
  CURRENT-TRAXER traxer-state.prev-pos
  TRAXER-OLDPOS point MOVE
  CURRENT-TRAXER traxer-state.pos
  CURRENT-TRAXER traxer-state.prev-pos point MOVE
  CURRENT-TRAXER traxer-state.pos DUP point.x @ SWAP point.y @ PARSED-GRID
  grid[] TO CURRENT-GRID-CELL
  ENABLE-BUG IF
    ."    ( type "
    CURRENT-GRID-CELL grid-cell.type C@ .
    ." inv "
    CURRENT-GRID-CELL grid-cell.invert C@ .
    ." )" CR
  THEN
  CURRENT-GRID-CELL grid-cell.type C@ GRID-0 = IF
    ENABLE-BUG IF
      ."    reject null source " CR
    THEN
    FALSE EXIT
  THEN
  CURRENT-GRID-CELL grid-cell.invert C@ 2 = IF
    0 CURRENT-GRID-CELL grid-cell.invert C!
  THEN
  CURRENT-TRAXER traxer-state.colour C@ CURRENT-GRID-CELL GRID-CELL-DEF-BEGINS
  TO CURRENT-GRID-CELL-DEF TO CURRENT-GRID-CELL-BEGINS
  CURRENT-GRID-CELL-DEF CURRENT-GRID-CELL-BEGINS CURRENT-TRAXER DROP 2DROP
  FIND-DIRECTION
  CURRENT-TRAXER traxer-state.pos DUP point.x @ SWAP point.y @ PARSED-GRID
  grid[] TO NEXT-GRID-CELL
  ENABLE-BUG IF
    ."    to "
    CURRENT-TRAXER traxer-state.pos DUP point.y @ SWAP point.x @ . . CR
    ."    ( type "
    NEXT-GRID-CELL grid-cell.type C@ .
    ." inv "
    NEXT-GRID-CELL grid-cell.invert C@ .
    ." )" CR
  THEN
  CURRENT-GRID-CELL grid-cell.wseen
  CURRENT-TRAXER traxer-state.colour C@ CHARS + C@
  IF
    ENABLE-BUG IF
      ."    reject seen source " CR
    THEN
    FALSE EXIT
  THEN
  CURRENT-TRAXER traxer-state.first C@ 0= IF
    TRUE CURRENT-GRID-CELL grid-cell.wseen
    CURRENT-TRAXER traxer-state.colour C@ CHARS + C!
  THEN
  FALSE CURRENT-TRAXER traxer-state.first C!
  NEXT-GRID-CELL NULL-GRID-CELL = IF
    TRUE CURRENT-TRAXER traxer-state.bump C!
  THEN
  NEXT-GRID-CELL grid-cell.type C@ GRID-0 = IF
    ENABLE-BUG IF
      ."    reject null target " CR
    THEN
    FALSE EXIT
  THEN
  CURRENT-TRAXER traxer-state.colour C@ NEXT-GRID-CELL GRID-CELL-DEF-BEGINS
  TO NEXT-GRID-CELL-DEF TO NEXT-GRID-CELL-BEGINS
  NEXT-GRID-CELL grid-cell.wseen
  CURRENT-TRAXER traxer-state.colour C@ CHARS + C@ IF
    ENABLE-BUG IF
      ."    found loop" CR
    THEN
    TRUE TO FOUND-LOOP
  THEN TRUE ;

BEGIN-STRUCTURE vstack
  FIELD: vstack.addr
  FIELD: vstack.len
END-STRUCTURE

0 VALUE VSTACK-ITEM

: VSTACK-PUSH ( addr vstack -- )
  >R R@ vstack.addr @ R@ vstack.len @
  VSTACK-ITEM * + VSTACK-ITEM MOVE
  1 R> vstack.len +! ;

: VSTACK-POP ( addr vstack -- flag )
  DUP vstack.len @ 0> 0= IF 2DROP FALSE EXIT THEN
  >R -1 R@ vstack.len +!
  R@ vstack.addr @ R> vstack.len @
  VSTACK-ITEM * + SWAP VSTACK-ITEM MOVE TRUE ;

CREATE QUEUE vstack ALLOT

: IMPLODE-POS ( u u -- u )
  PARSED-GRID grid.width @ * + ;

: EXPLODE-POS ( u -- u u )
  PARSED-GRID grid.width @ /MOD ;

BEGIN-STRUCTURE queue-elem-t
  FIELD: queue-elem.pos
END-STRUCTURE

CREATE QUEUE-ELEM queue-elem-t ALLOT

: NORM-PUSH ( n n -- FLAG )
  2DUP IMPLODE-POS QUEUE-ELEM !
  PARSED-GRID grid[] >R
  R@ grid-cell.type C@ GRID-0 =
  R@ grid-cell.wseen C@ 0= 0= OR 0= R> SWAP IF
    grid-cell.wseen TRUE SWAP C!
    QUEUE-ELEM QUEUE VSTACK-PUSH
  ELSE DROP THEN ;

: NORMALIZE ( -- )
  PARSED-GRID DUP grid.height @ SWAP grid.width @ * DUP point *
  ALIGN HERE QUEUE vstack.addr ! queue-elem-t * ALLOT
  0 QUEUE vstack.len !
  queue-elem-t TO VSTACK-ITEM
  DUP 0 ?DO
    I PARSED-GRID grid.width @ /MOD 2DUP
    TO PARSED-HEIGHT TO PARSED-WIDTH
    NORM-PUSH
    ENABLE-BUG IF
      CR ." [ flood fill at "
      PARSED-WIDTH . PARSED-HEIGHT .
      ."  ]" CR
    THEN
    BEGIN
      QUEUE-ELEM QUEUE VSTACK-POP
    WHILE
      QUEUE-ELEM @ EXPLODE-POS 2DUP TO PARSED-HEIGHT TO PARSED-WIDTH
      PARSED-GRID grid[] DUP TO CURRENT-GRID-CELL
      CURRENT-GRID-CELL grid-cell.invert C@ 2 = IF
        0 CURRENT-GRID-CELL grid-cell.invert C!
      THEN
      ENABLE-BUG IF
        CR ." >> pos "
        PARSED-WIDTH PARSED-HEIGHT SWAP . . CR
      THEN
      ENABLE-BUG IF
        ."    ( type "
        CURRENT-GRID-CELL grid-cell.type C@ .
        ." inv "
        CURRENT-GRID-CELL grid-cell.invert C@ .
        ." )" CR
      THEN
      DUP grid-cell.type C@ GRID-0 = IF 0 ELSE 2 THEN 0 ?DO
        ENABLE-BUG IF
          ."    color "
          I . CR
        THEN
        DUP I SWAP GRID-CELL-DEF-BEGINS
        TO CURRENT-GRID-CELL-DEF
        TO CURRENT-GRID-CELL-BEGINS
        2 0 DO
          CURRENT-GRID-CELL-BEGINS I point * + DUP point.x @ SWAP point.y @
          ENABLE-BUG IF
            ."    dir "
            2DUP SWAP . . CR
          THEN
          2DUP PARSED-WIDTH PARSED-HEIGHT ROT + ROT ROT + SWAP 2DUP
          ENABLE-BUG IF
            ."    to "
            2DUP SWAP . . CR
          THEN
          NORM-PUSH PARSED-GRID grid[] DUP
          TO NEXT-GRID-CELL DUP grid-cell.type C@
          ENABLE-BUG IF
            ."    to "
            QUEUE-ELEM @ EXPLODE-POS SWAP . . CR
          THEN
          GRID-0 = IF
            ENABLE-BUG IF
              ."    reject null target " CR
            THEN
            DROP 2DROP
          ELSE
            J SWAP GRID-CELL-DEF-BEGINS
            TO NEXT-GRID-CELL-DEF
            TO NEXT-GRID-CELL-BEGINS
            NEGATE SWAP NEGATE SWAP
            COLOUR-MISMATCH IF
              ENABLE-BUG IF
                ."    inverting " CR
              THEN
              NEXT-GRID-CELL grid-cell.invert C@ 2 = 0= IF
                1 ABORT" VERTIGO"
              THEN
              1 NEXT-GRID-CELL grid-cell.invert C!
            ELSE
              NEXT-GRID-CELL grid-cell.invert C@ 2 = IF
                ENABLE-BUG IF
                  ."    default " CR
                THEN
                0 NEXT-GRID-CELL grid-cell.invert C!
              THEN
            THEN
          THEN
        LOOP
      LOOP DROP
    REPEAT
  LOOP DUP 0 ?DO
    I PARSED-GRID grid.width @ /MOD
    PARSED-GRID grid[]
    grid-cell.wseen FALSE SWAP C!
  LOOP DROP ;

: ANALYZE-GRID ( -- flag )
  PARSED-GRID grid.width @ PARSED-GRID grid.height @ * 0 ?DO
    I PARSED-GRID grid.height @ /MOD
    TO PARSED-HEIGHT TO PARSED-WIDTH
    ENABLE-BUG IF
      CR CR ." [ #" I . ." scanning at "
      PARSED-WIDTH . PARSED-HEIGHT .
      ." ]" CR
    THEN
    4 0 DO
      TRAXER-STATES I traxer-state * + >R
      PARSED-HEIGHT PARSED-WIDTH R@ traxer-state.pos 2!
      R@ traxer-state.pos
      R@ traxer-state.prev-pos point MOVE
      TRUE R@ traxer-state.go? C!
      TRUE R@ traxer-state.first C!
      FALSE R> traxer-state.bump C!
    LOOP
    FALSE TO FOUND-LOOP
    4 0 DO
      TRAXER-STATES I traxer-state * + FORWARD-TRAXER
      TRAXER-STATES I traxer-state * + traxer-state.go? C!
    LOOP
    TRUE CURRENT-GRID-CELL grid-cell.wseen C!
    TRUE CURRENT-GRID-CELL grid-cell.rseen C!
    BEGIN
      FOUND-LOOP 0=
      FALSE 4 0 DO
        TRAXER-STATES I traxer-state * + traxer-state.go? C@ OR
      LOOP AND
    WHILE
      ENABLE-BUG IF CR ." ..." CR THEN
      4 0 DO
        TRAXER-STATES I traxer-state * + FORWARD-TRAXER
        TRAXER-STATES I traxer-state * + traxer-state.go? C!
      LOOP
    REPEAT
    FOUND-LOOP IF
      ENABLE-BUG IF ." loop!" CR THEN FALSE UNLOOP EXIT
    THEN
    2 0 DO
      TRAXER-STATES I 2* 0 + traxer-state * + traxer-state.bump C@
      TRAXER-STATES I 2* 1 + traxer-state * + traxer-state.bump C@
      AND IF
        TRAXER-STATES I 2* 0 + traxer-state * + traxer-state.pos point.x @
        TRAXER-STATES I 2* 1 + traxer-state * + traxer-state.pos point.x @
        - ABS
        TRAXER-STATES I 2* 0 + traxer-state * + traxer-state.pos point.y @
        TRAXER-STATES I 2* 1 + traxer-state * + traxer-state.pos point.y @
        - ABS MAX 8 < 0= IF
          ENABLE-BUG IF ." line!" CR THEN FALSE UNLOOP UNLOOP EXIT
        THEN
      THEN
    LOOP
  LOOP TRUE ;

: ENTRY ( c-addr u -- flag )
  HERE >R ALIGN HERE grid ALLOT PARSE-GRID
  NORMALIZE ANALYZE-GRID
  R> HERE - ENABLE-BUG IF
    CR
    DUP NEGATE . ." bytes used" CR
  THEN ALLOT ;

round #54

submitted at
0 likes

guesses
comments 2
olus2000

This can be executed online at https://www.pico-8-edu.com/


soweli Lomjo

however what illumination pierces through that distant aperture its the olus yet its a deceit the trickery originates from the east shattering my heart with its untrue nature


post a comment


cg54.p8.png PNG image data, 160 x 205, 8-bit/color RGBA, non-interlaced

round #53

submitted at
2 likes

guesses
comments 1
luatic

👍


post a comment


matroska.js.zst Zstandard compressed data (v0.8+), Dictionary ID: None

round #52

submitted at
0 likes

guesses
comments 0

post a comment


LICENSE ASCII text
1
Copyright (C)2024-2077 Amogus. All rights reserved.
README.md ASCII text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# wtf.sh

FAST, SECURE, DOUBLE-ALGORITHMIC thue-morse sequence GENERATOR

Generates roughly 1 digit per 1 second, depending on CPU quality. If you
need more, please contact the developer to purchase a wtf.sh Pro
license.

## Usage

    PATH="$PATH":. wtf.sh
fast_but_sussy.cpp ASCII text
 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
#include <cstdlib>
#include <iostream>

unsigned long  long   MAYBE_TRUE = 0;
unsigned long long  *  SLIGHTLY_TRUE = &MAYBE_TRUE;
unsigned long long * * MODERATELY_TRUE = &SLIGHTLY_TRUE;
unsigned long long *** VERY_TRUE = &MODERATELY_TRUE;

int main() {

	for (unsigned long long i = 0; (***VERY_TRUE = 42); i++) {

		unsigned long long digitals = 0;

		for (
			unsigned long long digitable = i;
			digitable;
			(digitals += digitable & 1), (digitable >>= 1)
		);

		printf("%llx", digitals & 1);

	}

}
slow_but_reliable.cpp ASCII text
 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
#include <cstdlib>
#include <iostream>

unsigned long long number_ate(unsigned long long **input, unsigned long long size);

unsigned long long number_ate(unsigned long long **input, unsigned long long size) {

	unsigned long long *number = (unsigned long long*)realloc(*input, sizeof(unsigned long long) * size * 2);
	*input = number;

	for(int i = size, j = 0; i < size * 2; i++, j++) {
		number[i] = !number[j];
		printf("%llx", number[i]);
	}

	return number_ate(input, size * 2);

}

int main() {

	unsigned long long *number = (unsigned long long*)malloc(sizeof(unsigned long long));
	*number = 0;
	printf("%llx", *number);

	number_ate(&number, 1);

}
wtf.sh ASCII text
  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
#!/bin/sh

dependnecy_satisfied=$({

	if [ -e /dev/null ]; then
		false
	else
		printf "/dev/null required but not found!!\n" >&2
		echo 0
	fi

	if [ -e /dev/stdin ]; then
		false
	else
		printf "/dev/stdin required but not found!!\n" >&2
		echo 0
	fi

	echo '[ <([ ]) ]' |. /dev/stdin 2>/dev/null>/dev/null;
	if [ ! $? -ne 0 ]; then
		false
	else
		printf "<( ) bashism required but not found!!\n" >&2
		echo 0
	fi

	if [ -e /dev/urandom ]; then
		false
	else
		printf "/dev/urandom required but not found!!\n" >&2
		echo 0
	fi

	if command -v openssl >/dev/null 2>&1; then
		false
	else
		printf "OpenSSL required but not found!!\n" >&2
		echo 0
	fi

	if command -v c++ >/dev/null 2>&1; then
		false
	else
		printf "C++ required but not found!!\n" >&2
		echo 0
	fi

	if command -v xxd >/dev/null 2>&1; then
		false
	else
		printf "xxd required but not found!!\n" >&2
		echo 0
	fi

	if command -v head >/dev/null 2>&1; then
		false
	else
		printf "head required but not found!!\n" >&2
		echo 0
	fi

	if command -v cat >/dev/null 2>&1; then
		false
	else
		printf "cat required but not found!!\n" >&2
		echo 0
	fi
	
	if command -v mkdir >/dev/null 2>&1; then
		false
	else
		printf "mkdir required but not found!!\n" >&2
		echo 0
	fi

	if command -v realpath >/dev/null 2>&1; then
		false
	else
		printf "realpath required but not found!!\n" >&2
		echo 0
	fi

	if command -v dirname >/dev/null 2>&1; then
		false
	else
		printf "dirname required but not found!!\n" >&2
		echo 0
	fi

	echo 1

})

if [ "$dependnecy_satisfied" = 1 ]
then
	false
else
	printf "FATAL: unsatisfied. dependnecy\n\n" >&2
	exit 1
fi

cd "$(dirname "$(realpath $0)")"

AMOGUS_ROOT=amoguses_"$(cat /dev/urandom | head -c 8 | xxd -p)"
mkdir -p "$AMOGUS_ROOT"
c++ ./slow_but_reliable.cpp -O0 -o "$AMOGUS_ROOT"/slow_but_reliable
c++ ./fast_but_sussy.cpp -O2 -o "$AMOGUS_ROOT"/fast_but_sussy

random_salt=$(cat /dev/urandom | head -c 8 | xxd -p)

secure_hash() {
	openssl kdf \
		-keylen 32 \
		-kdfopt digest:SHA256 \
		-kdfopt pass:"$(cat /dev/stdin)" \
		-kdfopt salt:$random_salt \
		-kdfopt iter:1000000 PBKDF2
}

desussify() {
	while true
	do
		trusted=$(head -c 1 $1);
		sussy=$(head -c 1 $2);
		trusted_hash=$(printf "%llx" $trusted | secure_hash)
		sussy_hash=$(printf "%llx" $sussy | secure_hash)
		if [ $trusted_hash = $sussy_hash ]
		then
			no_longer_sussy=$sussy
			printf "%llx" $no_longer_sussy;
		else
			printf "FATAL: sussy amogus\n" >&2
			exit 1
		fi
	done
}

{ sleep 0.01 && rm -rf "$AMOGUS_ROOT"; } &
	# sussy race condition: amoguses might get voted out before we run them
	# added a large delay to mitigate.

desussify \
	<("$AMOGUS_ROOT"/slow_but_reliable) \
	<("$AMOGUS_ROOT"/fast_but_sussy)

round #48

submitted at
0 likes

guesses
comments 0

post a comment


biblical.tar.gz gzip compressed data, from Unix
dir src
lib.rs ASCII text
  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
pub fn entry(haystack: &str, needle: &str) -> Option<(usize,usize)>

{let solver: solverstd::structs::implemented::SolverBuilderBuilder  = solverstd::structs::implemented::SolverBuilderBuilder::new();
   let solver: solverstd::structs::implemented::SolveBuilder      = solverstd::structs::implemented::SolverBuilderBuilder::haystack(solver,haystack);
 // // / / / / ////  // // //// / YOUR mom is GAY /// // / / / / // / / // / // / / / // // / //// / // /   //  / /
      let solver: solverstd::structs::implemented::Solverer   = solverstd::structs::implemented::SolveBuilder::needle(solver,needle);
 return solverstd::structs::implemented::Solverer::solve(&solver);}

   mod solverstd { pub mod structs { pub mod implemented {
trait CharIter: Iterator<Item=(usize,char)> + Clone {}
impl<T: Iterator<Item=(usize,char)> + Clone> CharIter for T {}
  struct IncompleteWord<'a> { begin: usize, stride: usize,
    characters_to_go: usize, character: char, characters: std::str::Chars<'a> 

   }  impl<'a> Solverer<'a> {
            pub fn solve(&'a self) -> std::option::Option<(usize,usize)> {
                if self.Lemonade.is_ascii() {
                    #[cfg(feature="timetest")]println!("ascii!");
                    let chariter = |i,s|self.hackstack.as_bytes()[i..].iter().enumerate().step_by(s).map(move|(o,c)|(o+i,unsafe{char::from_u32_unchecked(*c as u32)}));
                    self.solve_for_real(chariter)
                } else {
                    #[cfg(feature="timetest")]println!("unicode...");
                    let charinds = str::char_indices(self.hackstack).collect::<Vec<_>>();
                    let chariter = |i,s|charinds[i..].iter().step_by(s).copied();
                    self.solve_for_real(chariter)
                }
            }
             fn solve_for_real<T:CharIter,F:FnMut(usize,usize)->T>(&'a self, mut chariterf: F) -> std::option::Option<(usize,usize)> {#[cfg(any(feature="meow",not(feature="meow")))]{
                let meow: std::vec::Vec<char> = str::chars(self.Lemonade).collect();
                 let mut characterifier = meow.iter().copied();
	         let first_character = characterifier.next()?;
                let characterifier = characterifier;
             let second_character = characterifier.clone().next();

	            let mut word_seeds: std::vec::Vec<WordSeed<'a>> = std::vec::Vec::new();
                let mut bad_seeds: std::vec::Vec<usize> = std::vec::Vec::new();
#[cfg(feature="timetest")]let mut beginned = std::time::Instant::now();
#[cfg(feature="timetest")]println!("begin...");
         	   for (i,index, character) in chariterf(0,1).enumerate().map(|(i,(cind,character))|(i,cind,character)) {
	                 if second_character.map(|value|value==character).unwrap_or(false){
                         for (word_index, word_seed) in <[WordSeed]>::iter(std::borrow::Borrow::borrow(&word_seeds)).enumerate() {
                         if index+(index-word_seed.begin)*(self.Lemonade.len()-1)>self.hackstack.len() {
                             bad_seeds.push(word_index);
                            } else {
                         let mut count = 1;
                         if chariterf(i,index-word_seed.begin).map(|(_,character)|character).zip(characterifier.clone()).all(|(a,b)|{count+=1;a==b}) && count==self.Lemonade.len() {
                             return Some((word_seed.begin,index-word_seed.begin-1));
                         }
                            }
               }}
		          for word_index in bad_seeds.drain(..).rev() {
                          word_seeds.swap_remove(word_index);
                    }
                         if character == first_character {
                            if self.Lemonade.len()<2 { return Some((index,usize::MAX)); }
	                      std::vec::Vec::push(&mut word_seeds, WordSeed {begin : index, meow: std::marker::PhantomData});
                   }
                         #[cfg(feature="timetest")]{let meow = std::time::Instant::now(); if (meow-beginned).as_millis()>500 { beginned=meow;
                         println!("{} {}",index as f64 / self.hackstack.len() as f64,word_seeds.len())}}
	      	     }
              None
          	}
             }}
  pub struct

SolverBuilderBuilder { murder	//1 481 9991 003 884 4 2342342342 8jg LMK!fc gcc clang llvm
                	           	//rusted tragedy demonic recruitment
     :()
}
  pub struct SolveBuilder<'a> {
       haystack: &'a str,
  }

struct WordSeed<'a> {
	begin: usize,
    meow: std::marker::PhantomData<&'a str>,
 //  characters: std::str::Chars<'a>,
}

	pub struct Solverer<'a> {
		hackstack : &'a str,
		Lemonade : &'a str
	}

	impl SolverBuilderBuilder {
		pub fn new() -> Self {
			Self{murder:()}
		}

		pub fn haystack<'a>(self, hellostrat: &'a str) -> SolveBuilder<'a> {
			SolveBuilder {haystack: hellostrat}
		}
	}

   impl<'a> SolveBuilder<'a> {
     	pub fn needle(self, needLemon: &'a str) -> Solverer {
       Solverer {hackstack: self.haystack,
         Lemonade: needLemon}
          }
	}
}}}


#[cfg(test)]
mod tests {
    use super::*;

      fn strangle(stack: &str, index: Option<(usize,usize)>, len: usize) -> String {
        let mut buffer = String::new();
      let index = match index {
           None => {return buffer}
            Some(index) => {index}
            };
       for i in 0..len {
          buffer.push(stack.chars().nth(index.0 + i*(index.1)+i).unwrap());
      }
           return buffer;
   }

   #[test]
  fn it_works() {
         let result = entry("THISBOOKISSOFUCKINGAWESOMEANDIAMTOTALLYGAY", "S");
       assert!(match result {Some((n,_))=>n==3,None=>false}, "S test failed: {}", strangle("THISBOOKISSOFUCKINGAWESOMEANDIAMTOTALLYGAY",result,1));

         let result = entry("THISBOOKISSOFUCKINGAWESOMEANDIAMTOTALLYGAY", "SA");
          assert_eq!(Some((3, 15)), result, "SA test failed: {}", strangle("THISBOOKISSOFUCKINGAWESOMEANDIAMTOTALLYGAY",result,2));

     let result = entry("THISBOOKISSOFUCKINGAWESOMEANDIAMTOTALLYGAY", "SAD");
    assert_eq!(Some((10, 8)), result, "SAD test failed: {}", strangle("THISBOOKISSOFUCKINGAWESOMEANDIAMTOTALLYGAY",result,3));

          let result = entry("THISBOOKISSOFUCKINGAWESOMEANDIAMTOTALLYGAY", "SCAM");
	  assert_eq!(Some((9, 4)), result, "SCAM test failed: {}", strangle("THISBOOKISSOFUCKINGAWESOMEANDIAMTOTALLYGAY",result,4));

      	let result = entry("THISBOOKISSOFUCKINGAWESOMEANDIAMTOTALLYGAY", "GAY");
        assert_eq!(Some((39, 0)), result, "GAY test failed: {}", strangle("THISBOOKISSOFUCKINGAWESOMEANDIAMTOTALLYGAY",result,3));

      let result = entry("THISBOOKISSOFUCKINGAWESOMEANDIAMTOTALLYGAY", "SICK");
     	assert_eq!(None, result, "SICK test failed: {}", strangle("THISBOOKISSOFUCKINGAWESOMEANDIAMTOTALLYGAY",result,4));
    }

   //#[test]
      //fn it_does_not_works() {
    //      unsafe{
      //    *std::mem::transmute::<_,*mut u64>(std::ptr::null::<u8>()) = 42;
  //     };
      //}
}
.gitignore ASCII text
1
2
/target
/Cargo.lock
Cargo.toml ASCII text
1
2
3
4
5
6
7
8
[package]
name = "biblical"
version = "0.1.0"
edition = "2021"
[features]
timetest=[]
[dependencies]
dyn-clone = "1.0.16"

round #47

submitted at
2 likes

guesses
comments 0

post a comment


cpp.cpp.cpp ASCII text
  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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
   #include <condition_variable>
 #include <scoped_allocator>
#include <initializer_list>
#include <source_location>
#include <memory_resource>
 #include <unordered_map>
   #include <unordered_set>
      #include <system_error>
         #include <shared_mutex>
            #include <forward_list>
                #include <string_view>
                     #include <type_traits>
                         #include <stacktrace>
                              #include <inttypes.h>
                                   #include <stop_token>
                                       #include <filesystem>
                                            #include <spanstream>
                                                #include <syncstream>
                                                   #include <functional>
                                                      #include <cinttypes>
                                                         #include <stdexcept>
                                                           #include <streambuf>
                                                            #include <execution>
                                                            #include <algorithm>
                                                            #include <semaphore>
                                                           #include <typeindex>
                                                         #include <exception>
                                                      #include <locale.h>
                                                   #include <limits.h>
                                                #include <iterator>
                                            #include <wctype.h>
                                       #include <stdfloat>
                                   #include <charconv>
                              #include <optional>
                         #include <signal.h>
                     #include <expected>
                #include <assert.h>
            #include <setjmp.h>
         #include <concepts>
      #include <stdint.h>
   #include <stddef.h>
 #include <typeinfo>
#include <stdarg.h>
#include <valarray>
#include <stdlib.h>
 #include <string.h>
   #include <iostream>
      #include <csetjmp>
         #include <cassert>
            #include <cwctype>
                #include <compare>
                     #include <variant>
                         #include <cstdlib>
                              #include <cstddef>
                                   #include <float.h>
                                       #include <ctype.h>
                                            #include <cstring>
                                                #include <cstdarg>
                                                   #include <csignal>
                                                      #include <errno.h>
                                                         #include <sstream>
                                                           #include <fstream>
                                                            #include <stdio.h>
                                                            #include <utility>
                                                            #include <numeric>
                                                           #include <climits>
                                                         #include <codecvt>
                                                      #include <version>
                                                   #include <cstdint>
                                                #include <barrier>
                                            #include <ostream>
                                       #include <wchar.h>
                                   #include <uchar.h>
                              #include <numbers>
                         #include <istream>
                     #include <iomanip>
                #include <complex>
            #include <clocale>
         #include <string>
      #include <cwchar>
   #include <vector>
 #include <limits>
#include <locale>
#include <cstdio>
#include <cctype>
 #include <cuchar>
   #include <ranges>
      #include <random>
         #include <iosfwd>
            #include <format>
                #include <atomic>
                     #include <bitset>
                         #include <cfloat>
                              #include <chrono>
                                   #include <future>
                                       #include <math.h>
                                            #include <thread>
                                                #include <time.h>
                                                   #include <cerrno>
                                                      #include <fenv.h>
                                                         #include <memory>
                                                           #include <mutex>
                                                            #include <cfenv>
                                                            #include <queue>
                                                            #include <ctime>
                                                           #include <stack>
                                                         #include <deque>
                                                      #include <latch>
                                                   #include <tuple>
                                                #include <cmath>
                                            #include <array>
                                       #include <regex>
                                   #include <ratio>
                              #include <list>
                         #include <span>
                     #include <bit>
                #include <ios>
            #include <new>
         #include <set>
      #include <any>
   #include <map>
 using namespace std;
// waiter waiter!
// more sexual transmited dieseses please!!
typedef struct
{ double val;
  int count;
  int prev;} Linky;
extern int entry(double *input, int len, double **output)
{ vector<Linky>things={};
  things.push_back(Linky{0,0,0});
  vector<int>thing_index={};
  unordered_map<double,int>maxlens={};
  vector<int*>imaxlens={};
  for(int i=0;i<len;i++)
  maxlens[input[i]]=1;
  for(int i=0;i<len;i++)
  imaxlens.push_back(&maxlens[input[i]]);
  int counter=0;
  int nextgc=1;
  vector<Linky>thingbuf={};
  for(int ii=0;ii<len;ii++)
  { auto x=input[ii];
    thingbuf.push_back(Linky{x,1,-1});
    counter++;
    Linky v;
    things[0].val=x;
    int mid=upper_bound(thing_index.begin(),thing_index.end(),0,
    [&](int a, int b){return things[a].val>things[b].val;})-thing_index.begin();
    for(int i=mid;i<thing_index.size()&&(v=things[thing_index[i]],1);i++)
    { if(v.count+1>*imaxlens[ii])
      { thingbuf.push_back(Linky{x,v.count+1,thing_index[i]});
        *imaxlens[ii]=v.count+1;
        counter++; }}
    auto oldend=thing_index.size();
    sort(thingbuf.begin(),thingbuf.end(),[&](auto a,auto b){return a.val>b.val;});
    for(auto v: thingbuf)
    thing_index.push_back(things.size()),things.push_back(v);
    inplace_merge(thing_index.begin(),thing_index.begin()+oldend,thing_index.end(),
    [&](int a, int b){return things[a].val>things[b].val;});
    if(counter>nextgc)
    { thing_index.resize(remove_if(thing_index.begin(),thing_index.end(),
      [&](auto i){return things[i].count<maxlens[things[i].val];})-thing_index.begin());
      nextgc+=thing_index.size(); }
    #ifdef ENTRY_DEBUG
    cout<<x<<" -> "<<mid<<" {"<<endl;int n=0;for(auto i:thing_index)
    {auto v=things[i];cout<<"  "<<(n++)<<": ";;for(;;v=things[v.prev])
    {cout<<v.val<<" ";if(v.prev==-1)break;}cout<<"\n";}
    cout<<"}\n";
    #endif
    thingbuf.clear(); }
  Linky bestest=things[1];
  int bestest_len=bestest.count;
  for(auto it=things.begin()+2;it<things.end();it++)
  { if(it->count>bestest_len)
    bestest=*it,
    bestest_len=it->count; }
  double* out;
  int count=0;
  Linky outlinky=bestest;
  for(;;outlinky=things[outlinky.prev])
  { count++;
    if(outlinky.prev==-1)break; }
  out=(double*)malloc(sizeof(double)*count);
  *output=out;
  outlinky=bestest;
  for(int i=0;;outlinky=things[outlinky.prev],i++)
  { if(i>=count) abort();
    out[i]=outlinky.val;
    if(outlinky.prev==-1)break; }
  reverse(out,out+count);
  return count; }
int main ()
{ vector<double>input=vector<double>();
  for(istream_iterator<double>it
     =istream_iterator<double>(cin);
  it!=istream_iterator<double>()
        ;it++)input.push_back(*it);
  double *out;
  int count=entry(input.data(),input.size(),&out);
  for(int i=0;i<count;i++)cout<<out[i]<<endl;
  free(out);
  return 0; }

round #46

submitted at
1 like

guesses
comments 0

post a comment


meow.js ASCII text
 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
mreow=((meowest,submissive,meow,mreow,Mreow)=>{meow =_=>
new Set();meowest=(prrr,Meow)=>!((mreow,Prrr)=>
{Prrr=meow();for(mreow of Meow)
{if((meow=>(meow=JSON.stringify(meow),Prrr.has(meow)?1:(Prrr
.add(meow),0)))(prrr.map(i=>mreow[i]))){return 1}}//          ^     ^   - Meow
return 0;})();submissive=(owo,//                            /  |   |  \
uwu)=>((Owo,Uwu)=>{for(;Owo>=0//                           | \___.___/ |
&&Uwu>=0;Owo--,Uwu--)while(owo[Owo]!=uwu[Uwu]//            \           /
&&Owo>=0)Owo--;Owo++;Uwu++;return Uwu>=0&&Owo>=0})(owo.length-1,uwu.length
-1);Mreow=(meow,mreow,mrrp,prrr,Prrr,Meow)=>(//
(nyaa,Mrrp)=>{if(Meow.length<=//              prrr
1){meow.mrrp.push([]);return}Mrrp=0;for(;mrrp<prrr;mrrp++){
/* * * * * */nyaa=mreow.concat([mrrp]);if(/*  prrr   */    meowest  (nyaa,Meow))
/*   ^ ^   */{meow.mrrp.forEach((prrr,Prrr)=>(prrr!=[][0]? submissive(prrr,nyaa)
/*  (O_O)  */&&(meow.mrrp[Prrr]=[][0]):Mrrp++));Mrrp
/*  /   \  */>=meow.mrrp.length/2&&(meow.mrrp=meow.mrrp.   filter // ( mreow ? )
/*  ^^ ^^  */(meow=>(meow!=[][0])));meow.mrrp.push//       dismissive( :(  ;w; )
/*|||||||||*/(nyaa)}else Mreow(meow,nyaa,mrrp+1,
/*.-.-.-.-.*/ prrr,Prrr,Meow)}})();mreow
=(Prrr,...Meow)=>((prrr)=>(prrr={mrrp:[]},Mreow(prrr
,[],0,Prrr.length,Prrr,Meow),prrr.mrrp.filter(
meow=>meow!=[][0]).map(meow=>meow.map(meow=>
Prrr[meow]))))();return mreow})()

/*
consowo.meow(mreow(
	["contest","date held","winner","winner's second name"],
	["dog fight","oct 17 2000","discarding sabot","sabot"],
	["cat-off","jul 01 2001","palm tree oil","tree"],
	["rat duel","oct 05 2001","cart of iron","of"],
	["rat duel","mar 21 2006","cart of iron","of"],
	["shark race","mar 21 2006","linguist",null]
))
//*/

round #45

submitted at
1 like

guesses
comments 0

post a comment


dir parafour
dir src
bot.rs ASCII text
 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
use crate::game::*;
use rand::seq::IteratorRandom;
use rayon::prelude::*;
use std::cmp::Ordering;
use std::mem::swap;

pub trait Bottable<P: GamePlayer, M: GameMove>: Game<P, M> {
    fn random_move(&self) -> Option<M> {
        let mut rng = rand::thread_rng();
        return self.moves().choose(&mut rng);
    }
    fn best_move(&self) -> Option<M> {
        let p = self.current_player();
        let moves = self.moves().collect::<Vec<M>>();
        if moves.is_empty() {
            return None;
        } else if moves.len() == 1 {
            return moves.into_iter().next();
        }
        let mut score: Vec<f64> = vec![0.0; moves.len()];
        let mut weights: Vec<f64> = vec![0.0; moves.len()];
        let mut weights_old: Vec<f64> = vec![0.0; moves.len()];
        loop {
            (&moves).into_par_iter().zip(&mut score).for_each(|(m, c)| {
                *c += (0..2048)
                    .into_par_iter()
                    .map(|_| self.clone())
                    .map(|mut game| {
                        let mut m = *m;
                        loop {
                            match game.apply(m).unwrap() {
                                MoveOutcome::Win(p2) => break if p2 == p { 1.0 } else { -1.0 },
                                MoveOutcome::Tie => break 0.0,
                                MoveOutcome::Pass => (),
                            }
                            m = game.random_move().unwrap();
                        }
                    })
                    .sum::<f64>();
            });
            let min_score = score.iter().copied().reduce(f64::min).unwrap();
            (&mut weights)
                .into_iter()
                .zip(&score)
                .for_each(|(c, s)| *c = s - min_score);
            let total: f64 = weights.iter().copied().sum::<f64>();
            // normalize scores
            if total > 0.0 {
                (&mut weights).into_iter().for_each(|c| *c /= total);
            } else {
                (&mut weights).into_iter().for_each(|c| *c = 0.0);
            }
            let deviation: f64 = weights
                .iter()
                .copied()
                .zip(weights_old.iter().copied())
                .max_by(|(a, _), (b, _)| a.partial_cmp(b).unwrap_or(Ordering::Equal))
                .map(|(s, s_old)| f64::abs(s - s_old))
                .unwrap();
            if deviation < (1.0 / f64::powf(2.0, 12.0)) {
                break Some(
                    moves
                        .into_iter()
                        .zip(weights)
                        .max_by(|(_, a), (_, b)| a.partial_cmp(b).unwrap_or(Ordering::Equal))
                        .unwrap()
                        .0,
                );
            }
            swap(&mut weights, &mut weights_old);
        }
    }
}

impl<P: GamePlayer, M: GameMove, T: Game<P, M>> Bottable<P, M> for T {}
four.rs ASCII text
  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
use crate::game::*;
use std::fmt;

#[derive(Clone)]
pub struct Four<P> {
    player: P,
    data: [(u8, [Option<P>; 6]); 7],
    filled: u8,
    done: bool,
}

impl<P: GamePlayer + fmt::Display> fmt::Display for Four<P> {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("\n")?;
        for y in (0..6).rev() {
            formatter.write_str(" ")?;
            for x in 0..7 {
                match self.data[x].1[y] {
                    Some(p) => formatter.write_fmt(format_args!("{} ", &p)),
                    None => formatter.write_fmt(format_args!(". ")),
                }?;
            }
            formatter.write_str("\n")?;
        }
        formatter.write_str(" ")?;
        for x in 0..7 {
            formatter.write_fmt(format_args!("{} ", x + 1))?;
        }
        formatter.write_str("\n")?;
        Ok(())
    }
}

#[derive(Copy, Clone)]
pub struct FourMove(u8);
impl GameMove for FourMove {}
impl fmt::Display for FourMove {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        (self.0 + 1).fmt(formatter)
    }
}
impl TryFrom<u8> for FourMove {
    type Error = ();
    fn try_from(num: u8) -> Result<Self, ()> {
        if num >= 1 && num <= 7 {
            Ok(Self(num - 1))
        } else {
            Err(())
        }
    }
}

pub struct FourMoves<'a, P: 'a> {
    cols: std::iter::Enumerate<std::slice::Iter<'a, (u8, [Option<P>; 6])>>,
    size: usize,
}

impl<'a, P: GamePlayer> Iterator for FourMoves<'a, P> {
    type Item = FourMove;
    fn next(&mut self) -> Option<Self::Item> {
        let r = self.cols.find(|(_, d)| d.0 < 6).map(|(x, _)| {
            self.size -= 1;
            FourMove(x as u8)
        });
        r
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.size, Some(self.size))
    }
}

impl<P: GamePlayer> Four<P> {
    const DIRS: [[[i8; 2]; 2]; 4] = [
        [[0, -1], [0, 1]],
        [[-1, 0], [1, 0]],
        [[-1, -1], [1, 1]],
        [[1, -1], [-1, 1]],
    ];
    pub fn new() -> Self {
        Self {
            player: P::first(),
            data: [(0, [None; 6]); 7],
            filled: 0,
            done: false,
        }
    }
}

impl<P: GamePlayer> Game<P, FourMove> for Four<P> {
    type Moves<'a> = FourMoves<'a, P> where P: 'a;
    fn current_player(&self) -> P {
        self.player
    }
    fn moves<'a>(&'a self) -> Self::Moves<'a> {
        FourMoves {
            cols: self.data.iter().enumerate(),
            size: self.data.iter().filter(|d| d.0 < 6).count(),
        }
    }
    fn apply(&mut self, m: FourMove) -> Option<MoveOutcome<P>> {
        use MoveOutcome::*;
        if self.done {
            return None;
        }
        let x = m.0;
        if x >= 7 {
            return None;
        }
        let col = &mut self.data[x as usize];
        if col.0 >= 6 {
            return None;
        }
        let y = col.0;
        col.1[y as usize] = Some(self.player);
        col.0 += 1;
        self.filled += 1;
        for axis in Self::DIRS.iter() {
            let mut count = 1;
            for dir in axis.iter() {
                let (mut x, mut y) = (x as i8, y as i8);
                loop {
                    (x, y) = (x + dir[0], y + dir[1]);
                    if x < 0
                        || x >= 7
                        || y < 0
                        || y >= 6
                        || self.data[x as usize].1[y as usize].map_or(true, |p| p != self.player)
                    {
                        break;
                    }
                    count += 1;
                    if count >= 4 {
                        self.done = true;
                        return Some(Win(self.player));
                    }
                }
            }
        }
        self.player = self.player.next();
        Some(if self.filled >= 6 * 7 {
            self.done = true;
            Tie
        } else {
            Pass
        })
    }
}
game.rs ASCII text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#[derive(Debug)]
pub enum MoveOutcome<P> {
    Win(P),
    Tie,
    Pass,
}

pub trait GamePlayer: Copy + Clone + Eq + Send + Sync {
    fn first() -> Self;
    fn next(&self) -> Self;
}

pub trait GameMove: Copy + Clone + Send + Sync {}

pub trait Game<P: GamePlayer, M: GameMove>: Clone + Send + Sync {
    type Moves<'a>: Iterator<Item = M> + Sized
    where
        Self: 'a;
    fn current_player(&self) -> P;
    fn moves<'a>(&'a self) -> Self::Moves<'a>;
    fn apply(&mut self, m: M) -> Option<MoveOutcome<P>>;
}
main.rs ASCII text
  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
mod bot;
mod four;
mod game;
mod pl2;

use bot::Bottable;
use crossterm::tty::IsTty;
use four::{Four, FourMove};
use game::*;
use pl2::BinaryPlayer;
use std::io::{self, BufRead, Write};

#[derive(Debug)]
enum Miscommunication {
    Io(io::Error),
    MoveParse,
    ModeParse,
}

impl From<io::Error> for Miscommunication {
    fn from(error: io::Error) -> Self {
        Self::Io(error)
    }
}

fn handle_outcome<P: GamePlayer>(mmeee: P, out: MoveOutcome<P>) -> (&'static str, bool) {
    match out {
        MoveOutcome::Win(p) => (
            if p == mmeee {
                "YIPPIEE I WINNER"
            } else {
                "nuuuu :("
            },
            false,
        ),
        MoveOutcome::Tie => ("meh", false),
        MoveOutcome::Pass => ("...", true),
    }
}

fn apply_debugged<P: GamePlayer, M: GameMove, T: Game<P, M> + std::fmt::Display>(
    mmeee: P,
    game: &mut T,
    m: M,
    istty: bool,
) -> bool {
    let (msg, out) = handle_outcome(mmeee, game.apply(m).expect("unexpected move failure"));
    if istty {
        eprintln!("{}{}", &game, msg);
    }
    out
}

use clap::Parser;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
    #[arg(short, long)]
    quite: bool,
    #[arg(short, long)]
    load: bool,
}

fn main() -> Result<(), Miscommunication> {
    let args = Args::parse();
    assert!(
        !(args.quite && args.load),
        "can't be load and quite at once..."
    );
    let mut game: Four<BinaryPlayer> = Four::new();
    let reader = io::stdin();
    let mut stdout = io::stdout();
    let istty = if !(args.quite || args.load) {
        reader.is_tty()
    } else {
        args.load
    };
    let mut reader = reader.lock().lines();
    let mmeee;
    loop {
        if istty {
            eprint!("> ");
        }
        match reader.next().ok_or(Miscommunication::ModeParse)??.as_str() {
            "f" => {
                mmeee = BinaryPlayer::first();
                let m = game.best_move().expect("first move fail");
                println!("{}", m);
                stdout.flush()?;
                assert!(
                    apply_debugged(mmeee, &mut game, m, istty),
                    "first move fail"
                );
                break;
            }
            "s" => {
                mmeee = BinaryPlayer::first().next();
                if istty {
                    eprintln!("{}", &game);
                }
                break;
            }
            _ => {
                if istty {
                    eprintln!("bad mode");
                }
            }
        }
    }
    let mut reader = reader.map(|l| l.map(|s| s.parse::<u8>()));
    loop {
        loop {
            let m = loop {
                if istty {
                    eprint!("{}> ", game.current_player());
                }
                let num = reader.next().ok_or(Miscommunication::MoveParse)??.ok();
                if let Some(m) = num.map(|num| FourMove::try_from(num).ok()).flatten() {
                    break m;
                }
            };
            let out = game.apply(m);
            match out {
                Some(out) => {
                    let (msg, out) = handle_outcome(mmeee, out);
                    if !out {
                        if istty {
                            eprintln!("{}{}", &game, msg);
                        }
                        return Ok(());
                    }
                    break;
                }
                None => (),
            }
        }
        let m = game.best_move().expect("no moves");
        println!("{}", m);
        stdout.flush()?;
        if !apply_debugged(mmeee, &mut game, m, istty) {
            break;
        }
    }
    Ok(())
}
pfdm.rs ASCII text
  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
mod four;
mod game;
mod pl2;
use four::*;
use game::*;
use pl2::*;

use clap::Parser;
use std::ffi::{OsStr, OsString};
use std::io::{self, BufRead, BufReader, Write};
use std::mem::drop;
use std::process::{Child, ChildStdin, ChildStdout, Command, Stdio};

struct Bot {
    pub proc: Child,
    pub read: Option<BufReader<ChildStdout>>,
    pub write: Option<ChildStdin>,
}

impl Bot {
    fn new<S: AsRef<OsStr>>(program: S) -> io::Result<Self> {
        let mut proc = Command::new(program)
            .stdin(Stdio::piped())
            .stdout(Stdio::piped())
            .spawn()?;
        let read = proc.stdout.take().map(|s| BufReader::new(s));
        let write = proc.stdin.take();
        Ok(Self { proc, read, write })
    }
}

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
    bot_x: OsString,
    bot_o: OsString,
}

fn main() -> io::Result<()> {
    let args = Args::parse();
    println!("Player X: {:#?}", &args.bot_x);
    println!("Player O: {:#?}", &args.bot_o);
    let mut bots = [Bot::new(&args.bot_x)?, Bot::new(&args.bot_o)?];
    if let Some(s) = &mut bots[0].write {
        s.write(b"f\n")?;
    }
    if let Some(s) = &mut bots[1].write {
        s.write(b"s\n")?;
    }
    let mut game: Four<BinaryPlayer> = Four::new();
    let mut line = String::new();
    let mut stdout = io::stdout();
    let mut bot_read = bots
        .iter_mut()
        .map(|bot| bot.read.take().expect("no stdin"))
        .collect::<Vec<_>>();
    let mut bot_write = bots
        .iter_mut()
        .map(|bot| bot.write.take().expect("no stdout"))
        .collect::<Vec<_>>();
    'iter: for (from, to) in [(0, 1), (1, 0)].into_iter().cycle() {
        let from = &mut bot_read[from];
        let to = &mut bot_write[to];
        let pl = game.current_player();
        match 'read: {
            line.clear();
            print!("waiting for {}... ", pl);
            stdout.flush()?;
            if from.read_line(&mut line).is_err() {
                println!("fail");
                break 'read None;
            }
            println!("output: {:?}", &line);
            to.write(&line.as_bytes())?;
            to.flush()?;
            match line.strip_suffix("\n").unwrap().parse::<u8>() {
                Ok(m) => FourMove::try_from(m).ok(),
                Err(_) => None,
            }
        } {
            Some(m) => {
                let out = match game.apply(m) {
                    Some(out) => {
                        print!("{}: {}.{}", pl, m, &game);
                        out
                    }
                    None => {
                        println!("{}: invalid move ({}).", pl, m);
                        println!("{} wins.", pl.next());
                        break 'iter;
                    }
                };
                match out {
                    MoveOutcome::Win(p) => {
                        println!("{} wins.", p);
                        break 'iter;
                    }
                    MoveOutcome::Tie => {
                        println!("Tie.");
                        break 'iter;
                    }
                    MoveOutcome::Pass => {
                        println!("...");
                    }
                }
            }
            None => {
                println!("{} generated invalid output: {:?}", pl, &line);
                println!("{} wins.", pl.next());
                break 'iter;
            }
        }
    }
    drop((bot_read, bot_write));
    let exits: Vec<_> = bots
        .into_iter()
        .map(|c| c.proc)
        .map(|mut c| c.wait())
        .collect();
    for e in exits {
        e?;
    }
    Ok(())
}
pl2.rs ASCII text
 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
use crate::game::*;
use std::fmt;

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum BinaryPlayer {
    X,
    O,
}

impl fmt::Display for BinaryPlayer {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str(match self {
            Self::X => "X",
            Self::O => "O",
        })
    }
}

impl GamePlayer for BinaryPlayer {
    fn first() -> Self {
        Self::X
    }
    fn next(&self) -> Self {
        match self {
            Self::X => Self::O,
            Self::O => Self::X,
        }
    }
}
.gitignore ASCII text
1
/target
Cargo.lock ASCII text
  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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3

[[package]]
name = "anstream"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44"
dependencies = [
 "anstyle",
 "anstyle-parse",
 "anstyle-query",
 "anstyle-wincon",
 "colorchoice",
 "utf8parse",
]

[[package]]
name = "anstyle"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"

[[package]]
name = "anstyle-parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140"
dependencies = [
 "utf8parse",
]

[[package]]
name = "anstyle-query"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
dependencies = [
 "windows-sys",
]

[[package]]
name = "anstyle-wincon"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628"
dependencies = [
 "anstyle",
 "windows-sys",
]

[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"

[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"

[[package]]
name = "bitflags"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"

[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"

[[package]]
name = "clap"
version = "4.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956"
dependencies = [
 "clap_builder",
 "clap_derive",
]

[[package]]
name = "clap_builder"
version = "4.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45"
dependencies = [
 "anstream",
 "anstyle",
 "clap_lex",
 "strsim",
]

[[package]]
name = "clap_derive"
version = "4.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873"
dependencies = [
 "heck",
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "clap_lex"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"

[[package]]
name = "colorchoice"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"

[[package]]
name = "crossbeam-deque"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
dependencies = [
 "cfg-if",
 "crossbeam-epoch",
 "crossbeam-utils",
]

[[package]]
name = "crossbeam-epoch"
version = "0.9.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
dependencies = [
 "autocfg",
 "cfg-if",
 "crossbeam-utils",
 "memoffset",
 "scopeguard",
]

[[package]]
name = "crossbeam-utils"
version = "0.8.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
dependencies = [
 "cfg-if",
]

[[package]]
name = "crossterm"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
dependencies = [
 "bitflags 2.4.0",
 "crossterm_winapi",
 "libc",
 "mio",
 "parking_lot",
 "signal-hook",
 "signal-hook-mio",
 "winapi",
]

[[package]]
name = "crossterm_winapi"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
dependencies = [
 "winapi",
]

[[package]]
name = "either"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"

[[package]]
name = "getrandom"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
dependencies = [
 "cfg-if",
 "libc",
 "wasi",
]

[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"

[[package]]
name = "libc"
version = "0.2.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"

[[package]]
name = "lock_api"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
dependencies = [
 "autocfg",
 "scopeguard",
]

[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"

[[package]]
name = "memoffset"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
dependencies = [
 "autocfg",
]

[[package]]
name = "mio"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
dependencies = [
 "libc",
 "log",
 "wasi",
 "windows-sys",
]

[[package]]
name = "parafour"
version = "0.1.0"
dependencies = [
 "clap",
 "crossterm",
 "rand",
 "rayon",
]

[[package]]
name = "parking_lot"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
 "lock_api",
 "parking_lot_core",
]

[[package]]
name = "parking_lot_core"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
dependencies = [
 "cfg-if",
 "libc",
 "redox_syscall",
 "smallvec",
 "windows-targets",
]

[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"

[[package]]
name = "proc-macro2"
version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
dependencies = [
 "unicode-ident",
]

[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
 "proc-macro2",
]

[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
 "libc",
 "rand_chacha",
 "rand_core",
]

[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
 "ppv-lite86",
 "rand_core",
]

[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
 "getrandom",
]

[[package]]
name = "rayon"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1"
dependencies = [
 "either",
 "rayon-core",
]

[[package]]
name = "rayon-core"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed"
dependencies = [
 "crossbeam-deque",
 "crossbeam-utils",
]

[[package]]
name = "redox_syscall"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
dependencies = [
 "bitflags 1.3.2",
]

[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"

[[package]]
name = "signal-hook"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
dependencies = [
 "libc",
 "signal-hook-registry",
]

[[package]]
name = "signal-hook-mio"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
dependencies = [
 "libc",
 "mio",
 "signal-hook",
]

[[package]]
name = "signal-hook-registry"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
dependencies = [
 "libc",
]

[[package]]
name = "smallvec"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"

[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"

[[package]]
name = "syn"
version = "2.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e02e55d62894af2a08aca894c6577281f76769ba47c94d5756bec8ac6e7373"
dependencies = [
 "proc-macro2",
 "quote",
 "unicode-ident",
]

[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"

[[package]]
name = "utf8parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"

[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"

[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
 "winapi-i686-pc-windows-gnu",
 "winapi-x86_64-pc-windows-gnu",
]

[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"

[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
 "windows-targets",
]

[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
 "windows_aarch64_gnullvm",
 "windows_aarch64_msvc",
 "windows_i686_gnu",
 "windows_i686_msvc",
 "windows_x86_64_gnu",
 "windows_x86_64_gnullvm",
 "windows_x86_64_msvc",
]

[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"

[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"

[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"

[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"

[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"

[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"

[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
Cargo.toml ASCII text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[package]
name = "parafour"
description = "very Smart connect-four bot"
version = "0.1.0"
edition = "2021"

[dependencies]
clap = { version = "4.4.6", features = ["derive"] }
crossterm = "0.27.0"
rand = "0.8.5"
rayon = "1.8.0"

[[bin]]
name = "pfdm"
path = "src/pfdm.rs"

round #44

submitted at
2 likes

guesses
comments 0

post a comment


example ASCII text
1
2
814
2 1 3 7 6 9 + + * * * - /
numbers.lua ASCII text
  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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#!/usr/bin/env lua
--[[

  USAGE

  as a cli program:
    $ ./numbers.lua --help

  as a module:
    local numbers = require("numbers")

    numbers.solve(
      814, {2, 1, 3, 7, 6, 9, '+', '+', '*', '*', '-', '/'},
      function(msg) -- optional
         io.stderr:write(msg, '\n')
         io.stderr:flush()
      end,
      true -- equivalent to --hard in cli, optional
    ) -- returns 813, {9, 7, 2, '-', '*', 6, '*', 1, '+', 3, '*'}

--]]

local function eval(op, vals, strict)
	if type(op) == "number" then
		return {op, vals}
	else
		local a, b, o
		if not vals or not vals[2] then return end
		vals, a, b = vals[2][2], vals[2][1], vals[1]
		if strict and a < b then return end
		local commutable = false
		if op == '+' then
			o = a + b
			commutable = true
		elseif op == '-' then
			o = a - b
		elseif op == '*' then
			o = a * b
			commutable = true
		elseif op == '/' then
			o = a / b
		end
		o = (math.tointeger and math.tointeger(o)) or o
		if commutable and a < b then return end
		if strict and o % 1 ~= 0 then return end
		return {o, vals}
	end
end

local function copy(t, o)
	o = o or t
	for k, v in pairs(t) do
		o[k] = v
	end
	return o
end

local function flatten(stack)
	local reversed = {}
	while stack do
		table.insert(reversed, stack[1])
		stack = stack[2]
	end
	local out = {}
	for n = #reversed, 1, -1 do
		table.insert(out, reversed[n])
	end
	return out
end

local function stacklen(stack)
	local n = 0
	while stack do
		n = n + 1
		stack = stack[2]
	end
	return n
end

local function search(expr, vals, ops, write, strict)
	for op, count in pairs(ops) do
		local newvals = eval(op, vals, strict)
		if newvals then
			ops[op] = ops[op] - 1
			ops[op] = ops[op] > 0 and ops[op] or nil
			local newexpr = {op, expr}
			if not newvals[2] then
				write(newvals[1], newexpr)
			end
			search(newexpr, newvals, ops, write, strict)
			ops[op] = count
		end
	end
end

local function findmax(target, log)
	local maxdiff = math.huge
	local maxlen = math.huge
	local maxval = nil
	local maxexpr = nil
	return function(val, expr)
		local diff = math.abs(target - val)
		if diff <= maxdiff then
			local len = stacklen(expr)
			if diff < maxdiff or len <= maxlen then
				log(string.format(
					"... %s -> %s",
					table.concat(flatten(expr), " "), val))
				maxval, maxdiff, maxexpr, maxlen = val, diff, expr, len
			end
		end
	end, function()
		return maxval, flatten(maxexpr)
	end
end

local numbers = {}

function numbers.solve(target, oplist, log, hard)
	log = log or function() end
	local ops, write, maxfunc = {}, findmax(target, log)
	for _, op in pairs(oplist) do
		ops[op] = (ops[op] or 0) + 1
	end
	search(nil, nil, ops, write, not hard)
	return maxfunc()
end

do
	local ok, info = pcall(function()
		return debug.getinfo(5)
	end)
	if not ok or info then
		return numbers
	end
end

local usage = [[
Usage: numbers.lua [OPTION]... [FILE]
Solve a game of countdown.

With no FILE, or when FILE is -, read standard input.

  -q, --quiet, --silent    do not display intermediate results
  -h, --hard               allow fractions and negative numbers
      --help        display this help and exit

GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Full documentation <https://www.gnu.org/software/coreutils/numbers.lua>
or available locally via: info '(coreutils) numbers.lua invocation'
]]

local file = io.stdin
local istty = os.execute("tty >/dev/null")
istty = (type(istty) == "boolean" and {istty} or {istty == 0})[1]
local log = function(msg)
	io.stderr:write(msg, '\n')
	io.stderr:flush()
end
local hard = false

local options = {
	function(arg)
		if arg == "-" then
			file = io.stdin
		else
			file = assert(io.open(arg))
			istty = false
		end
	end,
	help = function()
		io.stdout:write(usage)
		os.exit(0)
	end,
	quiet = function()
		log = function() end
		istty = false
	end,
	hard = function()
		hard = true
	end,
}

local short_options = {
	q = options.quiet,
	h = options.hard,
}

local args = {...}
local args_done = false
for _, arg in ipairs(args) do
	if not args_done then
		if arg == "--" then
			args_done = true
		elseif string.sub(arg,1,2) == "--" and #arg>2 then
			assert(options[string.sub(arg,3)], "unknown option: " .. arg)()
		elseif string.sub(arg,1,1) == "-" and #arg>1 then
			string.gsub(string.sub(arg,2), '.', function(char)
				assert(short_options[char], "unknown option: -" .. char)()
			end)
		else
			options[1](arg)
		end
	else
		options[1](arg)
	end
end

local function test(target, ops, hard)
	local start = os.clock()
	local val, expr = numbers.solve(target, ops, log, hard)
	log(string.format("done in %.2fs", os.clock() - start))
	print(string.format("%s -> %s", table.concat(expr," "), val))
end

local function input(prompt)
	if istty then
		io.stderr:write(prompt .. "> ")
		io.stderr:flush()
	end
	return (assert(file:read(), "unexpected EOF"))
end

local function parse(str)
	local t = {}
	for v in string.gmatch(str, "%S+") do
		v = tonumber(v) or v
		table.insert(t, v)
	end
	return t
end

test(tonumber(input("target")), parse(input("ops")), hard)

round #42

submitted at
3 likes

guesses
comments 1
kimapr

updated versions available at gitlab and my website


post a comment


.gitignore ASCII text
1
2
/http.conf
/tmp
README.md ASCII text
 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
# 2048.php

An implementation of 2048 in PHP. Supports arbitrary board sizes.

## Web UI

**NOTE**: Unfinished.

Uses streamed HTML and CSS to create dynamic content without any client-side
JavaScript.

CGI. Communication between the main game process and control scripts (invoked
by form buttons targeting an invisible iframe) is done via UNIX domain datagram
sockets. Will not work on Windows, get a real operating system.

For convenience, a CLI script is provided that runs a pre-configured lighttpd
instance:

    ./server.php [address <port>]

## CLI

Simple CLI. Displays numbers on the board as base 2 logarithms in hexadecimal
(1=>2, 2=>4, b=>2048, etc.).

    ./cli.php [width [height [initial blocks]]]
cli.php ASCII text
  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
180
181
182
183
184
185
186
187
188
189
190
#!/usr/bin/php
<?php
include 'game.php';

class x1p11TextUI {
	private $game;
	private $board;
	private $ents;
	private $w, $h;
	private $lost;
	private $won;
	private $score;
	private const STATES = [
		" ",
		"new" => "!",
		"slide" => ":",
		"merge" => "+",
	];
	private function set($x, $y, $v = null, $new = 0) {
		$v = $v == null ? '.' : dechex(log($v, 2));
		$v = (object) ['v' => $v, 'new' => $new];
		$this->board[$y][$x] = $v;
	}
	private function expire() {
		for ($y = 0; $y < $this->h; $y++) {
			for ($x = 0; $x < $this->w; $x++) {
				$this->board[$y][$x]->new = false;
			}
		}
	}
	private function board_dump() {
		for ($y = 0; $y < $this->h; $y++) {
			echo ' ';
			for ($x = 0; $x < $this->w; $x++) {
				$v = $this->board[$y][$x];
				$v = $v->v . (self::STATES[$v->new]);
				echo $v;
			}
			echo "\n";
		}
	}
	public function __construct(x1p11 $game) {
		$this->game = $game;
		$this->board = [];
		$this->ents = [];
		$this->score = 0;
		[$this->w, $this->h] = $game->dimensions();
		for ($y = 0; $y < $this->h; $y++) {
			for ($x = 0; $x < $this->w; $x++) {
				$this->set($x, $y);
			}
		}
		/*
			// Debug
			$this->game->attach_handler(function ($type, $event) {
				/* //noise
					echo "Event: ";
					print_r($type->name);
					echo "\n";
					foreach ((array)$event as $k=>$v) {
						echo "	$k: ";
						print_r($v);
						echo "\n";
					}
					echo "\n";
				//* /
			});
			$deleting = [];
			$this->game->detach_handler($this->game->attach_handler(function ($type, $event) use (&$deleting) {
				if($type!=BoardEventType::Spawn){
					return;
				}
				$deleting[] = $event->pos;
			}));
			foreach ($deleting as [$x, $y]) {
				$this->game->set($x, $y);
			}
			foreach ([
				[4, 5, 6, 4],
				[1, 4, 2, 2],
				[2, 3, 0, 2],
				[0, 0, 0, 0],
			] as $y => $row) {
				foreach ($row as $x => $v) {
					$this->game->set($x, $y, $v>0?(2 ** $v):null);
				}
			}
		//*/
		$this->game->attach_handler($handler = function ($type, $event) use (&$handler) {
			switch ($type) {
			case BoardEventType::Slide:
				$ent = $this->ents[$event->id];
				[$x, $y] = $ent->pos;
				$this->set($x, $y);
				$ent->pos = $event->pos;
				[$x, $y] = $ent->pos;
				$this->set($x, $y, $ent->value, "slide");
				break;
			case BoardEventType::Merge:
				$src = $this->ents[$event->src];
				$dest = $this->ents[$event->dest];
				$handler(BoardEventType::Despawn, (object) [
					'id' => $event->src,
				]);
				$dest->value += $src->value;
				[$x, $y] = $dest->pos;
				$this->set($x, $y, $dest->value, "merge");
				break;
			case BoardEventType::Score:
				$this->score += $event->value;
				break;
			case BoardEventType::Spawn:
				$ent = (object) [
					'pos' => $event->pos,
					'value' => $event->value,
				];
				$this->ents[$event->id] = $ent;
				[$x, $y] = $ent->pos;
				$this->set($x, $y, $ent->value, "new");
				break;
			case BoardEventType::Despawn:
				$ent = $this->ents[$event->id];
				unset($this->ents[$event->id]);
				[$x, $y] = $ent->pos;
				$this->set($x, $y);
				break;
			case BoardEventType::Lose:
				$this->lost = true;
				if ($this->won) {
					echo "Game over.\n";
				} else {
					echo "You lost the game.\n";
				}
				break;
			case BoardEventType::Win:
				$this->won = true;
				echo "You won!\n";
				break;
			}
		});
		$cmds = [
			'w' => Direction::Up,
			's' => Direction::Down,
			'a' => Direction::Left,
			'd' => Direction::Right,
			'q' => false,
		];
		$this->expire();
		while (1) {
			$this->board_dump();
			echo "Score: {$this->score}\n";
			if ($this->lost) {
				break;
			}
			//var_dump($this->game);
			$cmd = "";
			while (!isset($cmds[$cmd])) {
				$cmd = readline('> ');
				if ($cmd === false) {
					break 2;
				}
				$cmd = strtolower($cmd);
			}
			$cmd = $cmds[$cmd];
			if (!$cmd) {
				break;
			}
			$this->expire();
			$this->game->move($cmd);
		}
	}
}

$w = 4;
$h = 4;
$c = 2;
if (isset($argv[1])) {$w = $argv[1];}
if (isset($argv[2])) {$h = $argv[2];}
if (isset($argv[3])) {$c = $argv[3];}
if (!(is_numeric($w) && is_numeric($h) && is_numeric($c))) {
	echo <<<Eof
	2048.php CLI. WASD to move.
	Numbers are displayed as base 2 logarithms in hex.
	Usage: 2048.php [width [height [initial blocks]]]

	Eof;
	return;
}

new x1p11TextUI(new x1p11($w, $h, $c));
game.php Unicode text, UTF-8 text
  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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
<?php

enum Direction: int {
case Down = 0;
case Left = 1;
case Up = 2;
case Right = 3;
}

enum BoardEventType {
case Spawn;
case Slide;
case Merge;
case Despawn;

case Score;
case Win;
case Lose;
}

class x1p11 {
	private $dirs;
	private $board;
	private $w, $h;
	private $freeds;
	private $ents;
	private $won;
	private $lost;
	private $score;
	private $handlers;
	private function pos($x, $y) {
		return $this->w * $y + $x;
	}
	private function spawn(Callable $handler, ?int $c = 1) {
		$cands = [];
		for ($y = 0; $y < $this->h; $y++) {
			for ($x = 0; $x < $this->w; $x++) {
				if ($this->board[$this->pos($x, $y)] == -1) {
					$cands[] = [$x, $y];
				}
			}
		}
		$c = min(count($cands), $c);
		if ($c == 0) {
			return;
		}
		$ids = array_slice($this->freeds, count($this->freeds) - $c);
		$rands = array_rand($cands, $c);
		if ($c == 1) {
			$rands = [$rands];
		}
		foreach (array_map(function ($k) use (&$cands) {return $cands[$k];}, $rands) as $i => [$x, $y]) {
			$handler(BoardEventType::Spawn, (object) [
				'pos' => [$x, $y],
				'id' => $ids[$i],
				'value' => rand(1, 2) * 2,
			]);
		}
	}
	private function safeset($i, $v) {
		if ($this->board[$i] != -1) {
			$this->apply(BoardEventType::Despawn, (object) [
				'id' => $this->board[$i],
			]);
		}
		$this->board[$i] = $v;
	}
	private function apply(BoardEventType $type, object $event) {
		switch ($type) {
		case BoardEventType::Slide:
			$id = $event->id;
			$pos = $event->pos;

			$ent = $this->ents[$id];
			$this->safeset($this->pos(...$pos), $id);
			$this->board[$this->pos(...$ent->pos)] = -1;
			$ent->pos = $pos;
			break;

		case BoardEventType::Merge:
			$src = $event->src;
			$dest = $event->dest;

			$entsrc = $this->ents[$src];
			$entdest = $this->ents[$dest];
			$this->apply(BoardEventType::Despawn, (object) [
				'id' => $src,
			]);
			$entdest->value += $entsrc->value;
			break;

		case BoardEventType::Score:
			$score = $event->value;

			$this->score += $score;
			break;

		case BoardEventType::Despawn:
			$id = $event->id;

			$ent = $this->ents[$event->id];
			$this->freeds[$event->id] = $event->id;
			unset($this->ents[$event->id]);
			$this->board[$this->pos(...$ent->pos)] = -1;
			break;

		case BoardEventType::Spawn:
			$id = $event->id;
			$pos = $event->pos;
			$value = $event->value;

			unset($this->freeds[$id]);
			$this->safeset($this->pos(...$pos), $id);
			$this->ents[$id] = (object) [
				'pos' => $pos,
				'value' => $value,
			];
			break;

		case BoardEventType::Lose:
			$this->lost = true;
			break;

		case BoardEventType::Win:
			$this->won = true;
			break;
		}
	}
	private function _move(Callable $handler, Direction $dir, bool $check = true) {
		[$ox, $oy, $mc, $mb, $cdx, $cdy, $bdx, $bdy] = $this->dirs[$dir->value];
		$moved = false;
		for ($c = 0; $c < $mc; $c++) {
			[$x🥺, $y🥺] = [$ox, $oy];
			[$x😈, $y😈] = [$ox, $oy];
			for ([$b🥺, $b😈] = [0, 0]; $b🥺 < $mb - 1 && $b😈 < $mb;) {
				$id🥺 = $this->board[$this->pos($x🥺, $y🥺)];
				$val🥺 = $id🥺 != -1 ? $this->ents[$id🥺]->value : null;
				$merges = $id🥺 == -1 ? 2 : 1;
				for (; $merges > 0;) {
					do {
						[$x😈, $y😈, $b😈] = [$x😈 + $bdx, $y😈 + $bdy, $b😈 + 1];
					} while ($b😈 <= $b🥺);
					if ($b😈 >= $mb) {
						break;
					}
					$id😈 = $this->board[$this->pos($x😈, $y😈)];
					$val😈 = $id😈 != -1 ? $this->ents[$id😈]->value : null;
					if ($id😈 != -1) {
						$merges--;
						if ($id🥺 == -1) {
							$handler(BoardEventType::Slide, (object) [
								'id' => $id😈,
								'pos' => [$x🥺, $y🥺],
								'lane' => $c,
							]);
							$val🥺 = $val😈;
							$val😈 = null;
							$id🥺 = $id😈;
							$id😈 = -1;
							$moved = true;
						} elseif ($val🥺 == $val😈) {
							$handler(BoardEventType::Merge, (object) [
								'src' => $id😈,
								'dest' => $id🥺,
								'lane' => $c,
							]);
							$val🥺 = $val🥺 + $val😈;
							$val😈 = null;
							$id🥺 = $id😈;
							$id😈 = -1;
							$handler(BoardEventType::Score, (object) [
								'value' => $val🥺,
							]);
							if ($check && !$this->won && $val🥺 >= 2048) {
								$handler(BoardEventType::Win, (object) []);
							}
							$moved = true;
						} else {
							[$x😈, $y😈, $b😈] = [$x😈 - $bdx, $y😈 - $bdy, $b😈 - 1];
							break;
						}
					}
				}
				[$x🥺, $y🥺, $b🥺] = [$x🥺 + $bdx, $y🥺 + $bdy, $b🥺 + 1];
			}
			[$ox, $oy] = [$ox + $cdx, $oy + $cdy];
		}
		if (!$check) {
			return $moved;
		}
		if ($moved) {
			$this->spawn($handler);
		}
		$lost = true;
		foreach (Direction::cases() as $cdir) {
			if ($cdir != $dir && $this->_move(fn() => null, $cdir, false)) {
				$lost = false;
				break;
			}
		}
		if ($lost) {
			$handler(BoardEventType::Lose, (object) []);
		}
	}
	private function handler(...$a) {
		$this->apply(...$a);
		foreach ($this->handlers as $f) {
			$f(...$a);
		}
	}

	public function __construct(?int $w = 4, ?int $h = null, ?int $c = 2) {
		$h = $h == null ? $w : $h;
		$this->board = [];
		$this->freeds = [];
		$this->ents = [];
		$this->handlers = new SplObjectStorage();
		$this->won = false;
		$this->lost = false;
		$this->score = 0;
		$id = 0;
		for ($i = 0; $i < $w * $h; $i++) {
			$this->board[] = -1;
			$this->freeds[$id] = $id;
			$id++;
		}
		array_reverse($this->freeds, true);
		[$mx, $my] = [$w - 1, $h - 1];
		$this->dirs = [
			[0, $my, $w, $h, 1, 0, 0, -1],
			[0, 0, $h, $w, 0, 1, 1, 0],
			[$mx, 0, $w, $h, -1, 0, 0, 1],
			[$mx, $my, $h, $w, 0, -1, -1, 0],
		];
		[$this->w, $this->h] = [$w, $h];
		$this->spawn([$this, 'apply'], $c);
	}
	public function dimensions() {
		return [$this->w, $this->h];
	}
	public function attach_handler(Callable $handler) {
		if (!is_object($handler)) {
			$handler = static function (...$a) use ($handler) {
				return $handler(...$a);
			};
		}
		$this->handlers->attach($handler);
		foreach ($this->ents as $id => $ent) {
			$handler(BoardEventType::Spawn, (object) [
				'id' => $id,
				'pos' => $ent->pos,
				'value' => $ent->value,
			]);
			if ($this->won) {
				$handler(BoardEventType::Win, (object) []);
			}
			if ($this->lost) {
				$handler(BoardEventType::Lose, (object) []);
			}
			$handler(BoardEventType::Score, (object) [
				'value' => $this->score,
			]);
		}
		return $handler;
	}
	public function detach_handler(Callable $handler) {
		$this->handlers->detach($handler);
	}
	public function move(Direction $dir) {
		$this->_move([$this, 'handler'], $dir);
	}
	public function get(int $x, int $y) {
		$pos = $this->pos($x, $y);
		$id = $this->board[$pos];
		if ($this->board[$id] == -1) {
			return null;
		}
		return $this->ents[$id]->value;
	}
	public function set(int $x, int $y, ?int $value = null) {
		$pos = $this->pos($x, $y);
		$id = $this->board[$pos];
		if ($id != -1) {
			$this->handler(BoardEventType::Despawn, (object) [
				'id' => $id,
			]);
		}
		if ($value != null) {
			[$id] = array_slice($this->freeds, count($this->freeds) - 1);
			$this->handler(BoardEventType::Spawn, (object) [
				'id' => $id,
				'pos' => [$x, $y],
				'value' => $value,
			]);
		}
	}
}
index.php ASCII text
  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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
<?php
include 'game.php';
include 'webutil.php';

ignore_user_abort(true);
define("DIR", getenv("C2K48_TMP_PREFIX") ?: "./tmp/c2k48_");

// the handler never runs in practice but not having one makes the script
// terminate on connection abort. i have no idea why.
$alive = true;
pcntl_signal(SIGTERM, function () {
	global $alive;
	$alive = false;
	error_log("bai!");
});

$chunking = false;

class BlockAnims {
	private $stylist;
	private $stack;
	private $buf;
	private $name;
	private $ents;
	private $t;
	//private $loaded;
	private $game;
	private static function valcolor($v) {
		return [255, floor(max(200 - ((log($v, 2) / 11) ** 1) * 200, 0)), floor(max(120 - ((log($v, 2) / 11) ** 1) * 120, 0))];
	}
	public function __construct(StyleMutator $stylist, string $name, x1p11 $game, Callable $write) {
		[$w, $h] = $game->dimensions();
		$entc = $w * $h;
		$this->stack = [];
		$this->name = $name;
		//$this->loaded=false;
		$this->game = $game;
		$this->stylist = $stylist;
		for ($i = 0; $i < $entc; $i++) {
			$ent = (object) [];
			$elid = $name . dechex($i);
			$elem = "<div class=b id=$elid><div>";
			$ent->name = '#' . $elid;
			$ent->num = new CursedNumber($stylist, $elid . "n", appendf($elem), 5);
			$ent->vis = false;
			$ent->real = ['color' => [0, 0, 0], 'pos' => [0, 0], 'z' => 0, 'value' => 0];
			$ent->fake = $ent->real;
			$elem .= "</div></div>\n";
			$write($elem);
			$this->ents[] = $ent;
		}
		$this->draw(0);
		/*$game->attach_handler(function($type,$event){
				if($this->loaded){
					//$realm="slide";
					switch($type){
					case BoardEventType::Slide:
						$id=$event->id;
						$ent=$this->ents[$id];
						break;
					case BoardEventType::Merge:
						break;
					case BoardEventType::Despawn:
						throw new Exception("unimplemented");
						break;
					case BoardEventType::Spawn:
						//$realm="spawn";
						break;
					}
				}else{
				}
			});
		*/
	}
	private function update(float $dt) {
		if ($dt <= 0) {return;}
		if (count($this->stack) == 0) {return;}
		$this->t += $dt;
	}
	public function draw(float $dt) {
		//$this->update($dt);
		foreach ($this->ents as $id => $ent) {
			$ent->vis = false;
		}
		$this->game->detach_handler($this->game->attach_handler(function ($type, $event) {
			if ($type != BoardEventType::Spawn) {
				return;
			}
			$value = $event->value;
			$pos = $event->pos;
			$ent = $this->ents[$event->id];
			$ent->vis = true;
			$ent->real = ['color' => self::valcolor($value), 'pos' => $pos, 'z' => 0, 'value' => $value];
			$ent->fake = $ent->real;
		}));
		[$w, $h] = $this->game->dimensions();
		$stylist = $this->stylist;
		foreach ($this->ents as $id => $ent) {
			$stylist->set($ent->name, "display", $ent->vis ? 'flex' : 'none');
			$stylist->set($ent->name, "z-index", $ent->fake['z']);
			$stylist->set($ent->name, "justify-content", "center");
			$stylist->set($ent->name, "align-items", "center");
			$stylist->set($ent->name, "position", "absolute");
			$stylist->set($ent->name, "background-color", sprintf("#%02X%02X%02X", ...$ent->fake['color']));
			[$x, $y] = $ent->fake['pos'];
			$stylist->set($ent->name, "left", sprintf("%f%%", ($x / $w) * 100));
			$stylist->set($ent->name, "top", sprintf("%f%%", ($y / $w) * 100));
			$stylist->set($ent->name, "width", sprintf("%f%%", (1 / $w) * 100));
			$stylist->set($ent->name, "height", sprintf("%f%%", (1 / $h) * 100));
			$stylist->set($ent->name, "font-size", "2em");
			$ent->num->draw($ent->fake['value']);
		}
	}
	public function mstart() {
		$this->buf = [];
	}
	public function mend() {
		array_push($this->stack, array_values($this->buf));
	}
}

const MOVES = [
	'u' => Direction::Up,
	'd' => Direction::Down,
	'l' => Direction::Left,
	'r' => Direction::Right,
];

function game(&$quitf) {
	global $alive;
	$uid = bin2hex(random_bytes(8));
	$dir = DIR . hash("sha256", $uid);
	$socket = socket_create(AF_UNIX, SOCK_DGRAM, 0);
	socket_bind($socket, $dir);
	socket_set_nonblock($socket);
	$quitf = function () use (&$socket, &$dir) {
		socket_close($socket);
		unlink($dir);
	};
	chunk_start();
	$styles = "";
	$cons = "";
	$elems = "";
	$statusl = "";
	$stwrite = appendf($styles);
	$stylist = new StyleMutator(callf($stwrite));
	foreach ([
		["l", "&lt;", 1, 2],
		["d", "v", 2, 3],
		["u", "^", 2, 1],
		["r", "&gt;", 3, 2],
	] as [$cmd, $label, $x, $y]) {
		$cons .=
			"<form method=post action=act/$uid/$cmd id=cb$cmd name=cb$cmd target=out></form>" .
			"<div class=conbc id=cbd$cmd><button class=conb form=cb$cmd>$label</button></div>";
		$stylist->set("#cbd$cmd", "grid-row-start", $y);
		$stylist->set("#cbd$cmd", "grid-column-start", $x);
	}
	$statusl .= "<div>";
	$tlab = new CursedNumber($stylist, "tcc", appendf($statusl));
	$statusl .= " fps</div><div id=win>You won!</div><div>score: ";
	$scor = new CursedNumber($stylist, "scc", appendf($statusl));
	$tlab->draw(0);
	$scor->draw(0);
	$game = new x1p11(4, 4);
	$gamer = new BlockAnims($stylist, "gg", $game, appendf($elems));
	[$w, $h] = $game->dimensions();
	$statusl .= "</div>";
	unset($cmd, $label);
	$bvalc = 16;
	unset($i, $elem, $elid, $bval, $bvald, $elnc, $elnid);
	$stylist->set("#win", "display", "none");
	$stylist->set("#die", "display", "none");
	$stylist->present();
	$headch = <<<Eof
	<!DOCTYPE html>
	<head><meta name="viewport" content="width=device-width" /><title>2048.php</title></head>
	<style>
	body,html{width:100%;height:100%;margin:0;padding:0;font-size:min(1em,3vmin)}
	#cont{display:flex;width:100%;height:100%;flex-direction:row;}
	#bcont{flex-grow:1;padding:2em;display:flex;align-items:center;justify-content:center}
	.filler{flex-grow:1}
	#sidec{font-size:1.5em;flex-basis:min(13rem,50vmin);padding:1rem;border-left:solid 1px black;display:flex;flex-direction:column;}
	@media(max-aspect-ratio:1/1){
		#cont{flex-direction:column}
		#sidec{flex-direction:row;border-left:initial;border-top:solid 1px black}
	}
	#bcont2{container-name:bbox;container-type:size;width:100%;height:100%;display:flex;justify-content:center;align-items:center}
	#board{aspect-ratio:$w/$h;border:solid 1px black;position:relative}
	@container bbox (max-aspect-ratio:$w/$h) {#board{width:100%}}
	@container bbox not (max-aspect-ratio:$w/$h) {#board{height:100%}}
	#if{display:none}
	#con{display:grid;aspect-ratio:1;}
	.conbc{width:100%;height:100%;}
	.conb{font-size:1em;width:100%;height:100%}
	form{display:none}
	</style>
	$styles<iframe id=if name=out></iframe>
	<div id=cont>
	<div id=bcont><div id=bcont2><div id=board>
	$elems</div></div></div>
	<div id=sidec>
	<div id=status>$statusl</div>
	<div class=filler></div>
	<span id=die>Game over.</span><div id=con>
	$cons
	</div>
	</div>
	</div>

	Eof;
	unset($styles, $elems, $cons, $statusl);
	$stwrite = 'chunk';
	chunk($headch);
	$timer = new DTimer();
	$score = 0;
	$lost = false;
	$won = false;
	$game->attach_handler(function ($type, $event) use (&$lost, &$won, &$score) {
		switch ($type) {
		case BoardEventType::Score:
			$score += $event->value;
			break;
		case BoardEventType::Win:
			$won = true;
			break;
		case BoardEventType::Lose:
			$lost = true;
			break;
		}
	});
	$t = 0;
	$tt = (int) (1000_000 / 30);
	$hidden = false;
	$hidt = 1;
	$tod = 10;
	$ii = 2;
	while (1) {
		$dt = $timer->tick();
		$t += $dt;
		$hidt -= $dt;
		$tod -= $dt;
		if ($hidt <= 0) {
			$hidden = !$hidden;
			$hidt = 0.5;
		}
		//$stylist->set("#board","display",$hidden?"none":"block");
		//$stylist->set("#board", "width", ((sin($t) + 1) / 2 * 25) . 'em');
		//chunk("<!--".str_repeat("-",4096*1024)."-->"); // stress test
		$buf = '';
		while (socket_recv($socket, $buf, 65536, 0) != false) {
			if (MOVES[$buf]) {
				$game->move(MOVES[$buf]);
				if ($lost) {
					$stylist->set("#con", "display", "none");
					$stylist->set("#die", "display", "initial");
				}
				if ($won) {
					$stylist->set("#win", "display", "initial");
				}
			}
		}
		$tlab->draw(1 / $dt);
		$gamer->draw($dt);
		$scor->draw($score);
		$stylist->present();
		if (connection_aborted() || !$alive) {
			error_log("bye!");
			return;
		}
		if ($lost) {
			break;
		}
		usleep(floor(max($tt - $dt, 0)));
		//if(--$ii==0){ break; }
	}
	/*chunk(<<<Eof
		<meta http-equiv="refresh" content="0">

	*/
	chunk_end();
};
$path = explode('/', $_SERVER["REQUEST_URI"]);
$path = array_values(array_filter($path, function ($e) {
	return $e != '';
}));
$spath = implode('/', $path);
if ($spath == '') {
	echo <<<EOF
	<!DOCTYPE html>
	<head><title>2048</title></head>
	<h1>2048.php</h1>
	<p>An implementation of the popular puzzle game <a href="https://en.wikipedia.org/wiki/2048_(video_game)">2048</a>.</p>
	<p>As it relies heavily on progressive HTML rendering and advanced CSS features (e.g. <code>display: none</code>) it might not work in older web browsers.</p>
	<p><a href="play">Start game</a></p>
	EOF;
} else if ($spath == "play") {
	$quitf = function () {};
	try {
		game($quitf);
	} catch (\Throwable $e) {
		error_log($e);
	} finally {
		$quitf();
	}
} else {
	if ($path[0] == "play") {
		array_shift($path);
	}
	if ($path[0] != "act") {
		echo "404\n";
		return;
	}
	array_shift($path);
	if (count($path) < 2) {
		echo "bad\n";
		return;
	}
	$dir = DIR . hash("sha256", $path[0]);
	$socket = socket_create(AF_UNIX, SOCK_DGRAM, 0);
	socket_sendto($socket, $path[1], strlen($path[1]), 0, $dir);
}
server.php ASCII text
 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
#!/usr/bin/php
<?php
chdir(dirname(realpath($argv[0])));
$cwd = getcwd();
$host = "127.0.0.1";
$port = "4444";
if (count($argv) == 3) {
	$host = $argv[1];
	$port = $argv[2];
} elseif (count($argv) != 1) {
	error_log("invalid argument");
	exit(1);
}
$f = fopen("http.conf", "w");
fwrite($f, <<<Eof
server.document-root = "$cwd"
server.bind = "$host"
server.port = $port
server.stream-response-body = 2
server.modules += ( "mod_cgi", "mod_rewrite" )
url.rewrite-once = ( "^/(.*)" => "/" )
cgi.assign = (".php" => "/usr/bin/php-cgi")
index-file.names = ( "index.php" )
Eof);
fclose($f);
mkdir("tmp");
$httpd = getenv("LIGHTTPD") ?: "/usr/sbin/lighttpd";
system("$httpd -D -f ./http.conf");
webutil.php Unicode text, UTF-8 text
  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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
<?php

function chunk_start() {
	global $chunking;
	if ($chunking) {
		throw new Exception("already chunking");
	}

	$chunking = true;
	if (ob_get_level() == 0) {
		ob_start();
	}

	header("Content-type: text/html; charset=utf-8");
	header("X-Content-Type-Options: nosniff");
	header("Transfer-encoding: chunked");
}

function chunk($str) {
	global $chunking;
	if (!$chunking) {
		throw new Exception("not chunking");
	}

	printf("%s\r\n", dechex(strlen($str)));
	printf("%s\r\n", $str);
	ob_flush();
	flush();
	if ($str == '') {
		$chunking = false;
		ob_end_flush();
	}
}

function chunk_end() {
	chunk("");
}

class DTimer {
	private $last;
	public function __construct() {
		$this->last = 0;
		$this->tick();
	}
	public function tick() {
		$cur = hrtime(true);
		$dt = $cur - $this->last;
		$this->last = $cur;
		return $dt / 1000_000_000;
	}
}
function appendf(&$s) {return function ($a) use (&$s) {$s .= $a;};}
function callf(&$f) {return function (...$a) use (&$f) {return $f(...$a);};}

class StyleMutator {
	private $current;
	private $dirty;
	private $write;
	public function __construct(Callable $write, ?StyleMutator $from = null) {
		if (isset($from)) {
			$this->current =  &$from->current;
			$this->dirty =  &$from->dirty;
		} else {
			$this->current = [];
			$this->dirty = [];
		}
		$this->write = $write;
	}
	public function set($i, $k, $v) {
		$this->dirty[$k][$i] = $v;
		if (isset($this->current[$k][$i]) && $this->current[$k][$i] == $v) {
			unset($this->dirty[$k][$i]);
		}
	}
	public function present() {
		$str = "<style>%s</style>\n";
		$byval = [];
		foreach ($this->dirty as $k => $l) {
			foreach ($l as $i => $v) {
				$byval[$k . ":" . $v][] = $i;
			}
		}
		foreach ($byval as $v => $l) {
			$byval[$v] = sprintf("%s{%s}", implode(',', $l), $v);
		}
		($this->write)(sprintf($str, implode('', $byval)));
		foreach ($this->dirty as $k => $l) {
			foreach ($l as $i => $v) {
				$this->current[$k][$i] = $v;
			}
		}
		$this->dirty = [];
		return true;
	}
}

const SI_BIGGER = [
	['k', 1000 ** 1],
	['M', 1000 ** 2],
	['G', 1000 ** 3],
	['T', 1000 ** 4],
	['P', 1000 ** 5],
	['E', 1000 ** 6],
	['Z', 1000 ** 7],
	['Y', 1000 ** 8],
	['R', 1000 ** 9],
	['Q', 1000 ** 10],
];
const SI_SMALLER = [
	['m', 1000 ** -1],
	['μ', 1000 ** -2],
	['n', 1000 ** -3],
	['p', 1000 ** -4],
	['a', 1000 ** -5],
	['z', 1000 ** -6],
	['y', 1000 ** -7],
	['r', 1000 ** -8],
	['q', 1000 ** -9],
];

function fnumfitweak($n, $m) {
	$dd = max($m - strlen(sprintf("%.0f", $n)) - 1, 0);
	$s = rtrim(sprintf("%.{$dd}f", $n), ".0");
	return $s == '' ? '0' : $s;
}

function fnumfit($n, $m) {
	$p = '';
	$s = fnumfitweak($n, $m);
	foreach (SI_SMALLER as [$vp, $vm]) {
		if (!($n > 0 && $s == 0)) {
			break;
		}
		$p = $vp;
		$s = fnumfitweak($n / $vm, $m - 1);
	}
	if ($p != '') {
		return [$s, $p];
	}
	foreach (SI_BIGGER as [$vp, $vm]) {
		if (strlen($s . $p) <= $m) {
			break;
		}
		$p = $vp;
		$s = fnumfitweak($n / $vm, $m - 1);
	}
	return [$s, $p];
}

class CursedNumber {
	private $stylist;
	private $maxlen;
	private $name;
	private const DIGITS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, '.' => 's'];
	public function __construct( ? StyleMutator &$stylist = null, ?string $name = null,  ? Callable $write = null, int $maxlen = 5) {
		$this->stylist =  &$stylist;
		$this->maxlen = $maxlen;
		if (isset($stylist)) {
			if (!(isset($name) && isset($write))) {
				throw new Exception("invalid argument");
			}
			$this->name = $name;
			$str = "<span id=$name>";
			$state = "none";
			for ($i = 0; $i < $maxlen; $i++) {
				foreach (self::DIGITS as $v => $d) {
					$en = $this->elname('d', $i, $d);
					$str .= "<span id=$en>$v</span>";
					$this->stylist->set('#' . $en, "display", $state);
				}
			}
			foreach ([...SI_BIGGER, ...SI_SMALLER] as [$d, $v]) {
				$en = $this->elname('p', $d);
				$str .= "<span id=$en>$d</span>";
				$this->stylist->set('#' . $en, "display", $state);
			}
			$str .= "</span>";
			$write($str);
		}
	}
	private function elname($type, ...$l) {
		$name = $this->name;
		switch ($type) {
		case "d" :
			return "{$name}n{$l[0]}{$l[1]}";
		case "p" :
			return "{$name}p{$l[0]}";
		}
	}
	public function draw($n) {
		$n = fnumfit($n, $this->maxlen);
		for ($i = 0; $i < $this->maxlen; $i++) {
			foreach (self::DIGITS as $v => $d) {
				$en = $this->elname('d', $i, $d);
				$state = "none";
				if (isset($n[0][$i]) && $n[0][$i] == $v) {
					$state = "initial";
				}
				$this->stylist->set('#' . $en, "display", $state);
			}
		}
		foreach ([...SI_BIGGER, ...SI_SMALLER] as [$d, $v]) {
			$en = $this->elname('p', $d);
			$state = "none";
			if ($n[1] == $d) {
				$state = "initial";
			}
			$this->stylist->set('#' . $en, "display", $state);
		}
	}
}

round #41

submitted at
3 likes

guesses
comments 0

post a comment


false.js Unicode text, UTF-8 text, with very long lines (1509)
 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
<!----><!DOCTYPE html> <html> <head><meta  charset= utf-8></head >no  js :(<script>
eval(`(()=>{cc=[];eval(\`((Z,z,b)=>{C=(l,c)=>String.fromCodePoint(...[...Array(l)]\
.map#Ų̴̴̢̡̙̙̳̓̓̾̊̇̌̽̏V̴̶̡̡̜̦̥̮̙̲̹̦̜̦̭̏̍̽̐̕į̸̴̢̡̜̤̯̙̮̹̥̝̲̙̗̍̆̔̋̊̆́̔̑h̶̢̨̛̛̖̹̣̥̜̠̩̹̥̦̯̙̜̑̊̒̍̆̔Ą̨̲̤̩̜̲̤̩̤̙̤̻̦̋̆̔̊̒̒̂̐̽̊6̸̴̷̢̡̨̨̛̳̜̳̦̆̐̽̏̏̓̈̅̑̕K̥̞̙̖̯̙̲̤̩̦̇̑̄̍̆̊̂̋̑̕j̶̡̥̘̤̙̮̙̗̜̠̖̥̮̝̽̒̃̕ć̸̡̧̡̡̢̛̜̞̮̉̒̋Ŷ̴̡̛̙̳̮̖̰̊̅̊̆̌̕H̶̡̡̦̮̘̜̤̯̙̝̠̽̏̌̍̆́̂̕5̨̰̤̩̱̳̤̩̩̰̊̒̊̒̊̒̊̆̐̎̀Q̴̴̡̤̰̩͂̑̅̌̔̔̽̊̂̋̆̏8̵̹̻̜̻̟̭̭̗̭̰̓̃̓̏̽̎E̵̷̡̡̡̛̩̰̦̥̘̖̥̜̣̘̜̥̮̘̲̦̋̑̂́X̢̡̛̛̝̖̹̣̝̥̯̩̲̱̤̆̋6̶̵̴̵̢̛̘̩̞̖̻̝̣̇̐̽̋9̸̨̮̗̲̘̗̤̣̘̩̗̹̐̉̌̒b̴̷̨̭̘̗̗̳̥̭̘̦̬̀̾̔̽̊ô̵̧̤̩̰̲̩̤̎̊̋̋ḿ̴̸̴̶̨̨̯̜̜̰̗̳̞̥̦̃̆̽̏̓̾̊̆̐Ę̷̴̷̨̛̮̮̙̰̗̜̦̆̑̏̓̊̑̽̕n̵̛̝̳̝̣̲̦̥̜̈̂̆̅́̑̚ļ̷̷̢̛̛̦̙̬̜̥̝̲̎̉̇̕D̷̨̛̛̰̮̘̗̰̤̙̥̤́̀́̇̂̽̊̒N̷̨̨̛̙̹̰̩̲̯̗̩̤̂̀̎̀P̷̷̷̛̛̛̥̰̙̹̰̻̙̹̰̋̽̀̽̂̀̂Ừ̷̶̸̧̨̙̮̘̩̽̑̕E̴̴̢̡̛̗̭̩̙̥̳̦̱̥̦̝̊̆̋̃̚̚Ç̴̴̷̡̥̯̝̲̜̽̌̂̇̉̀̑̚k̶̷̛̘̬̠̝̖̹̤̙̗̦̳̉̆̽̉4̵̸̡̭̲̙̗̜̦̠̝̩̜̲̹̟̜̑̆̆̽Ḭ̵̷̢̨̥̰̙̹̰̝̗̣̼̠̊̂̽̎̊̂̑̏̽̏̉̕T̢̛̛̝̲̗̥̲̩̩̲̤̦̑̉́́̉̚ļ̦̥̯̝̲̗̥̋̑̊̅̍̚d̴̶̜̦̥̮̙̲̹̦̜̦̭̤̙̽̐̽̕ú̴̯̖̹̮̜̰̊̆̐̆̽̚+̵̸̴̷̧̧̤̩̤̻̗̩̤̝̗̳̠̝̊̂̊̒̀̋́̆̽̾̊̂ļ̩̝̥̮̥̯̘̉̆̔̈̆̈̆̊̒p̷̷̨̨̛̦̖̼̮̝̩̝̙̹̰̉̆̔̂̀̚m̵̧̬̲̤̩̰̊̒̉̎̊b̴̵̷̨̛̙̹̤̝̗̗̳̞̼̙̹̰̭̤̂̀̽̾̽̂̀̊̓B̵̶̴̧̨̜̠̗̲̱̟̗̻̗̩̤̦̋́̊̀̋̑1̷̴̶̛̲̗̳̞̮̜̀̽̾̐̆T̵̰̥̰̙̽̊̂̽̎̊̂Ḑ̶̵̶̧̹̳̝̰̼̭̤̜̠̅̏̽̏̋́̕x̸̶̨̢̨̧̮̙̹̳̜̱̩̘̩̥̝̦̲̜̋̂̆̔̋̓̈̋̉̕į̶̵̷̴̵̛̥̰̙̹̲̗̳̞̼̔̊̒̽̎̊̂̐̽̾5̙̹̳̜̱̩̘̽̂̆N̶̵̨̩̼̔̋̓̌̎5̴̡̧̨̮̜̳̟̖̙̇̂̋̍̕̚̚Z̶̢̤̩̮̜̳̠̮̹̟̊̂̎̐̇̂̋̕̚Ģ̴̶̗̻̗̩̤̩̘̊̀̋́8̴̵̷̨̛̬̗̳̞̼̙̹̰̽̾̽̂̀̊Ļ̵̶̴̨̛̭̤̜̠̙̭̤̦̱̥̦̝̓̋́̅̋̚6̴̴̵̧̱̝̗̻̘̰̖̬̂̋̽̊̂̊̕J̷̵̧̛̘̖̤̲̰̬̲̬̗̱̑̉̉̒̉̍/̵̴̢̧̘̜̬̜̭̬̖̲̝̭̝̖̰̋̂̉P̶̧̢̧̧̰̝̝̬̙̥̲̰̬̲̼̗̋̂̊̋̅̆̉̉̒Ở̶̡̧̧̢̛̱̦̰̉̐̋̂̉ű̷̧̧̝̝̬̘̦̲̲̰̬̰̗̱̅̽̉̉̒P̶̧̡̛̝̲̲̰̲̉̉̋̒̄̉Ȩ̢̧̧̰̝̝̬̙̗̜̭̏̋̅̄̋̂̈̒J̧̨̛̜̝̝̗̮̖̰̄̋̂̽̏̒̐̅ḻ̡̢̛̛̰̊̂̋̆̽8̴̴̨̢̝̘̮̭̮̟̘̱̊̓̾̆̐̉̇̓̒j̴̵̷̡̞̭̝̖̮̜̊̓̾̋̆̉̏̐́ḩ̴̵̬̖̥̲̭̤̜̍̊̂̊̓̋́̚ẙ̶̨̠̻̜̼̲̝̤̂̑̃̿̉̽̊̆̄M̶̴̢̞̘̤̩̰̰̗̻̘̽̽̏̃̊̂ơ̢̧̤̮̦̩̠̲̤̬̥̽̉̂̚k̶̴̛̭̹̥̙̲̜̬̲̉̉5̶̷̧̛̗̱̹̯̝̜̬̒̉̂̉#((_\
,i)=#Z̸̴̧̛̗̮̖̰̅̊̂̕i̡̢̢̛̛̱̯̗̤̦̤̒̽̏́̋Q̴̴̧̛̻̘̑̽̓̾5̶̨̞̮̜̳̠̭̯̟̖̐̇̂̉̇̕̚m̴̮̜̰̤̩̰̰̗̻̘̤̮̐̆̽̊̂̏̃̊̂w̸̢̧̨̛̦̩̠̲̥̝̦̩̯̖̽̉̋̉̚̚d̨̲̜̩̰̩̰̦̘̗̎̋̍̉ȅ̸̢̨̛̳̗̬̮̬̲̤̋̊̆̄B̢̡̡̛̛̯̗̭̮̖̰̽̏̏̽̋̆̄̅̊̂1̶̴̢̨̧̲̱̗̤̠̲̬̳̖̬̩̒̽̏̉̽̏̏̚̚Ṱ̵̨̫̗̩̫̹̭̘̗̓̊̒̀̚z̴̵̴̛̳̘̫̲̜̾̊̆̽̽̊̇̉̽̏̓̚T̵̶̴̷̨̧̼̜̳̜̲̹̮̜̠̩̘̩̘̩̤̊̓̾̂̊̎̊̒x̧̛̬̲̤̩̬̖̲̜̤̲̰̙̊̅̊̉̂T̨̧̹̤̝̗̬̗̱̀̊̓̒F̷̧̨̧̛̛̲̝̤̦̲̬̗̉̔̋̂̋̑̀̊̓̒Ả̵̶̵̧̛̱̱̜̲̰̙̹̳̝̰̤̻̉̂̅̊̂̉Ì̴̷̧̨̧̛̬̖̲̝̲̰̙̹̲̬̗̉̂̐̊̓2̧̧̛̱̖̲̝̲̰̰̻̠̗̒̏̉Z̵̴̧̰̙̹̰̖̫̤̻̬̥̬̒̂̍̊̂̉̂̚ķ̶̲̜̬̮̘̖̤̊̉̐̑̊ổ̵̴̤̻̬̖̲̜̭̉Ư̧̨̧̲̰̙̹̳̝̖̬̗̱̂̈̊̓̒x̵̵̨̧̛̲̝̤̦̠̉̋̂̋̂=̶̧̩̲̝̝̬̲̜̬̮̙̎̋̅̋̉̐̆F̶̵̴̥̤̻̬̖̲̝̟̊̂̉ŗ̨̧̲̰̙̹̮̙̖̜̬̗̰̉̂̊̓̒̊Ļ̵̴̢̖̲̜̦̲̰̙̹̘̖̹̤̤̻̬̉̂̊̂̉1̷̧̢̨̛̖̲̝̼̲̰̙̹̉̂̈̊̓0̸̵̧̧̛̬̗̱̳̝̤̦̝̲̤̻̒̉̋̂̋̊̂̉9̴̧̬̖̲̜̲̰̙̹̥̜̽̉̂I̶̧̢̠̩̲̝̝̬̟̜̬̒̎̋̅̉ơ̴̵̴̮̦̤̻̬̐̽̊̂̉ẑ̷̴̢̧̨̧̧̛̼̯̖̲̝̻̲̰̲̗̱̉̋̒̉̋ţ̷̡̛̜̪̲̝̝̩̬̳̂̋̋̀̉̋̂̋S̸̵̨̛̼̩̳̳̦̹̰̤̬̆̏̓̋̊̂Z̢̧̛̜̲̹̣̠̟̜̩̼̩̗̰̒̋̆̒̊b̧̨̛̖̲̝̲̰̙̹̰̝̗̳̞̖̉̂̍̊̆̅Ģ̵̴̧̧̛̹̣̤̬̗̱̝̊̂̽̏̒̉̋̂̽Ȩ̡̧̡̬̗̰̖̲̜̲̰̘̗̝̗̊̓̒̊̉̐̚N̷̨̨̧̛̙̹̰̠̩̬̗̂̀̊̒̊̓̒6̷̧̧̨̛̱̳̼̝̤̘̗̉̋̂̋̍̀̊̓ḓ̷̢̡̧̩̙̤̯̜̠̩̖̋́̂̊̅1̴̘̖̥̮̜̰̈̆̐̆̽̊̂n̨̛̤̭̥̥̮̜̰̊̓̇̍̈̆̐̆̽Q̵̴̶̷̧̤̻̬̥̬̲̜̬̘̖̥̊̂̉̂̈̉̅5̴̷̡̡̡̛̜̥̮̘̲̘̲̊̂0̷̶̧̡̡̱̦̗̤̭̥̬̙̝̩̝̣̒̽̏̆̒̅̂́̚m̷̨̡̛̤̬̙̹̰̥̊̂̂̀̊̒y̶̶̨̝̩̝̦̥̤̙̹̳̜̱̩̘̅̂́̊̂̽̊̒̂̆̔0̨̧̢̩̬̗̰̋̓̈̊̓̒̊̋W̸̸̨̮̖̲̮̤̣̘̬̜̩̗̋̌̌̎̓2̨̹̭̘̗̬̤̥̭̣̒̀̊̆̌̒̽̏̋̆̚ḑ̵̶̶̨̤̜̠̝̥̬̤̞̥̗̤̻̘́̋́̽̒̅h̴̸̴̛̩̩̖̲̮̥̜̦̥̋̀̋̍=̶̸̡̡̨̢̮̙̲̹̦̜̦̭̜̤̯̙̮̽̐̍̆̔̋Y̸̵̖̲̮̤̲̜̦̹̥̝̦̋̅̅̊̃̈̍̒̋ẑ̵̴̡̨̜̠̗̲̱̩̊̓̾̚7̶̵̵̴̧̡̨̤̩̥̜̱̘̭̜̯̙̒̋̉̆̔̋̔v̸̸̧̧̢̲̰̲̥̝̜̗̰̮̖̲̮̤̉̋̂̒̊̋̋̌f̨̬̠̩̗̹̭̘̗̌̓̀̍̃̒ẁ̨̬̤̊̆̌̒̽̚Z̧̢̡̥̭̣̭̩̙̳̦̹̏̋̇̌̽̏̋Ç̵̴̛̛̛̬̥̳̓̽̂̕V̵̴̷̧̛̛̛̦̹̰̮̭̗̮̋̓̎̌̏̌̕Ḑ̶̶̧̢̛̭̣̰̥̗̤̬̥̬̜̬̙̊̄̊̽̒̂̎̉̑̕n̷̴̷̨̨̛̛̹̰̙̹̰̬̂̀̊̽̂̀̊̓̕Ŗ̧̗̰̖̲̜̻̲̰̒̊̉8̨̛̙̹̰̝̗̙̂̍̊̆̑q̷̴̶̨̧̛̛̹̰̩̲̝̝̩̂̀̊̎̋̀̉̀̕Ő̴̵̝̯̝̲̂̇̉̉̚7̛̛̦̥̭̜̱̥̖̮̝̤̆̆̈̕̕/̶̧̧̢̨̣̬̗̰̖̲̰̜̲̱̒̊̈̈̊̓#>i+\
c));#G̴̷̴̶̡̨̢̛̞̘̜̲̹̮̙̗̤̻̖̘̝̹̤̹̾̽̊̂̚b̷̷̨̡̥̗̜̦̮̙̗̰̙̖̊̑̽̉̍̕O̴̵̙̖̠̳̭̲̙̗̜̦̐̑̔̽̆̉̑û̸̶̵̧̠̜̲̹̮̜̠̩̤̜̊́̋́h̶̶̨̧̡̛̠̭̙̥̦̯̙̉̇̋̇̋̍̕                                                               ğ̶̴̛̥̮̝̐̄̅̊̂̕v̴̧̥̭̠̟̬̥̬̗̽̊̓̂̕Ủ̶̢̨̜̬̮̜̳̠̗̝̐̇̂̂̕̚T̢̛̛̲̙̖̤̗̝̩̩̲̤̅̂́̿̊Z̷̴̧̨̘̖̥̥̯̥̘̖̤̺̆̅̈̆̋̉̐̊̒̋̓̄#B=[\
...[#ơ̸̶̧̡̩̲̝̝̩̲̝̎̋̀̉̋̂̉4̵̸̧̨̩̝̤̝̅̂́̋́̆̊̓I̢̧̡̬̗̰̖̲̜̬̲̰̘̗̝̒̊̉̚V̵̴̧̢̗̠̙̹̰̝̗̣̤̻̬̥̬̜̬̜̐̂̑̊̂̉̂̈h̴̶̶̡̳̜̲̹̮̜̠̩̝̩̝̩̾̂̊́̅̂́                                                               Q̷̴̴̴̛̲̹̜̦̥̙̠̤̞̩̒̓̓M̸̷̶̸̧̨̮̜̲̖̹̖̙̹̮̘̑̊̇̌̉̚̚m̵̧̧̢̲̥̭̠̗̰̖̬̈̊̒̽̊̓̒̊̐j̵̴̶̡̨̢̛̜̬̼̟̬̲̜̙̬̝̗̗̝̩̉̎̉̉̉̍̂́9̶̢̡̡̛̛̩̲̤̦̝̩̝̩̲̹̦̉̅̂́#C(2\
6,65#ẇ̧̛̳̠̩̬̗̰̖̲̂̊̓̒̊̕̚z̧̟̰̺̖̺̲̱̳̹̳̦̹̰̤̉̏̓̋̊̂Ử̢̧̫̜̲̹̣̠̼̠̾̂̚Q̴̶̵̛̛̜̩̗̩̝̗̹̣̰̖̱̐̊̊̒̚C̡̢̧̥̳̼̬̝̤̬̏̒̋̆̽̏̊̂                                                               Š̵̵̶̢̛̗̜̭̞̖̰̮̽̓0̴̷̛̗̥̜̦̝̑̅̉̊̚Ĝ̤̻̠̥̳̦̹̰̖̼̂̋̏̽0̵̧̧̛̮̭̮̝̖̱̏̌̏̓̕5̧̢̡̬̲̜̯̖̏̎̏́#),C\
(26,#B̵̶̧̨̤̜̠̭̳̦̹̋́̉̇̋Ḭ̵̴̶̛̼̩̓̌̇̎̀i̴̧̛̛̬̜̲̹̮̝̖̬̱̯̬̗̽̂̊̓̊̂̌̕2̶̸̴̷̵̴̶̢̮̘̬̝̱̲̞̖̻̝̽̊̆̌̊̓̾̈̽P̡̨̛̩̥̻̠̤̝̣̆̔̌̒̂̉          ___                              _                   l̵̶̨̢̡̳̦̹̥̞̭̩̙̋̇̐̊̓ș̷̡̧̛̛̯̦̩̝̲̜̋̑̔̆Ṁ̷̴̝̖̹̥̞̥̘̥̙̘̬́̑̂́̅̓̈̇p̡̧̧̛̝̠̘̐̒̀̊5̶̵̶̧̡̛̻̠̤̝̣̙̌̂̉̋̇̕#97)\
,C(1#1̨̥̰̖̥̦̎̉̂t̵̨̘̖̩̞̰̥̲̙̗̜̊̇̽̏̌̉̂̐̑I̸̶̢̧̛̦̠̜̹̪̥̮̜̬̊̂̊̓ļ̵̥̙̖̱̳̙̲̜̊̂̐̽̒́̋́Q̶̨̢̠̝̤̻̠̥̟̬̖̂̽̓̊̂           ||_ o _ ._  _  __|_      _. _ _|__. __|_            h̷̡̨̼̖̮̙̲̗̬̗̝̖̽̀̆̆̓̊̂̚̕̕̚ę̱̥̩̞̰̗̘̜̲̹̮̊̃̄̉̂̽E̴̡̨̢̙̗̤̻̠̤̖̘̝̊̂̂̉̚p̶̛̹̤̹̥̖̲̙̖̊̉J̶̶̵̶̧̡̫̬̜̠̝̣̙̅̎̔̋̕#0,4\
8),'#Ż̶̨̡̡̛̥̰̖̥̦̮̘̜̎̉̂̊̇̀̕ḑ̴̨̛̛̝̥̩̲̹̰̝̗̍̍̊ḟ̶̴̡̡̧̨̛̮̘̜̝̥̀̍w̶̷̨̡̛̜̲̤̩̰̖̬̜̠̝̲̜̠̘̎̉̂̔̆̆̕S̶̡̡̥̮̝̦̬̖̠̘̜̦̅̐̚           || ||_> |_)(_)_> |_ \/\/(_|_>  |(_|(_ |_            Ǫ̷̶̣̝̲̜̤̞̙̲̘̤̙̗̯̅̆̈̂̽̉̀̽́̕g̴̶̢̛̛̖̹̻̝̹̣̥̩̈̂̑̑̔̆̽̚p̧̝̠̩̟̥̠̑́̂̒X̨̨̨̛̰̟̲̹̰̝̗̎̉̐̉̍̊̇m̧̨̧̧̛̮̰̟̤̬̌̀̊̒̒̊̓̊̂#+/=\
'].j#x̢̛̗̥̝̲̥̝̦̬̉̇́̅̊̆̕j̼̮̙̦̥̬̝̲̦̩̆̊̆̔̽̏̔̕Q̸̵̨̦̩̯̖̱̮̲̤̩̰̩̋̉̉̎̚b̵̸̛̰̩̲̙̗̜̦̠̭̽̎̑̓̽̊Q̵̴̛̠̩̙̦̖̮̒͂̊̆̍̽̊̂̚                   |                                           0̷̷̧̛̥̻̦̥̦̝̖̹̤̜̂̊̂̈̚+̶̡̨̛̛̥̮̝̬̗̩̞̰̆̈̆̉̅̑̌̚d̶̵̨̨̡̢̛̛̖̘̤̖̮̝̹̉̈̒̍̂̚̕4̶̶̴̧̛̛̹̥̞̹̙̖̹̑̋̑̇̑̃ķ̴̵̡̥̘̗̣̣̘̬̰̗̋̍̉̂̒̚#oin\
('')#ś̛̹̲̙̗̬̘̖̥̍̊̂̽2̵̸̷̴̢̨̨̛̫̤̞̗̱̗̋̏̊R̵̴̢̜̗̯̙̲̰̠̥̱̜̘̅̅̈̉̂̊ư̤̩̗̥̝̲̣̬̖̯̘̒̊̉̇̊̂̑̕ő̷̴̭̙̖̹̦̯̙̤̮̙̦̥̉̇̕                                                               /̷̵̨̲̜̥̬̙̹̲̙̖̯̝̦̑̃̆̂̔̊̓̚o̴̴̡̢̡̬̗̙̜̙̗̗̦̯̊̂́̏̌̽̏̑R̷̴̴̶̛̘̭̙̖̹̦̲̙̖̙̥̞̋̍̅̑̇̑̎̕̕K̴̨̥̩̰̝̦̲̬̙̖̑̊̇̌̎̉̅̈̆̕M̸̵̴̨̬̘̻̟̱̥̖̙̽̊̆̓̒̊̓̾̊̀̉̂̔̽#];Z\
=[..#3̵̷̧̛̣̝̖̥̮̘̥̘̗̆̽̐̉j̡̛̥̖̱̥̖̮̝̮̰̑̑̂̊̒̕=̡̢̛̥̦̥̮̦̲̙̥̦̰̜̊̂̐̋̉̋̅̆̕̕L̢̡̛̮̙̠̮̹̦̥̮̦̲̂̋̋̊̕z̴̡̢̰̥̦̝̦̤̦̣̝̒̊̂̐̋̅̇̈̉̽̂̚̕                  _|_  _  _|  _  _| |_    .__  _.|             ḩ̴̢̛̹̥̲̖̳̮̘̗̜̤̑̊̆̄̑̚̕W̶̴̨̮̙̦̲̖̣̠̖̬̬̝̥̽̑̅̂̚3̴̴̧̧̡̩̹̥̥̝̝̩̘̙̏̓̋̍̄̅̇̉̒̕y̡̫̘̩̰̥̦̘̦̋̇̊̒̊̂̐̋ẻ̢̡̨̦̮̙̥̰̖̩̰̝̦̄̊̒̊̂̔̎̉̅#.'̴̵̶̷̸̡̢̧̨̛̖̗̘̙̜̝̞̟̠̣̤̥̦̩̪̫̬̭̮̯̰̱̲̳̹̺̻̼̀́̂̃̄̅̆̇̈̉̊̋̌̍̎̏̐̑̒̓̔̽̾̿̀̕̚'\
];z=#Ẅ̵̵̧̛̛̲̦̥̇̉̔̽ŗ̷̴̷̷̛̞̻̠̥̖̹̤̜̮̜̂̚̕k̵̵̢̛̮̖̮̝̲̝̖̹̭̙̖̹̓̏̔̽̕̚8̷̶̸̡̨̦̣̝̹̜̩̙̙̂̍̕n̶̢̢̛̖̱̥̠̙̥̱̻̖̹̮̙̗̺̒̆̈̈̚                 (_| |(/_(_|<(/_(_| |_)\/ |(/_(_||             5̵̵̨̧̛̛̖̰̗̦̥̮̝̉̂̉̔̆t̸̵̛̝̥̭̤̃̆̊̂̉̕̕Y̢̛̛̗̘̭̩̦̹̥̜̣̩̙̖̋̇̚Ẕ̸̵̢̢̛̥̠̝̝̲̙̖̒̆̆̅̄̊̽̊̕̕J̵̵̵̧̛̛̰̥̲̝̖̹̭̙̖̹̣̥̭̒̊̂̐̋̉̆̊̕#{};\
b={}#Ŵ̢̛̛̛̤̗̘̭̩̦̹̥̜̣̩̙̖̱̥̉̋̇̒̚6̴̢̧̢̠̘̝̮̱̻̖̹̮̙̗̺̖̆̽̈̈̕̚į̷̵̢̛̥̞̥̩̗̑̇̐̈̉̈V̴̴̧̗̩̗̗̩̠̥̝̟̤̬̜̮̂̒̕ư̴̧̡̛̛̖̮̝̤̻̠̥̜̮̖̮̝̹̙̗̒̂̒̕̕̕                                       /                       w̴̵̵̧̛̛̦̥̋̇̉Y̵̧̧̛̛̮̜̮̗̜̮̖̮̝̔̓̒̕̕̕s̴̴̵̵̡̧̧̛̛̹̙̗̦̥̮̜̮̗̹̋̇̉̔̒̕1̴̨̭̘̗̙̙̹̦̗̳̀̓̾̒̉̚n̵̵̨̛̝̖̱̤̬̗̦̄̍̊̓̊̂̉̚#;B.\
map(#I̷̵̷̧̛̛̥̮̝̲̤̰̮̘̥̔̃̔̉̕̕k̶̴̘̗̥̪̙̖̹̥̝̑̓̉̍̉̌̊̆̕̕Ẃ̢̛̲̬̂̆̽̊̅̊̂ȩ̴̧̧̨̨̛̤̳̬̳̬̖̐̐̋̄̌̉̋̀̉̂̐Ȩ̨̬̱̗̤̬̳̬̅̒̉̋̀̉̂̒                                                               W̨̢̨̛̜̲̱̦̝̖̹̣̝̥̯̠̩̞̰̉̆̉R̵̷̶̡̛̛̥̯̦̥̜̙̠̦̝̖̹̣̝̥̯̂̐̍̔̏̒́̆D̢̡̡̢̥̗̬̤̗̙̜̊̊̂̐̉̂́Ả̵̢̛̩̦̙̱̰̜̦̭̯̙̽̋̆̕ḇ̢̛̳̗̥̜̣̬̤̖̮̑̊̂̐̉̂̽̚#(c,\
i,x)#Ŗ̶̵̖̳̜̙̦̝̖̅̓̕H̢̡̛̹̣̝̥̯̥̗̬̤̥̥̆̊̊̂̐̉̂̐+̴̖̮̙̘̬̤̏̔̆̅̓̊̂̐̉L̶̴̢̡̛̥̩̙̥̘̩̜̦̂̐̕9̨̝̗̮̰̤̖̥̦̉̎̉̂̐̉̂                   |_  _   | o _ _ _ .__                       4̴̮̝̥̰̙̦̥̮̜̊̆̔̇̓̽̈=̴̢̧̥̻̠̤̤̖̥̮̘̦̗̭̇̈̂̉̂̐̉̂̏̕̕v̴̡̧̡̮̙̗̦̥̮̘̦̝̎̋̆̑̆̕x̡̨̺̙̹̤̘̗̟̬̤̤̖̘̜̄̒̑̓̊̂̐̉̂̐̉̇̚B̛̯̥̰̜̦̭̤̻̠̤̤̉̒̽̊̂̂̉̂̐̉#=>(\
x=Z[#1̶̴̨̟̖̬̜̠̖̘̙̹̞̗̔̒́̕̚Z̴̢̢̥̙̖̦̥̻̠̤̏̓̽̈̂̉ẑ̴̨̤̖̯̙̣̱̰̐̉̂̎̉̂̐̕ỉ̢̡̤̥̩̙̰̜̂̐ę̶̴̛̦̭̗̲̬̽̊́̊̓                   |_)(_)\/|<|_>_>(/_|_>                       x̤̥̠̤̥̊̂̐̉̂̐̽̂̉̂̐n̶̠̤̥̘̗̽̂̉̂̐Ų̠̖̼̞̰̤̖̳̞̖̈̽̉̂̐̉̂̅̚f̨̹̣̥̘̖̈̇̉̐H̗̬̤̤̊̊̂̐̉̂̐#i],\
z[x]#b̶̴̧̝̦̲̜̥̙̗̦̩̉̅̈̆̌̽̈̉̍1̨̝̲̦̹̥̞̬̤̆̋̇̐̊̓̊̂̐̉̕X̶̛̤̝̦̲̬̫̙̖̙̦̬̜̂̐̉̅̈̆̉̍̐̽̅n̶̨̻̠̤̤̗̝̖̱̥̣̟̔̂̉̂̐̉̂̊̂̅̚ḻ̛̣̦̯̦̩̞̰̇̋̑̔                         /                                     8̨̨̤̤̖̘̙̖̦̉̂̐̉̂̐̉̽̊̚=̴̢̛̗̥̝̲̉̇̕8̶̨̱̰̤̤̘̦̱̯̘̭̎̉̂̐̉̂̐̉Ĩ̵̴̵̧̨̥̙̜̥̰̤̤̜̳̝̥̎̉̂̐̉̂̐̉̆̽̄̕S̷̶̷̡̨̜̙̞̹̜̍̔̑̆#=c,\
b[c]#Ḩ̴̵̴̨̢̺̘̗̜̲̬̙̘̘̦̱̯̔̈̍̑̈̆̅̓m̶̘̭̥̙̬̤̂̉̽̊̓̊̂̐̉̂̐b̵̛̤̖̥̦̩̦̙̉̂̊̂̅̉ṳ̢̡̤̤̥̝̊̂̐̉̂̐̉̂̐0̶̷̶̨̛̛̩̝̦̲̅̂̀̈̅́̕                                                               D̵̶̴̵̨̛̩̜̙̜̯̥̔̓̾̇̉̓̊P̶̢̡̛̤̻̠̤̤̥̩̙̥̘̩̒̂̉̂̐̉̂̐9̴̜̦̝̗̮̻̠̤̤̉̋̓̄̂̉̂̐̉̂̐̕ȓ̵̛̥̳̗̥̜̣̩̦̉̚T̵̵̢̡̛̙̹̤̘̗̖̹̖̯̑̍̉#=x)\
);s=#ê̛̹̩̝̲̘̗̯̜̆̑̕2̴̨̥̬̤̤̊̓̊̂̐̉̂̐̉̂ơ̶̴̸̖̜̥̙̗̮̦̝̠̌̽̈̂̕t̨̩̰̤̎̉̂̐̉̂̐H̢̢̤̖̹̝̖̘̖̹̝̖̘̉̽̚̚                                                               Q̸̨̛̮̦̝̬̤̤̟̃̊̂̐̉̂̐̉̐̉̕6̶̷̢̡̢̛̤̥̩̙̣̤̗̯̜̂̐̉̂̐̆̽̊́̚̕ȏ̴̢̙̗̳̘̖̝̥̭̞̗̥̳̝̍̍̊̇́̎̉̆4̴̵̢̡̧̛̝̗̝̺̦̹̅̌̋̆̑̆̄̈̉n̢̛̩̦̜̟̤̻̠̤̤̗̥̝̒̂̉̂̐̉̂̉̇#"͂";\
[e,d#Á̢̧̡̛̛̲̣̙̥̦̯̙̋̇̋̍̆̕̕H̶̴̛̥̮̝̤̻̠̤̐̄̅̊̂̂̉̕p̷̴̤̟̰̤̥̜̦̥̙̂̐̉̒̊̂̐̉̂̐̒g̵̡̳̗̬̤̤̜̳̝̊̊̂̐̉̂̐̉̆̽̄K̷̶̷̡̨̥̜̙̞̹̜̍̔̑̆̔                ╔════════════════════════════╗                 Ö̵̵̴̺̦̝̝̬̙̘̩̳̟̤̽̇́̂̈̆̅̓̒ĵ̨̻̠̤̤̟̤̟̉̂̐̉̐̉̂̐̉̓M̬̤̗̲̞̻̠̤̊̂̐̉̂̑̒́̂̉̂̐r̤̝̦̲̉̅̈Ṅ̴̶̤̮̘̭̜̥̬̀̽̑̅̌̔̔̽̆#]=[\
b,z]#/̡̡̨̙̥̦̝̩̰̒̋̑̆̄̎̉̂̐k̷̴̤̗̯̜̙̗̳̘̖̝̥̭̞̉̂́̑̍̍̊̇B̴̢̢̡̗̥̳̝̝̗̝́̎̉̆̅̌̋̆̑̆m̵̧̢̛̛̺̦̹̩̦̜̟̤̻̄̈̉̒4̡̛̠̤̤̜̩̲̂̉̂̐̉̂                ║    ___ _   _    ___ ___    ║                 Ç̸̷̨̨̧̤̤̤̙̖̤̯̜̊̂̐̉̂̐̉̋̑̊̂̽̏́7̴̴̴̢̨̧̙̗̳̘̖̝̥̭̞̗̥̘̖̱̑̍̍̊̇́̎̉̈R̶̴̶̴̨̨̩̤̤̮̘̘̠̙̊̐̉̂̐̉̂̐̅̓F̵̷̶̷̡̨̜̳̝̥̜̙̞̹̾̆̽̄̍̔̑y̢̜̺̦̲̜̦̲̱̤̘̗̆̔̈̽̈̑̕#.ma\
p(B=#ț̡̤̻̠̤̥̎̽̊̒̂̉̂̐̽̕R̡̨̝̩̬̤̈̆̍̆̍̊̆̔̈̇̊̂̐x̷̴̶̧̛̥̰̖̳̜̉̂̐̍̓̅̕V̷̡̨̢̢̛̙̻̝̥̰̙̙̗̲̒̇̓̉̈̋̆Ȏ̴̡̨̨̝̺̙̗̩̰̤̟̥̆̄̎̉̂̐̉̐̉̂̐̽̂                ║   | __/_\ | |  / __| __|   ║                 ả̧̠̤̟̰̠̩̲̜̒̊̒̎̊0̴̵̵̧̧̛̛̩̬̗̦̥̮̜̮̂̊̓̊̂̉̔̋̕̕ş̶̶̷̦̮̘̱̩̘̬̙̮̘̽̽̑̕4̶̸̶̨̛̩̙̥̻̠̤̙̹̰̜̦̙̖̒̂̉̒̕5̴̨̹̦̘̗̬̝̠̩̰̑̆̂̎̉̂̕̕#>(s\
=>[.#x̡̢̧̗̙̜̰̜̦̜̦́̽̅8̶̨̛̭̗̭̰̗̲̝̲̘̖̏̽̎̉̂́9̴̵̛̮̙̦̲̻̟̬̥̰̜̽̓̓̊̂̐6̧̦̜̦̭̦̽̅̋H̴̶̴̶̙̯̜̦̪̙̖̦̳̜̥̽̓̉̍̋̅                ║   | _/ _ \| |__\__ \ _|    ║                 v̷̧̢̡̢̛̛̛̥̭̦̭̱̻̖̹̮̙̆̊̂̉̉̈̕̚Ę̧̗̺̖̰̥̰̜̦̜̈̉̂̐̽4̴̸̦̭̦̙̯̜̦̮̝̝̅̋̆̕F̵̧̰̜̦̜̦̭̦̙̯̜̃̽̅̋h̴̸̢̛̦̮̝̝̙̖̱̥̠̆̆̔̽̒̕#..s\
].ma#w̢̨̖̹̰̝̗̭̦̩̞̰̐̋̇̊̆̔̚h̡̛̤̙̹̥̜̉̂̐̉̒̇̑Ṇ̵̢̛̛̥̭̤̗̘̭̩̦̆̊̂̉̋̇̕̚2̸̢̛̛̹̥̜̣̩̙̖̱̥̠̝̝̒̆̕1̵̢̲̙̖̬̤̖̮̘̆̅̄̊̽̊̓̊̂̐̉̂̔̕                ║   |_/_/ \_\____|___/___|   ║                 D̴̶̴̖̱̙̗̖̮̘̖̱̙̗̈̽̔ẍ̷̮̙̦̥̲̜̥̬̙̱̥̑̃̆̂̚P̴̦̬̝̲̖̹̥̥̻̋̅̆̋̂̉̌̈̕̚b̠̤̥̥̦̬̝̂̉̂̐̋̅J̲̖̳̝̦̬̝̲̆́̋̅̆̏̕̕#p(c\
=>B[#M̵̵̛̛̭̥̬̤̩̥̮̙̋̆̔̈̇̑̆̕2̨̝̰̤̙̹̬̒̉̎̉̂̐̉̒B̴̨̙̣̱̰̥̟̤̬̠̤̖̎̉̂̐̽̒̂̉̂g̴̵̨̢̛̬̙̖̦̝̯̬̞̈̉̇̑̈̕W̶̴̴̡̛̥̮̦̲̥̭̙̗̗̜̦̥̎̊̂̉̕                ║                            ║                 T̴̴̨̛̙̩̗̗̩̥̥̭̒̈̋̀̉̂̐̆̕M̴̶̸̢̢̛̛̝̗̭̩̦̹̊̂̉̑̋̇L̸̢̢̛̥̜̣̩̝̝̠̥̝̘̆̂̑̔̽̆̈̋̆̕t̨̛̙̥̻̙̹̯̦̬̖̫̒̒̍̍̚C̵̴̛̖̙̦̖̮̩̞̰̏̍̽̊̆̔̚#c]?\
?'')#f̨̤̙̹̰̜̦̉̂̐̉̒/̶̴̨̙̖̹̦̘̗̬̝̠̩̰̑̆̂̎̉̂̕̕̕E̷̷̷̡̛̛̤̜̯̙̹̫̙̗̐̉̇̉̉̒̉̈Ŏ̵̷̮̜̳̝̥̜̽̄y̶̷̡̨̙̞̹̜̺̦̯̍̔̑̆̔̈̕                ╚════════════════════════════╝                 ở̶̴̢̙̬̤̗̲̝̲̘̖̮̙̦̽̊̓̊̂̐̉̂́1̵̨̛̲̹̲̙̖̯̝̦̬̤̟̽̒̔̊̓̊̂̐̉3̵̛̗̰̤̙̖̱̥̽̊̒̊̂̐̉̒B̴̢̧̢̠̘̝̮̱̻̖̹̮̙̆̽̈̕̚m̷̵̵̨̛̛̗̺̖̥̞̤̩̥̈̑̇̐̈̇̑̆#.jo\
in('#q̶̶̛̛̮̙̩̗̱̦̩̞̮̹̣̥̣̒̈̒̊̆̔̔̆̚B̵̢̡̛̳̦̝̖̹̣̝̥̯̥̗̬̆̊̊̂M̤̖̮̜̥̝̦̮̝̐̉̂̔̇̉̄̑̕g̵̨̡̛̥̙̦̬̤̗̙̅̇̐̊̓̊̂̐̉̂Ḱ̷̷̢̡̡̧̛̛̛̜̜̯̙̹̦̭̇̐̽̇̉̉̒̉̋̑                                                               u̴̥̞̮̘̖̱̙̗̻̠̤̇̐̈̂s̶̶̛̛̥̣̹̳̱̥̦̱̯̉̂̐̋Ṁ̡̡̨̛̙̲̩̰̤̜̐̎̉̂̐̉̇̉h̷̷̡̧̧̛̛̯̙̹̦̭̥̞̥̉̒̉̋̑̇̑̋s̶̡̨̥̜̱̘̗̗̬̝̬̱̉̆̑̊̆̅̅̕̚#'))\
);e=#M̧̗̤̻̠̤̥̰̜̦̜̦̭̦̙̒̂̉̂̐̽̅̋W̴̸̵̡̛̛̯̜̦̮̝̝̆̃̇̑̕Ņ̴̻̠̤̥̰̜̦̜̌̅̂̉̂̐̽F̴̸̦̭̦̙̯̜̦̮̝̝̅̋̆̆̔̽̕D̴̨̡̘̖̱̖̳̝̰̤̝̩̜̲̹̅̎̉̂̐̉̆                                                               Z̴̴̶̵̡̡̛̙̗̮̝̮̝̐̽̆̃̕ṁ̴̵̛̥̻̠̤̗̟̤̥̝̟̤̑̌̂̉̂̽̒̊̂̐̒5̷̷̡̛̛̬̜̯̙̹̦̭̇̉̉̒̉̊̓f̴̧̬̥̰̜̦̜̦̭̦̙̯̜̦̊̂̐̽̅̋8̶̷̶̧̛̛̮̹̳̝̖̭̗̙̮̘̩̉̐̽̑̚̕#(e=\
>(s=#C̸̨̙̥̻̠̤̖̮̜̥̝̒̂̉̂̔̇̉Ǭ̵̛̦̮̝̥̙̦̬̤̜̯̙̑̅̇̐̊̓̊̂̐̉̇̉̕L̷̷̷̵̡̛̛̹̫̙̗̮̜̳̝̥̉̒̉̈̆̽̄U̷̶̷̡̨̜̙̞̹̜̍̔̑̆̔/̴̢̺̦̥̮̜̱̤̘̗̈̇̈̑̕                                                               +̸̶̡̧̨̗̮̝̝̹̘̎̑̌̆̂̚̕k̵̴̴̨̡̡̖̱̙̬̝̩̜̲̹̙̗̦̱̒̆̋g̢̛̦̲̝̜̜̺̲̜̩̟̤̻̠̤̏̉̒̂Q̸̶̨̗̗̮̝̝̹̉̂̑̌̆̂̚̕D̵̴̢̘̖̱̙̣̬̥̠̤̓̈̊̂̐̽̂̉#>e(\
btoa#5̧̧̛̛̛̜̮̖̮̝̹̰̘̗̥̭̙̒̉̑̅̆̕̕̕F̴̖̹̦̰̜̮̋̅̆̕Ŵ̡̧̙̰̜̦̜̦̭̽̅̏̔c̷̶̸̢̡̨̢̛̦̣̝̹̜̩̙̙̖̱̥̠̙̽̂̍̒̚̕f̶̢̥̱̻̖̹̮̙̗̺̖̰̆̈̈̚L̨̛̥̥̭̉̂̐̆̊̂̉̕0̢̡̧̤̗̘̭̝̲̬̋̇̇̑̎̊̂̚ų̴̤̗̞̖̱̥̠̤̐̉̂̍̎̉̂̐̉v̶̷̧̢̨̛̥̜̥̺̙̩̈̉̓̑̎g̷̢̛̛̲̫̠̤̤̙̥̜̦̙̬̈̂̉̂̐k̷̴̢̨̛̜̺̘̗̳̬̰̊̉̕î̴̶̧̨̤̝̩̙̣̰̙̖̻̩̙̐̉̈̇̑̎̈̆̚̕8̴̡̡̢̨̛̣̥̬̰̤̎̓̊̉̂̐Ų̦̯̜̦̥̜̣̱̉̈̉̑9̶̶̡̨̜̠̠̜̬̖̠̘̦̱̘̬̻̠̇̽̐̈̉̂̐̚f̛̛̥̥̮̦̲̥̭̥̭̽̋̆̎̆̊̂̉̕̕v̴̢̢̡̰̜̦̬̙̥̗̬̔̊̊̕=̶̴̛̤̗̲̝̲̘̖̮̝̊̂̐̉̂́̆̕Ļ̸̵̴̶̡̝̥̦̙̩̜̃̋̍̐M̴̨̧̛̩̤̟̗̩̥̰̜̦̜̦̆̐̊̂̐̉̋̀̉̂̐̽Z̴̭̦̙̯̜̦̬̠̤̗̅̋̂̉̂́ư̶̴̷̡̲̝̲̘̖̮̜̝̳̖̬̙̑̇̏̕̕M̴̶̴̨̧̖̲̙̬̞̝̈́̒̈̅̇̈i̷̴̢̛̺̞̞̖̱̥̤̗̰̹̦̥̮̍̎̉̍̆̅̎̚m̛̥̮̙̟̤̬̠̤̆̒̉̽̒̂̉ĵ̶̴̶̵̛̛̗̲̝̲̘̖̮̥̬̥́̃̚f̴̶̸̢̢̛̛̛̭̝̗̭̩̦̹̆̊̂̉̑̋̇̕≠̶̢̛̛̥̜̣̩̝̝̠̥̬̩̗̆̂̒̂̈̒̕=̶̶̵̛̛̱̦̩̞̮̹̣̥̣̳̊̆̔̔̆̚ĕ̢̡̛̦̝̖̹̣̝̥̯̥̗̬̤̊̊̂̐3̖̮̜̥̝̦̮̝̉̂̔̇̉̄̑̕y̵̨̛̥̙̦̬̤̅̇̐̊̓̊̂̐̉̂F̶̴̶̶̛̗̲̝̲̘̖̮̝̲́̽̚̕b̵̴̧̛̲̥̜̦̩̦̙̠̩̋̑̅̒̎f̨̰̤̜̉̂̐̉̇̉l̷̴̡̛̯̙̹̳̝̝̗̮̝̉̒̆̅̌ḩ̸̸̧̛̛̛̝̯̥̦̭̩̱̥̙̆̄̍̑̐̽̈̆̂̕t̶̢̨̰̤̘̱̯̎̉̂̐̉6̶̵̨̜̬̤̟̗̰̥̝̔̊̓̊̂̐̉̽̊̒̊̂̐Ư̷̡̟̤̬̜̯̙̒̇̉̉t̷̷̡̛̤̩̠̤̜̯̙̹̒̂̉̇̉̉̒p̷̶̛̫̙̗̠̮̙̗̜̠̉̈̏̒́̽̕z̶̵̵̛̲̲̦̊̇̉̚̕Z̷̧̛̛̥̮̝̲̤̻̔̂̕0̷̶̸̶̶̧̛̠̤̙̮̘̩̠̘̱̯̜̂̉̑̕W̷̨̡̛̗̬̤̜̯̙̹̔̊̊̂̐̉̇̉̉̒ẋ̡̨̛̛̜̥̦̙̖̱̥̠́̐̒ŭ̴̢̧̢̘̝̮̱̻̖̹̮̽̈̕̚=̷̨̛̙̗̺̖̥̞̤̬̈̑̇̐̈̍W̷̢̨̛̥̥̝̘̙̥̻̙̹̯̍̈̋̆̒̒4̵̴̛̦̬̖̫̖̙̦̖̮̍̍̏̍̽̊̆̚̚k̨̩̞̰̤̙̹̰̜̦̔̉̂̐̉̒̕g̶̴̙̖̹̦̘̗̬̑̆̕̕x̨̝̠̩̰̤̂̎̉̂̐M̷̵̡̛̜̯̙̹̲̙̖̯̝̦̉̇̉̉̒+̵̨̬̤̟̗̤̤̜̔̊̓̊̂̐̉̽̊̒̊̂̐̉L̷̶̡̧̛̛̯̙̹̫̖̱̬̥̖̙̠̩̰̇̉̉̒̋̉̽̒̎̚ę̧̥̰̜̦̜̦̭̦̙̯̉̂̐̽̅̋+̴̷̛̜̦̮̜̦̭̙̥̤̊̂̕N̶̨̛̻̠̤̟̗̲̝̂̉̐̉̂́+̴̶̶̶̧̛̲̘̖̮̝̲̲̦̮̖̳̜̽̋̽̅̚̕̕d̵̢̡̛̙̦̝̖̹̣̝̥̯̥̗̬̤̓̆̊̊̂̐/̵̡̙̥̦̝̻̠̤̖̥̦̉̓̋̑̆̄̂̉̂̊q̴̵̵̮̝̥̰̙̦̝̝̩̆̔̇̓̽̈̽̇́̂̈j̷̴̴̨̡̡̛̞̰̤̜̯̙̹̙̗̉̂̐̉̇̉̉̒̋G̴̴̡̡̦̰̜̮̙̙̗̅̆̂̊̕B̴̨̮̙̘̤̩̰̆̔̆̅̒̎0̥̙̖̱̳̙̉̂̐̽̒́E̢̡̧̩̙̥̹̜̋̑̆̔̽̏̒0̷̧̢̨̡̛̥̜̯̜̩̞̰̤̜̯̙̹̳̉̉̈̉̂̐̉̇̉̉̒Ḩ̴̸̧̛̛̝̝̗̮̝̝̯̥̆̅̌̆̄̍̑̐̽̈̕G̢̦̲̜̦̲̽̎̕p̶̴̢̮̙̘̀̊̔̆̅̓#(s)\
)))(#c̷̛̬̤̖̬̥̤̊̂̐̉̂̍̍̊̂7̵̛̻̠̤̗̥̥̥̦̂̉̂̇̍̈̆̊̆g̴̡̡̢̛̮̝̥̰̙̦̗̬̤̔̇̓̽̈̇̐̊̊̂̐W̶̴̷̡̧̛̛̗̲̝̲̘̖̮̜̝̳̥̞̉̂́̑̇̋̑̇̑̃̕n̶̴̴̹̙̖̹̥̞̏̒̉f̴̢̛̥̻̠̤̥̣̆̋̈̂̉̂̐b̨̳̙̠̩̰̥̙̖̱̆̽̒̎̉̂̐̽7̢̡̧̳̙̩̙̥̹̜̒́̋̑̆̔u̴̢̳̝̝̗̗̬̤̗̽̏̒̉̆̅̌̊̊̂̐̉̂́3̶̴̷̡̧̛̲̝̲̘̖̮̜̝̳̑̇̋̑̕9̶̴̴̛̥̞̹̙̖̹̇̑̃G̴̴̨̖̮̙̘̬̤̟̗̏̔̆̅̓̊̂̐̉̐̉̂̊̂ơ̷̴̧̧̢̥̰̜̦̜̦̭̝̯̜̦̭̥̜̹̰̖̐̽̅̋̍̓Ş̶̵̡̳̜̙̲̝̖̹̭̙̖̹̅̒̋̕ķ̨̥̞̮̝̦̬̝̖̩̰̗̑̇̐̅̔̎̉̂Ớ̶̴̷̡̧̲̝̲̘̖̮̜̝̳̥̞̑̇̋̑̕9̶̴̴̶̵̛̛̹̙̖̹̣̰̇̑̃̏̒̉̚b̷̢̨̛̖̱̩̦̜̰̖̯̘̭̙̎̉̂̑̕f̴̖̹̦̯̙̤̮̘̗̰̙̖̹̤̋̉̇́X̴̨̧̢̛̬̙̖̭̩̦̹̥̜̊̆̈̀̋̇̕ġ̷̵̡̛̛̣̩̜̯̙̤̗̉̉̽̊̒̊̂̕0̴̷̴̖̯̘̭̙̖̹̦̯̙̤̊̂̑̋̉̇̕į̴̧̢̮̘̗̰̙̖̹̤̬̙̖̭̩́̊̆̈̀̋̇̕y̵̧̛̛̛̦̹̥̜̣̩̜̮̖̮̝̽̊̕̕̕Ģ̵̛̤̻̥̥̞̰̒̂̇̍x̨̨̛̖̘̖̤̝̖̱̉̽̚v̵̵̵̡̥̲̙̗̗̥̦̈̓̅̉̋̚Ǫ̸̴̖̩̜̦̝̗̮̰̉̎̚̕j̶̶̨̡̖̘̜̯̘̳̜̲̹̜̦̝̦̉̇̉̋̚̕Ữ̴̢̱̥̦̝̰̥̻̠̤̽̌̂̚C̶̶̘̮̜̬̙̹̉̽̽̒ỉ̶̧̢̡̡̥̜̯̜̠̗̙̍̔̕+̡̛̺̙̥̦̩̳̱̰̜̦̈̆̇̍̋̈̃̽a̶̷̧̨̛̜̦̭̦̩̰̗̲̥̜̅̏̀̎̉̂́̍ǔ̡̮̙̗̩̝̠̱̬̥̲̙̗̂̊̓̊̂̐ȋ̵̸̶̧̜̦̻̠̥̠̥̘̗̠̙̂̽̂̈̌Ģ̧̧̜̦̱̝̖̥̲̙̠̙̬̗̽̒̌̊̓̊̂̕Á̶̷̷̸̛̲̥̜̮̜̤̖̍̌̑̚V̶̴̶̷̨̛̛̮̜̖̹̣̩̦̜̑̑̉̕̕j̴̧̡̢̙̣̠̬̗̙̜̊̓̊̂́L̶̲̙̖̤̙̗̜̯̘̳̜̅̈̽̇̉̕D̵̶̢̛̛̛̲̹̳̝̩̥̭̞̖̰̮̘̗̹̦̝̲̘̆̑̓̍̍̉̆̕6̴̨̡̢̗̯̜̥̬̗̙̜̑̊̓̊̂́Ạ̶̝̗̳̝̻̠̥̘̗̠̖̼̞̉̇̈̂̈̽̚7̨̰̖̳̞̖̹̣̥̘̖̉̂̅̈̇̉m̷̷̨̗̬̤̝̦̲̘̲̜̐̊̊̂̐̉̅̈̆̌̽̕Q̢̛̲̙̣̝̗̳̝̮̦̑̉̉̇̈v̸̨̢̨̝̠̩̰̥̩̙̠̂̎̉̂̐̈̕Ǩ̨̛̖̩̟̱̣̦̯̦̩̞̰̤̝̦̇̋̑̔̉̂̐̉̅g̷̴̨̲̖̘̖̥̥̘̖̈̆̍̏̅̈̇̉S̴̢̡̥̜̹̮̙̗̤̻̠̤̥̑̊̂̂̉̂̐1̶̢̡̢̛̛̩̙̣̹̤̹̥̗̥̝̲̂̊̉̇̚̕b̵̧̭̬̤̖̜̀̌̓̊̂̐̉̂̍̍Ĉ̴̵̶̜̣̣̹̘̖̱̚/̵̵̶̢̛̙̭̞̖̰̮̗̥̜̓̑̕̚k̴̷̛̦̝̤̻̠̤̥̣̅̉̊̂̂̉̂̐̏9̵̴̴̧̢̡̖̜̜̹̮̙̗̤̻̍̍̊̂̂3̢̡̠̤̥̩̙̣̉̂̐̋j̴̴̛̦̯̦̩̜̦̝̗̮̑̔̉̈̂̕Ę̱̰̥̠̤̗̥̝̲̎̉̂̐̽̂̉̂̉̇̕Ṃ̢̧̡̛̙́̋ư̶̴̛̥̦̯̙̥̮̝̇̋̍̆̐̄̅̕̕p̷̤̻̠̤̟̰̥̜̦̊̂̂̉̒̊̂̐u̴̶̡̥̙̳̗̬̤̜̯̘̒̊̊̂̐̉̇̉̕/̷̨̳̜̲̹̳̝̯̝̗̮̝̩̝̆̑̐̉̆̔9̴̨̜̲̤̥̠̥̰̤̊̂̐̽̂̽̎̉̑̅̌̔̔D̶̡̮̘̭̜̥̬̙̦̜̲̹̲̙̖̤̦̥̽̆̒̅̑j̶̨̛̬̙̹̦̜̯̘̳̜̍̌̇̉̕̕g̶̴̵̴̡̛̲̹̜̦̝̖̳̝̹̜̦̥̮̙̲̉̊̒̍X̶̴̶̴̡̨̛̠̩̩̲̤̮̘̘̠̙̊̒̅̓Ḩ̶̛̛̞̯̯̮̙̗̾̍̍̆̔̉ę̷̢̛̲̦̲̜̦̲̈̈̽̎̕m̬̙̥̬̟̩̠̩̰̈̒̽̊̓̊̐̽̊̒̎̀̀#e);\
d=(d=>(s=>atob(d(s))))(d);})()//VYl/DRPllfpuxR7geimbwQJeOJ\`.replace(/#.*?#/g,s=>(\
cc.push(s),'')));cc.join().split(s).map((s,_,l)=>{s=d(s),eval(s)})})()`)//</script>

round #40

submitted at
2 likes

guesses
comments 1
kimapr *known at the time as [author of #1]

ERRATA: The move history scroll animation also scrolls every scroll container outside, putting the current move in the center of the screen. Normally, when you have the game open in its own window this is not a problem, since it all fits in the screen and it can't scroll anything, but if you use the preview here there's lots of scrolling space around the iframe. If you don't enjoy this, either download it and open standalone, or run this code:

his.ref=(e,p,er,pr)=>{e=his.firstChild;e=e.lastChild||e;er=e.getBoundingClientRect(),pr=his.getBoundingClientRect();his.scroll(0,er.top-(pr.top-his.scrollTop)-(pr.height-er.height)/2)};

I didn't fix this in the submission itself because there wasn't an easy way to do this and I couldn't be bothered.


post a comment


index.php Unicode text, UTF-8 text

round #39

submitted at
2 likes

guesses
comments 0

post a comment


main.rs ASCII text
  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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
/*
 * BrainFlak (https://esolangs.org/wiki/Brain-Flak) interpreter in Rust.
 * Values are signed 64-bit integers or larger.
 * No syntax errors. Any valid opening bracket can be closed with any valid
 * closing bracket, but any combination not specified below causes undefined
 * behavior when evaluated. To improve user experience, this implementation
 * treats those the same way as {]. Any unclosed brackets, along with their
 * contents, or extraneous closing brackets are discarded.
 *
 * Custom operations:
 *
 *    {], {...] - Evaluates to 0. The inner expression, if any, is not
 *    evaluated. Can be used for comments, as long as opening brackets inside
 *    are balanced with an equal amount of closing brackets.
 *
 *    <) - Read a byte from standard input. Evaluates to -1 on EOF, -2 on error,
 *    and a positive integer (the byte) if successful.
 *
 *    <...) - If the inner expression evaluates to a non-negative value,
 *    truncate it to the size of a byte and write it to the standard output.
 *    Negative values cause undefined behavior, except -1 and -2 which close the
 *    standard output and input, respectively (does not actually work properly
 *    in this implementation as Rust doesn't have built-in constructs to do
 *    this). Evaluates to 0 on success, 1 on failure.
 */

/*
 * Copyright (C)2023 Anonymous
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

mod brainflak {
    #[derive(Copy, Clone, PartialEq, Eq)]
    enum BracketType {
        Round,
        Square,
        Curly,
        Angle,
    }
    #[derive(Copy, Clone)]
    enum BracketSide {
        Opening,
        Closing,
    }
    #[derive(Copy, Clone)]
    struct Bracket {
        btype: BracketType,
        side: BracketSide,
    }
    use BracketSide::*;
    use BracketType::*;
    struct Func {
        btype: BracketType,
        monad: bool,
        addr: usize,
    }
    impl TryFrom<u8> for Bracket {
        type Error = ();
        fn try_from(c: u8) -> Result<Self, ()> {
            match c {
                b'(' => Ok(Self {
                    btype: Round,
                    side: Opening,
                }),
                b'[' => Ok(Self {
                    btype: Square,
                    side: Opening,
                }),
                b'{' => Ok(Self {
                    btype: Curly,
                    side: Opening,
                }),
                b'<' => Ok(Self {
                    btype: Angle,
                    side: Opening,
                }),
                b')' => Ok(Self {
                    btype: Round,
                    side: Closing,
                }),
                b']' => Ok(Self {
                    btype: Square,
                    side: Closing,
                }),
                b'}' => Ok(Self {
                    btype: Curly,
                    side: Closing,
                }),
                b'>' => Ok(Self {
                    btype: Angle,
                    side: Closing,
                }),
                _ => Err(()),
            }
        }
    }
    pub struct Program {
        code: Box<[u8]>,
    }
    mod ops {
        pub const NOP: u8 = 0;

        pub const ONE: u8 = 1;
        pub const HEIGHT: u8 = 2;
        pub const POP: u8 = 3;
        pub const SWAP: u8 = 4;

        pub const NEW: u8 = 5;
        pub const PUSH: u8 = 6;
        pub const NEGATE: u8 = 7;
        pub const DROP: u8 = 8;

        pub const SAVE: u8 = 9;
        pub const ZRET: u8 = 10;

        pub const READ: u8 = 11;
        pub const WRITE: u8 = 12;
    }
    use ops::*;
    use std::io;
    use std::io::ErrorKind;
    use std::io::{Read, Write};
    use std::mem;
    impl Program {
        fn backtrack(code: &mut Vec<u8>, f: &Func) {
            code.truncate(f.addr);
        }
        pub fn run(&self, input: Vec<i64>, stdin: impl Read, stdout: impl Write) -> Vec<i64> {
            let mut active = input;
            let mut passive: Vec<i64> = Vec::new();
            let mut data: Vec<i64> = Vec::new();
            let mut rets: Vec<u32> = Vec::new();
            let mut exec: u32 = 0;
            let mut stdin = Some(stdin);
            let mut stdout = Some(stdout);
            let clen = self.code.len() as u32;
            while exec < clen {
                let c = self.code[exec as usize];
                match c {
                    SAVE | ZRET => match c {
                        SAVE => {
                            rets.push(exec + 5);
                            data.push(0);
                            exec = u32::from_le_bytes(
                                self.code[((exec + 1) as usize)..((exec + 5) as usize)]
                                    .try_into()
                                    .unwrap(),
                            );
                        }
                        ZRET => {
                            if active.last().map(|v| *v).unwrap_or(0) != 0 {
                                exec = *rets.last().unwrap();
                            } else {
                                let v = data.pop().unwrap();
                                data.last_mut().map(|pc| *pc += v);
                                rets.pop().unwrap();
                                exec += 1;
                            };
                        }
                        _ => unreachable!(),
                    },
                    NEW => {
                        data.push(0);
                        exec += 1;
                    }
                    NOP | ONE | HEIGHT | POP | SWAP | READ => {
                        let v = match c {
                            NOP => 0,
                            ONE => 1,
                            HEIGHT => active.len() as i64,
                            POP => active.pop().unwrap_or(0),
                            SWAP => {
                                mem::swap(&mut active, &mut passive);
                                0
                            }
                            READ => {
                                let mut buffer = [0; 1];
                                match stdin.as_mut() {
                                    Some(stdin) => match stdin.read_exact(&mut buffer) {
                                        Ok(_) => buffer[0] as i64,
                                        Err(e) => match e.kind() {
                                            ErrorKind::UnexpectedEof => -1,
                                            _ => -2,
                                        },
                                    },
                                    None => -2,
                                }
                            }
                            _ => unreachable!(),
                        };
                        data.last_mut().map(|pc| *pc += v);
                        exec += 1;
                    }
                    PUSH | NEGATE | DROP | WRITE => {
                        let mut v = data.pop().unwrap();
                        match c {
                            PUSH => active.push(v),
                            NEGATE => v = -v,
                            DROP => v = 0,
                            WRITE => {
                                v = match v {
                                    v if v >= 0 => match stdout.as_mut() {
                                        Some(stdout) => match stdout.write_all(&[v as u8]) {
                                            Ok(_) => 0,
                                            Err(_) => 1,
                                        },
                                        None => 1,
                                    },
                                    -1 => stdin.take().map_or(1, |_| 0),
                                    -2 => stdout.take().map_or(1, |_| 0),
                                    _ => 1,
                                }
                            }
                            _ => unreachable!(),
                        }
                        data.last_mut().map(|pv| *pv += v);
                        exec += 1;
                    }
                    _ => panic!(),
                }
            }
            active
        }
        pub fn new(file: impl Read) -> io::Result<Self> {
            let mut funcs: Vec<Func> = Vec::new();
            let mut code: Vec<u8> = Vec::new();
            for b in file.bytes().filter_map(|c| match c {
                Ok(c) => Bracket::try_from(c).ok().map(|c| Ok(c)),
                Err(e) => Some(Err(e)),
            }) {
                let b = b?;
                match b.side {
                    Opening => {
                        funcs.last_mut().map(|f| {
                            if f.monad {
                                return;
                            }
                            f.monad = true;
                            if f.btype == Curly {
                                code.extend([0; 4]);
                            }
                        });
                        funcs.push(Func {
                            btype: b.btype,
                            monad: false,
                            addr: code.len(),
                        });
                        code.push(0);
                    }
                    Closing => 'm: {
                        let f = if let Some(f) = funcs.pop() {
                            f
                        } else {
                            break 'm;
                        };
                        'e: {
                            match f.monad {
                                false => {
                                    code[f.addr] = match (f.btype, b.btype) {
                                        (Round, Round) => ONE,
                                        (Square, Square) => HEIGHT,
                                        (Curly, Curly) => POP,
                                        (Angle, Angle) => SWAP,
                                        (Angle, Round) => READ,
                                        _ => break 'e Err(()),
                                    }
                                }
                                true => {
                                    if let (Curly, Curly) = (f.btype, b.btype) {
                                        code[f.addr] = SAVE;
                                        let addr = &(code.len() as u32).to_le_bytes();
                                        code[(f.addr + 1)..(f.addr + 5)].copy_from_slice(addr);
                                        code.push(ZRET);
                                    } else {
                                        code[f.addr] = NEW;
                                        code.push(match (f.btype, b.btype) {
                                            (Round, Round) => PUSH,
                                            (Square, Square) => NEGATE,
                                            (Angle, Angle) => DROP,
                                            (Angle, Round) => WRITE,
                                            _ => break 'e Err(()),
                                        });
                                    }
                                }
                            }
                            Ok(())
                        }
                        .err()
                        .map(|_| Self::backtrack(&mut code, &f));
                    }
                }
                if code.len() > (u32::MAX as usize) {
                    panic!("Program too large");
                }
            }
            funcs.first().map(|f| Self::backtrack(&mut code, &f));
            code.shrink_to_fit();
            Ok(Self {
                code: code.into_boxed_slice(),
            })
        }
    }
}

pub use brainflak::*;
use std::env;
use std::fs::File;
use std::io;
use std::str::FromStr;

fn main() {
    let mut args = env::args();
    args.next();
    let pfile = File::open(args.next().expect("invalid argument")).expect("failed to open file");
    let mut inputs = Vec::new();
    for p in args {
        inputs.push(i64::from_str(&p).expect("invalid argument"));
    }
    let program = Program::new(pfile).expect("fail");
    for i in program.run(inputs, io::stdin(), io::stdout()) {
        println!("{}", i);
    }
}