package main import ( "fmt" "log" "math" "math/rand" "time" ) type testCase struct { function func(Element, Element) Element expect func(int, int) int maxm, maxn int order bool } func init() { rand.Seed(time.Now().Unix()) } var cases = map[string]testCase{ "+": testCase{ function: Add, expect: testAdd, maxm: 100, maxn: 100, order: false, }, "*": testCase{ function: Mul, expect: testMul, maxm: 10, maxn: 10, order: false, }, "^": testCase{ function: Pot, expect: testPot, maxm: 10, maxn: 3, order: false, }, "-": testCase{ function: Sub, expect: testSub, maxm: 100, maxn: 100, order: true, }, } func verify(op string) (string, bool) { c, ok := cases[op] if !ok { log.Fatal("unknown case") } m := rand.Intn(c.maxm) n := rand.Intn(c.maxn) if c.order && n > m { m, n = n, m } e := c.expect(m, n) me := scan(m) ne := scan(n) ee := scan(e) re := c.function(me, ne) return fmt.Sprint(me, op, ne, "=", re), re.equals(ee) } func scan(n int) Element { if n > alphabet.Len() { log.Fatal("out of range ", n) return Element{} } e := alphabet.Front() for i := 0; i < n; i++ { e = e.Next() } return Element{e} } func testAdd(m, n int) int { return m + n } func testMul(m, n int) int { return m * n } func testPot(m, n int) int { return int(math.Pow(float64(m), float64(n))) } func testSub(m, n int) int { return m - n } func verifyAll() { for op := range cases { fmt.Println(verify(op)) } } // String pretty-prints value func (m Element) String() string { return fmt.Sprint(m.Value) } func (m Element) equals(n Element) bool { return m.Value == n.Value }