-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmain.go
121 lines (104 loc) · 1.93 KB
/
main.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
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
package main
import (
"bufio"
"io"
lib "github.com/teivah/advent-of-code"
)
func fs1(input io.Reader, startState string, steps int) int {
scanner := bufio.NewScanner(input)
states := make(map[string]State)
for scanner.Scan() {
// Empty line
scanner.Text()
id, state := toState(scanner)
states[id] = state
}
checksum := []int{0}
offset := 0
id := startState
for i := 0; i < steps; i++ {
right := false
state := states[id]
if checksum[offset] == 0 {
checksum[offset] = state.zero.write
if state.zero.moveRight {
right = true
}
id = state.zero.nextState
} else {
checksum[offset] = state.one.write
if state.one.moveRight {
right = true
}
id = state.one.nextState
}
if right {
offset++
if offset == len(checksum) {
checksum = append(checksum, 0)
}
} else {
offset--
if offset == -1 {
offset = 0
checksum = append([]int{0}, checksum...)
}
}
}
ones := 0
for _, v := range checksum {
if v == 1 {
ones++
}
}
return ones
}
type State struct {
zero Cmd
one Cmd
}
type Cmd struct {
write int
moveRight bool
nextState string
}
func toCmd(scanner *bufio.Scanner) Cmd {
// Write
scanner.Scan()
s := scanner.Text()
del := lib.NewDelimiter(s, " ")
tmp := del.GetString(8)
write := lib.StringToInt(tmp[:len(tmp)-1])
// Move
scanner.Scan()
s = scanner.Text()
right := false
if s[27] == 'r' {
right = true
}
// Continue
scanner.Scan()
s = scanner.Text()
next := string(s[26])
return Cmd{
write: write,
moveRight: right,
nextState: next,
}
}
func toState(scanner *bufio.Scanner) (string, State) {
scanner.Scan()
s := scanner.Text()
del := lib.NewDelimiter(s, " ")
tmp := del.GetString(2)
state := tmp[:len(tmp)-1]
// If the current value is 0
scanner.Scan()
s = scanner.Text()
zero := toCmd(scanner)
// If the current value is 1
scanner.Scan()
s = scanner.Text()
one := toCmd(scanner)
return state, State{zero, one}
}