advent_of_code/2023/01/main.go

123 lines
2.5 KiB
Go
Raw Normal View History

2023-12-01 21:11:54 +00:00
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()
}