123 lines
2.5 KiB
Go
123 lines
2.5 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"strings"
|
||
|
"unicode"
|
||
|
|
||
|
"github.com/fatih/color"
|
||
|
"github.com/thoas/go-funk"
|
||
|
)
|
||
|
|
||
|
var numberstrings = [9]string{"one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}
|
||
|
|
||
|
func readFileLines(filename string) ([]string, error) {
|
||
|
var lines []string
|
||
|
|
||
|
file, err := os.Open(filename)
|
||
|
if err != nil {
|
||
|
return lines, err
|
||
|
}
|
||
|
fileScanner := bufio.NewScanner(file)
|
||
|
fileScanner.Split(bufio.ScanLines)
|
||
|
|
||
|
for fileScanner.Scan() {
|
||
|
lines = append(lines, fileScanner.Text())
|
||
|
}
|
||
|
|
||
|
return lines, nil
|
||
|
}
|
||
|
|
||
|
func getNumbersFromLines(lines []string) []int {
|
||
|
var result []int
|
||
|
for _, line := range lines {
|
||
|
firstnum := -1
|
||
|
lastnum := -1
|
||
|
for _, char := range line {
|
||
|
if unicode.IsDigit(rune(char)) {
|
||
|
if firstnum == -1 {
|
||
|
firstnum = int(char) - int('0')
|
||
|
} else {
|
||
|
lastnum = int(char) - int('0')
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if lastnum == -1 {
|
||
|
lastnum = firstnum
|
||
|
}
|
||
|
result = append(result, firstnum*10+lastnum)
|
||
|
}
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
func getNumbersFromLinesPart2(lines []string) []int {
|
||
|
var result []int
|
||
|
for _, line := range lines {
|
||
|
firstnum := -1
|
||
|
lastnum := -1
|
||
|
firstnumIndex := len(line)
|
||
|
lastnumIndex := 0
|
||
|
for idx, char := range line {
|
||
|
if unicode.IsDigit(rune(char)) {
|
||
|
if firstnum == -1 {
|
||
|
firstnum = int(char) - int('0')
|
||
|
firstnumIndex = idx
|
||
|
} else {
|
||
|
lastnum = int(char) - int('0')
|
||
|
lastnumIndex = idx
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if lastnum == -1 {
|
||
|
lastnum = firstnum
|
||
|
lastnumIndex = firstnumIndex
|
||
|
}
|
||
|
for idx, num := range numberstrings {
|
||
|
stridx := strings.Index(line, num)
|
||
|
if stridx != -1 && stridx < firstnumIndex {
|
||
|
firstnum = idx + 1
|
||
|
firstnumIndex = stridx
|
||
|
}
|
||
|
stridx = strings.LastIndex(line, num)
|
||
|
if stridx > lastnumIndex {
|
||
|
lastnum = idx + 1
|
||
|
lastnumIndex = stridx
|
||
|
}
|
||
|
}
|
||
|
if lastnum == -1 {
|
||
|
lastnum = firstnum
|
||
|
}
|
||
|
result = append(result, firstnum*10+lastnum)
|
||
|
}
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
redPrint := color.New(color.FgRed)
|
||
|
yellowPrint := color.New(color.FgYellow)
|
||
|
if len(os.Args) < 2 {
|
||
|
redPrint.Fprintln(os.Stderr, "You must provide the input file")
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
lines, err := readFileLines(os.Args[1])
|
||
|
if err != nil {
|
||
|
redPrint.Fprintln(os.Stderr, "Could not read input file")
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
numbers := getNumbersFromLines(lines)
|
||
|
sum := funk.Reduce(numbers, '+', 0)
|
||
|
|
||
|
fmt.Print("Part 1: ")
|
||
|
yellowPrint.Print(sum)
|
||
|
fmt.Println()
|
||
|
|
||
|
numbers2 := getNumbersFromLinesPart2(lines)
|
||
|
sum2 := funk.Reduce(numbers2, '+', 0)
|
||
|
|
||
|
fmt.Print("Part 2: ")
|
||
|
yellowPrint.Print(sum2)
|
||
|
fmt.Println()
|
||
|
}
|