summaryrefslogtreecommitdiff
path: root/go/ocr-numbers/ocr_numbers.go
diff options
context:
space:
mode:
Diffstat (limited to 'go/ocr-numbers/ocr_numbers.go')
-rw-r--r--go/ocr-numbers/ocr_numbers.go113
1 files changed, 113 insertions, 0 deletions
diff --git a/go/ocr-numbers/ocr_numbers.go b/go/ocr-numbers/ocr_numbers.go
new file mode 100644
index 0000000..fb9c502
--- /dev/null
+++ b/go/ocr-numbers/ocr_numbers.go
@@ -0,0 +1,113 @@
+package ocr
+
+import (
+ "regexp"
+ "strings"
+)
+
+/*
+ _ _ _ _ _ _ _ _
+| | | _| _||_||_ |_ ||_||_|
+|_| ||_ _| | _||_| ||_| _|
+
+*/
+
+var rules = []map[string][]int{
+ { // 1. line
+ " _ ": []int{0, 2, 3, 5, 6, 7, 8, 9},
+ " ": []int{1, 4},
+ },
+ { // 2. line
+ "| |": []int{0},
+ " |": []int{1, 7},
+ " _|": []int{2, 3},
+ "|_ ": []int{5, 6},
+ "|_|": []int{4, 8, 9},
+ },
+ { // 3. line
+ "|_|": []int{0, 6, 8},
+ " |": []int{1, 4, 7},
+ "|_ ": []int{2},
+ " _|": []int{3, 5, 9},
+ },
+ { // 4. line
+ " ": []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
+ },
+}
+
+func splitByLine(s string) [][]string {
+ l := strings.Split(s, "\n")
+ var ret [][]string
+ for _, v := range l {
+ if len(v) > 0 {
+ ret = append(ret, splitLineByGroup(v))
+ }
+ }
+ return ret
+}
+
+func splitLineByGroup(line string) []string {
+ l := len(line) / 3
+ ret := make([]string, l)
+ for i := 0; i < l; i++ {
+ ret[i] = line[i*3 : i*3+3]
+ }
+ return ret
+}
+
+func Recognize(s string) []string {
+ re, _ := regexp.Compile("\n *\n")
+ s = re.ReplaceAllString(s, "\n\n")
+ groups := strings.Split(s, "\n\n")
+ var ret []string
+ for _, v := range groups {
+ ret = append(ret, recognizeDigit(v))
+ }
+ return ret
+}
+
+func recognizeDigit(s string) string {
+ if len(s) == 0 {
+ return "?"
+ }
+ l := splitByLine(s)
+ if len(l) == 0 {
+ return "?"
+ }
+ o := make([][]int, len(l[0]))
+ for i := range o {
+ o[i] = []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
+ }
+ for i, v := range l {
+ for j, z := range v {
+ o[j] = intersect(o[j], rules[i%len(rules)][z])
+ }
+ }
+ var ret []rune
+ for _, v := range o {
+ if len(v) > 0 {
+ ret = append(ret, rune('0'+v[0]))
+ } else {
+ ret = append(ret, '?')
+ }
+ }
+ return string(ret)
+}
+
+func intersect(a, b []int) []int {
+ has := func(x []int, a int) bool {
+ for _, v := range x {
+ if v == a {
+ return true
+ }
+ }
+ return false
+ }
+ var r []int
+ for _, v := range a {
+ if has(b, v) {
+ r = append(r, v)
+ }
+ }
+ return r
+}