package main import ( "fmt" "regexp" "strconv" ) var replaceMap = map[string]string{ "one": "1", "two": "2", "three": "3", "four": "4", "five": "5", "six": "6", "seven": "7", "eight": "8", "nine": "9", } var r = regexp.MustCompile(`\d|one|two|three|four|five|six|seven|eight|nine`) var rr = regexp.MustCompile(`\d|eno|owt|eerht|ruof|evif|xis|neves|thgie|enin`) // forward parses a single line from start to last // Match all substrings matching `\d|one|two|three|four|five|six|seven|eight|nine` // Returns the first match func forward(s string) string { m_all := r.FindAllString(s, -1) match := m_all[0] match, ok := replaceMap[match] if !ok { match = m_all[0] } return match } // backward parses a single line in reverse order // Match all substrings matching `\d|eno|owt|eerht|ruof|evif|xis|neves|thgie|enin` // Returns the first match func backward(s string) string { m_all := rr.FindAllString(s, -1) match := m_all[0] match, ok := replaceMap[reverse(match)] if !ok { match = m_all[0] } return match } // two takes a string array and for each line: // Search by regex all substrings matching numeric (and word representations of numeric) values. // It then combines the first digit and the last digit (in that order) to form a single two-digit number. // Returns the sum of all calibrated values. func two(lines []string) (int, error) { sum := 0 for _, line := range lines { m1 := forward(line) m2 := backward(reverse(line)) n, err := strconv.Atoi(fmt.Sprintf("%s%s", m1, m2)) if err != nil { return 0, err } sum += n } return sum, nil }