aoc2023/day01/day01.go

75 lines
1.5 KiB
Go

package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
const digits = "0123456789"
func words() [10]string {
return [10]string{"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}
}
func firstDigit(input string) string {
var result string
loc := len(input)
if index := strings.IndexAny(input, "0123456789"); index != -1 {
loc = index
result = string([]rune(input)[index])
}
for key, value := range words() {
if index := strings.Index(input, value); index != -1 && index <= loc {
loc = index
result = strconv.Itoa(key)
}
}
return result
}
func lastDigit(input string) string {
var result string
loc := -1
if index := strings.LastIndexAny(input, "0123456789"); index != -1 {
loc = index
result = string([]rune(input)[index])
}
for key, value := range words() {
if index := strings.LastIndex(input, value); index != -1 && index >= loc {
loc = index
result = strconv.Itoa(key)
}
}
return result
}
func calibration(input string) int {
first := firstDigit(input)
last := lastDigit(input)
output, _ := strconv.Atoi(first + last)
return output
}
func ScanFile(file *os.File) (int, error) {
scanner := bufio.NewScanner(file)
sum := 0
for scanner.Scan() {
sum += calibration(scanner.Text())
}
if err := scanner.Err(); err != nil {
return 0, err
}
return sum, nil
}
func main() {
sum, err := ScanFile(os.Stdin)
if err != nil {
fmt.Fprintf(os.Stderr, "Invalid input: %s\n", err)
return
}
fmt.Println(sum)
}