153 lines
2.7 KiB
Go
153 lines
2.7 KiB
Go
|
|
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
|
||
|
|
}
|