1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- package main
- import (
- "bufio"
- "errors"
- "fmt"
- "io"
- "log"
- "os"
- "strconv"
- "strings"
- )
- func trim(s string) string {
- if len(s) > 0 && s[len(s)-1] == '\n' {
- return s[:len(s)-1]
- }
- return s
- }
- func main() {
- r := bufio.NewReader(os.Stdin)
- calibration := 0
- for {
- line, err := r.ReadString('\n')
- if errors.Is(err, io.EOF) {
- break
- }
- if err != nil {
- log.Fatalf("While reading input: %v", err)
- }
- line = trim(line)
- parts := strings.SplitN(line, ":", 2)
- test64, err := strconv.ParseInt(parts[0], 10, 32)
- if err != nil {
- log.Fatalf("Unable to parse test value %#v: %v", parts[0], err)
- }
- test := int(test64)
- fs := strings.Fields(parts[1])
- operands := make([]int, 0, 8)
- for _, f := range fs {
- o, err := strconv.ParseInt(f, 10, 32)
- if err != nil {
- log.Fatalf("Unable to parse operand %#v: %v", f, err)
- }
- operands = append(operands, int(o))
- }
- if bruteForce(test, operands) {
- calibration += test
- }
- }
- fmt.Printf("%d\n", calibration)
- }
- func bruteForce(test int, vars []int) bool {
- if len(vars) > 64 {
- log.Fatalf("Maximum expected operands exceeded: %#v", vars)
- }
- var ops uint64
- for ops < uint64(len(vars)) {
- candidate := vars[0]
- for i := 0; i < len(vars)-1; i++ {
- switch (ops & (uint64(1) << i)) >> i {
- case 0:
- candidate += vars[i+1]
- case 1:
- candidate *= vars[i+1]
- default:
- log.Fatal("BUG: unexpected bit value: neither 0 nor 1!")
- }
- if candidate > test {
- break
- }
- }
- if candidate == test {
- return true
- }
- ops++
- }
- return false
- }
|