-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwalk.go
98 lines (91 loc) · 2.07 KB
/
walk.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
package levenshtein
// Walk is the older method to iterate the edit distance matrix. It doesn't have any way to stop the iteration. Using this for diff is broken, use Diff instead.
func Walk[T Number](mat []T, width uint, to func(uint, uint)) {
WalkVals(mat, width, func(prev T, this T, x uint, y uint) bool {
to(x, y)
return false
})
}
// WalkVals iterates the edit distance matrix. Use true to stop the iteration. Using this for diff is broken, use Diff instead.
func WalkVals[T Number](mat []T, width uint, to func(prev T, this T, x uint, y uint) bool) {
pos := uint(len(mat) - 1)
x := (pos % width)
y := (pos / width)
for x > 0 && y > 0 {
here := x + width*y
diag := x - 1 + width*(y-1)
up := x + width*(y-1)
left := x - 1 + width*(y)
if diag >= 0 {
if mat[left] == mat[up] && mat[diag] == mat[left] {
if x == y {
if to(mat[here], mat[diag], x, y) {
return
}
x--
y--
continue
}
if x > y {
if to(mat[here], mat[left], x, y) {
return
}
x--
continue
}
if x < y {
if to(mat[here], mat[up], x, y) {
return
}
y--
continue
}
}
if mat[diag] < mat[left] && mat[diag] < mat[up] {
if to(mat[here], mat[diag], x, y) {
return
}
x--
y--
continue
}
if mat[up] < mat[left] {
if to(mat[here], mat[up], x, y) {
return
}
y--
continue
}
if mat[up] > mat[left] {
if to(mat[here], mat[left], x, y) {
return
}
x--
continue
}
}
if left >= 0 {
if to(mat[here], mat[left], x, y) {
return
}
x--
continue
}
if up >= 0 {
if to(mat[here], mat[up], x, y) {
return
}
y--
continue
}
}
}
// WalkVals iterates the edit distance matrix in reverse. Use false to stop the iteration. Using this for diff is broken, use Diff instead.
func WalkValsR[T Number](mat []T, width uint, cb func(prev, this T, x, y uint) bool) {
height := uint(len(mat)) / width
WalkVals(mat, width, func(prev, this T, x, y uint) bool {
x = width - x
y = height - y
return !cb(prev, this, x, y)
})
}