-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path16.coffee
63 lines (58 loc) · 1.46 KB
/
16.coffee
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
{_log,_print,test,expect,testAndRun} = require './util'
ansi = require('ansicolor').nice
class Solver
constructor: ( @input )->
@prog = for l in @input.split ','
k = l[0]
[a,b]=l[1..].split '/'
a = +a unless isNaN +a
b = +b unless isNaN +b
[k,a,b]
#_log @input, @prog
return
solve: (rep = 1, len = 16)->
#_log len, rep
s = 'abcdefghijklmnop'[...len].split ''
step = 0
visited = {}
visited[s.join ''] = step
while ++step<=rep
_log.clear.darkGray step, s.join '' unless step%1000
for l in @prog
switch l[0]
when 's'
s = s[-l[1]..].concat s[...-l[1]]
when 'x'
[s[l[1]],s[l[2]]] = [s[l[2]],s[l[1]]]
when 'p'
a = s.indexOf l[1]
b = s.indexOf l[2]
[s[a],s[b]] = [s[b],s[a]]
else
_log.red 'invalid instruction', l
ss = s.join ''
if visited[ss]?
_log.clear ''
_log.darkGray 'repeated', ss.green, 'at', step, visited[ss]
d = step - visited[ss]
step = rep - (rep-step)%d
visited = {}
_log.darkGray 'skip to', step
else
visited[ss] = step
_log.clear ''
s.join ''
test.solve1 = ->
s = new Solver 's1,x3/4,pe/b'
expect 'baedc', s.solve 1, 5
return
test.solve2 = ->
s = new Solver 's1,x3/4,pe/b'
expect 'ceadb', s.solve 2, 5
return
testAndRun ->
s = new Solver require './input/16.txt'
_log.yellow '1:', s.solve()
_log.yellow '2:', s.solve 1000000000
_log.yellow 'verify:', s.solve 10
return