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 { // bogus part: sanitize input, split by groups 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) == 1 { 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 }