aoc2025/day6/main.go

153 lines
2.7 KiB
Go
Raw Permalink Normal View History

2025-12-07 00:10:20 -05:00
package main
import (
"fmt"
"os"
"regexp"
"strconv"
"strings"
)
func readLines(filename string) []string {
raw, err := os.ReadFile(filename)
if err != nil {
panic(err)
}
return strings.Split(string(raw), "\n")
}
func main() {
filename := "input0.txt"
if len(os.Args) > 1 {
filename = os.Args[1]
}
lines := readLines(filename)
hw, err := parseHomework(lines)
if err != nil {
panic(err)
}
fmt.Printf("%v\n", hw.do())
hw2, err := parseWeirdHomework(lines)
if err != nil {
panic(err)
}
fmt.Printf("%v\n", hw2.do())
}
type op uint8
const (
STAR op = iota
PLUS
)
type homework struct {
cols [][]uint64
ops []op
}
var spaces = regexp.MustCompile(" +")
func parseHomework(lines []string) (homework, error) {
var hw homework
var err error
for i := 0; i < len(lines)-1; i++ {
parts := spaces.Split(strings.TrimSpace(lines[i]), -1)
if i == 0 {
hw.ops = make([]op, len(parts))
hw.cols = make([][]uint64, len(parts))
for j := range hw.cols {
hw.cols[j] = make([]uint64, len(lines)-1)
}
}
for j, part := range parts {
hw.cols[j][i], err = strconv.ParseUint(part, 10, 64)
if err != nil {
return hw, err
}
}
}
parts := spaces.Split(strings.TrimSpace(lines[len(lines)-1]), -1)
for j, part := range parts {
var op op
switch part {
case "*":
op = STAR
case "+":
op = PLUS
default:
return hw, fmt.Errorf("invalid op")
}
hw.ops[j] = op
}
return hw, nil
}
func parseWeirdHomework(lines []string) (homework, error) {
var hw homework
hw.ops = []op{}
hw.cols = [][]uint64{}
c := 0
hw.cols = append(hw.cols, []uint64{})
for i := len(lines[0]) - 1; i >= 0; i-- {
value := uint64(0)
foundValue := false
for j := 0; j < len(lines)-1; j++ {
line := lines[j]
char := line[i]
switch char {
case ' ':
continue
default:
digit, err := strconv.ParseUint(string(char), 10, 4)
if err != nil {
return hw, err
}
foundValue = true
value = value*10 + digit
}
}
if foundValue {
hw.cols[c] = append(hw.cols[c], value)
} else {
c++
hw.cols = append(hw.cols, []uint64{})
}
}
parts := spaces.Split(strings.TrimSpace(lines[len(lines)-1]), -1)
for i := len(parts) - 1; i >= 0; i-- {
var op op
switch parts[i] {
case "*":
op = STAR
case "+":
op = PLUS
default:
return hw, fmt.Errorf("invalid op")
}
hw.ops = append(hw.ops, op)
}
return hw, nil
}
func (hw homework) do() uint64 {
total := uint64(0)
for i, col := range hw.cols {
op := hw.ops[i]
value := uint64(0)
switch op {
case PLUS:
for _, x := range col {
value += x
}
case STAR:
value = 1
for _, x := range col {
value *= x
}
}
total += value
}
return total
}