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 }