-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathhelpers.go
More file actions
155 lines (147 loc) · 3.1 KB
/
helpers.go
File metadata and controls
155 lines (147 loc) · 3.1 KB
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package permutation
import (
"log"
"reflect"
)
// Useable defines an interface that must exist if a type is usable
// as one that is testable
type Useable interface {
Equal(Useable) bool
}
func factorial(i int) int {
if i == 0 {
return 0
}
result := 1
for i > 0 {
result *= i
i--
}
return result
}
func checkSliceInt(e, j [][]int) {
for i, v := range j {
if !equalSliceInt(e[i], v) {
log.Fatal("array:", e[i], "!=", v)
}
}
}
func equalSliceInt(a, b []int) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
func equalSliceString(a, b []string) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
func equalSliceGen(a, b interface{}, piv int) bool {
switch b.(type) {
case []int:
refArr := a.([][]int)
resArr := b.([]int)
if !equalSliceInt(refArr[piv], resArr) {
log.Fatal("array:", refArr[piv], "!=", resArr)
}
case []string:
refArr := a.([][]string)
resArr := b.([]string)
if !equalSliceString(refArr[piv], resArr) {
log.Fatal(piv, "String array:", refArr[piv], "!=", resArr)
}
case []Useable:
refArr := a.([][]Useable)
resArr := b.([]Useable)
for i, w := range resArr {
if !refArr[piv][i].Equal(w) {
log.Fatal(i, "element failed at ", piv)
}
}
default:
log.Fatalf("Unknown type %T, %t\n", a, a)
}
return true
}
// leng is the length of outer array
// sz if the size of inner element
func equalSliceSliceGen(a, b interface{}) (good bool, leng, sz int) {
switch b.(type) {
case [][]int:
refArr := a.([][]int)
resArr := b.([][]int)
leng = len(resArr)
sz = len(resArr[0])
for piv := range resArr {
if !equalSliceInt(refArr[piv], resArr[piv]) {
log.Fatal("array:", refArr[piv], "!=", resArr)
}
}
good = true
case [][]string:
refArr := a.([][]string)
resArr := b.([][]string)
leng = len(resArr)
sz = len(resArr[0])
for piv := range resArr {
if !equalSliceString(refArr[piv], resArr[piv]) {
log.Fatal(piv, "String array:", refArr[piv], "!=", resArr)
}
}
good = true
default:
_, ok := a.([][]Useable)
if ok {
refArr := a.([][]Useable)
resArr := b.([][]Useable)
leng = len(resArr)
sz = len(resArr[0])
for piv := range resArr {
for i, w := range resArr[piv] {
if !refArr[piv][i].Equal(w) {
log.Fatal(i, "element failed at ", piv)
}
}
}
good = true
} else {
val := reflect.ValueOf(b)
if val.Kind() == reflect.Slice {
leng = val.Len() // outer length
for i := 0; i < leng; i++ {
v := val.Index(i)
if v.Kind() == reflect.Slice {
sz = v.Len() // inner length
for j := 0; j < sz; j++ {
vv := v.Index(j)
// b implements Usable
if m, ok := vv.Interface().(Useable); ok {
n, ok := reflect.ValueOf(a).Index(i).Index(j).Interface().(Useable)
if !ok {
log.Fatal("a is not the same type as b")
}
good = m.Equal(n)
} else {
log.Fatal("Candidate cannot be converted to a Usable type")
}
}
}
}
}
}
}
//good = true
return
}