-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path16_exec_loop.go
81 lines (65 loc) · 1.48 KB
/
16_exec_loop.go
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
package main
import (
"fmt"
"metalim/advent/2017/lib/source"
"strings"
. "github.com/logrusorgru/aurora"
)
func main() {
var ins source.Inputs
ins = ins.Test(3, `s1,x3/4,pe/b`, `baedc`, `ceadb`)
for par := range ins.Advent(2017, 16) {
fmt.Println(Brown("\n" + par.Name))
spar := par.Split(",")
sw := spar.Values
ssn := spar.Ints()
fmt.Println(len(sw), Black(sw[:3]).Bold(), Black(ssn[:3]).Bold())
p := program{sw, ssn}
init := "abcdefghijklmnop"
part2Count := int(1e9)
if strings.Contains(par.Name, "test") {
init = init[:5]
part2Count = 2
}
if par.Part(1) {
par.Submit(1, p.exec(init))
}
if par.Part(2) {
reg := init
seen := map[string]int{}
for i := 1; i <= part2Count; i++ {
reg = p.exec(reg)
if step, ok := seen[reg]; ok { // found a loop? -> warp to same instance before target.
i = part2Count - (part2Count-step)%(i-step)
seen = map[string]int{} // reset map
}
seen[reg] = i
}
par.Submit(2, string(reg))
}
}
}
type program struct {
code []string
args [][]int
}
func (p *program) exec(sreg string) string {
mod := len(sreg)
reg := []byte(sreg)
for ip, c := range p.code {
a := p.args[ip]
switch c[0] {
case 's':
x := a[0] % mod
reg = append(reg[mod-x:], reg[:mod-x]...)
case 'x':
reg[a[0]], reg[a[1]] = reg[a[1]], reg[a[0]]
case 'p':
s := string(reg)
i := strings.IndexByte(s, c[1])
j := strings.IndexByte(s, c[3])
reg[i], reg[j] = reg[j], reg[i]
}
}
return string(reg)
}