Skip to content

Commit e08472a

Browse files
committed
2017.25 extract tape to common turing.Tape.
1 parent d475afc commit e08472a

File tree

2 files changed

+82
-70
lines changed

2 files changed

+82
-70
lines changed

25_turing_machine.go

+19-70
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"fmt"
55
"metalim/advent/2017/lib/source"
6+
"metalim/advent/2017/lib/turing"
67
"strconv"
78

89
. "github.com/logrusorgru/aurora"
@@ -49,35 +50,39 @@ func main() {
4950
for len(ssw) > 0 {
5051
ins := ssw[1][len(ssw[1])-1]
5152

53+
// assuming ssw[2] is 0.
5254
v1, _ := strconv.Atoi(ssw[3][len(ssw[3])-1])
5355
l1 := ssw[4][len(ssw[4])-1] == "left"
54-
st1 := ssw[5][len(ssw[5])-1]
56+
s1 := ssw[5][len(ssw[5])-1]
5557

58+
// assuming ssw[6] is 1.
5659
v2, _ := strconv.Atoi(ssw[7][len(ssw[7])-1])
5760
l2 := ssw[8][len(ssw[8])-1] == "left"
58-
st2 := ssw[9][len(ssw[9])-1]
61+
s2 := ssw[9][len(ssw[9])-1]
5962

60-
rules[ins] = [2]cmd{{v1, l1, st1}, {v2, l2, st2}}
63+
rules[ins] = [2]cmd{{v1, l1, s1}, {v2, l2, s2}}
6164
ssw = ssw[10:]
6265
}
6366

64-
tape := tape{}
67+
t := turing.Tape{}
6568

69+
// execute.
6670
for ; n > 0; n-- {
67-
c := rules[state][tape.get()]
68-
tape.set(c.v)
71+
c := rules[state][t.Get()]
72+
t.Set(c.v)
6973
if c.l {
70-
tape.left()
74+
t.Left()
7175
} else {
72-
tape.right()
76+
t.Right()
7377
}
74-
state = c.st
78+
state = c.s
7579
}
7680

81+
// count checksum.
7782
var sum int
78-
l, r := tape.bounds()
83+
l, r := t.Bounds()
7984
for ; l <= r; l++ {
80-
if tape.getAt(l) == 1 {
85+
if t.GetAt(l) == 1 {
8186
sum++
8287
}
8388
}
@@ -92,63 +97,7 @@ func main() {
9297
////////////////////////////////////////////////////////////////////////
9398

9499
type cmd struct {
95-
v int
96-
l bool
97-
st string
98-
}
99-
100-
////////////////////////////////////////////////////////////////////////
101-
102-
type tape struct {
103-
d [2][]int
104-
p int
105-
}
106-
107-
func (t *tape) sel(p int) (int, int) {
108-
if p < 0 {
109-
return 1, -p - 1
110-
}
111-
return 0, p
112-
}
113-
114-
// getAt - for iteration.
115-
func (t *tape) getAt(pos int) int {
116-
i, p := t.sel(pos)
117-
if p < len(t.d[i]) {
118-
return t.d[i][p]
119-
}
120-
return 0
121-
}
122-
123-
func (t *tape) get() int {
124-
return t.getAt(t.p)
125-
}
126-
127-
func (t *tape) set(v int) {
128-
i, p := t.sel(t.p)
129-
if p >= len(t.d[i]) {
130-
t.d[i] = append(t.d[i], make([]int, p+1-len(t.d[i]))...) // extra space
131-
}
132-
t.d[i][p] = v
133-
}
134-
135-
func (t *tape) left() {
136-
t.p--
137-
}
138-
139-
func (t *tape) right() {
140-
t.p++
141-
}
142-
143-
func (t *tape) go2(p int) {
144-
t.p = p
145-
}
146-
147-
func (t *tape) goRight(d int) {
148-
t.p += d
149-
}
150-
151-
// bounds inclusive
152-
func (t *tape) bounds() (int, int) {
153-
return -len(t.d[1]), len(t.d[0]) - 1
100+
v int
101+
l bool
102+
s string
154103
}

lib/turing/tape.go

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package turing
2+
3+
// Tape for turing machine.
4+
type Tape struct {
5+
d [2][]int
6+
p int
7+
}
8+
9+
// GetAt - for iteration.
10+
func (t *Tape) GetAt(pos int) int {
11+
i, p := t.sel(pos)
12+
if p < len(t.d[i]) {
13+
return t.d[i][p]
14+
}
15+
return 0
16+
}
17+
18+
// Get value at current position.
19+
func (t *Tape) Get() int {
20+
return t.GetAt(t.p)
21+
}
22+
23+
// Set value at current position.
24+
func (t *Tape) Set(v int) {
25+
i, p := t.sel(t.p)
26+
if p >= len(t.d[i]) {
27+
t.d[i] = append(t.d[i], make([]int, p+1-len(t.d[i]))...) // extra space
28+
}
29+
t.d[i][p] = v
30+
}
31+
32+
// Left 1 position.
33+
func (t *Tape) Left() {
34+
t.p--
35+
}
36+
37+
// Right 1 position.
38+
func (t *Tape) Right() {
39+
t.p++
40+
}
41+
42+
// Goto position.
43+
func (t *Tape) Goto(p int) {
44+
t.p = p
45+
}
46+
47+
// GoRight by distance.
48+
func (t *Tape) GoRight(d int) {
49+
t.p += d
50+
}
51+
52+
// Bounds inclusive
53+
func (t *Tape) Bounds() (int, int) {
54+
return -len(t.d[1]), len(t.d[0]) - 1
55+
}
56+
57+
// select slice and position.
58+
func (t *Tape) sel(p int) (int, int) {
59+
if p < 0 {
60+
return 1, -p - 1
61+
}
62+
return 0, p
63+
}

0 commit comments

Comments
 (0)