package ocr import ( "bufio" "bytes" "fmt" "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 splitByDigit(line string) []string { ret := make([]string, len(line)/3) for i := range ret { ret[i] = line[i*3 : i*3+3] } return ret } func toString(r [][]int) string { buf := new(bytes.Buffer) for _, v := range r { if len(v) == 1 { fmt.Fprint(buf, v[0]) } else { fmt.Fprint(buf, "?") } } return buf.String() } func intersection(a, b []int) []int { isInSet := 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 isInSet(b, v) { r = append(r, v) } } return r } func recognizeDigit(s []string, set [][]int, k int) [][]int { if set == nil { set = make([][]int, len(s)) for i := range set { set[i] = []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} } } ret := make([][]int, len(s)) for i, v := range s { if r, ok := rules[k][v]; ok { ret[i] = intersection(set[i], r) } } return ret } func Recognize(s string) []string { scan := bufio.NewScanner(strings.NewReader(s)) var set [][]int var ret []string for i := 0; scan.Scan(); { if t := scan.Text(); len(t) > 0 { set = recognizeDigit(splitByDigit(t), set, i) if i++; i == len(rules) { str := toString(set) ret = append(ret, str) set = nil i = 0 } } } return ret }