add day7
This commit is contained in:
111
day7/combine_with_concat.go
Normal file
111
day7/combine_with_concat.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"fmt"
|
||||
"strings"
|
||||
"strconv"
|
||||
"math"
|
||||
)
|
||||
|
||||
// data types
|
||||
type Equation struct {
|
||||
result int
|
||||
params []int
|
||||
}
|
||||
|
||||
// general util
|
||||
func check(e error) {
|
||||
if e != nil { panic(e) }
|
||||
}
|
||||
|
||||
func newEquations(data string) []*Equation {
|
||||
/* Reads the puzzle input, return a list of Equation structs.
|
||||
*/
|
||||
lines := strings.Split(data, "\n")
|
||||
equations := make([]*Equation, 0, len(lines))
|
||||
|
||||
for _, line := range lines {
|
||||
split_line := strings.Split(line, ":")
|
||||
|
||||
// get result/ number before the colon
|
||||
result, err := strconv.Atoi(split_line[0])
|
||||
check(err)
|
||||
|
||||
// parse paramter/ numbers after the colon
|
||||
str_params := strings.Split(strings.TrimSpace(split_line[1]), " ")
|
||||
params := make([]int, 0, len(str_params))
|
||||
for _, num := range str_params {
|
||||
param, err := strconv.Atoi(num)
|
||||
check(err)
|
||||
|
||||
params = append(params, param)
|
||||
}
|
||||
|
||||
equations = append(equations, &Equation{ result: result, params: params })
|
||||
}
|
||||
|
||||
return equations
|
||||
}
|
||||
|
||||
func incr(arr []int) []int {
|
||||
/* least significant bit first increment, base 3 */
|
||||
over := 1
|
||||
for i := range arr {
|
||||
if over == 0 { break }
|
||||
arr[i] += over
|
||||
over = arr[i] / 3
|
||||
arr[i] = arr[i] % 3
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
func isValid(eq *Equation) bool {
|
||||
/* Checks whether the equation could be right by combining the paramters in
|
||||
* all possible ways and comparing to the result.
|
||||
*/
|
||||
|
||||
operators := make([]int, len(eq.params) - 1)
|
||||
|
||||
for range int(math.Pow(3.0, float64(len(operators)))) {
|
||||
|
||||
// calc possible result
|
||||
acc := eq.params[0]
|
||||
for i, op := range operators {
|
||||
if op == 0 {
|
||||
acc += eq.params[i + 1]
|
||||
} else if op == 1 {
|
||||
acc *= eq.params[i + 1]
|
||||
} else if op == 2 {
|
||||
num, err := strconv.Atoi(strconv.Itoa(acc) + strconv.Itoa(eq.params[i + 1]))
|
||||
check(err)
|
||||
acc = num
|
||||
}
|
||||
}
|
||||
|
||||
// compare to actual result
|
||||
if acc == eq.result { return true }
|
||||
|
||||
operators = incr(operators)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// main loop
|
||||
func main() {
|
||||
|
||||
// read in file
|
||||
dat, err := os.ReadFile("data.txt")
|
||||
check(err)
|
||||
dat_str := strings.TrimSpace(string(dat))
|
||||
|
||||
|
||||
equations := newEquations(dat_str)
|
||||
|
||||
result := 0
|
||||
for _, eq := range equations {
|
||||
if isValid(eq) { result += eq.result }
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
}
|
||||
Reference in New Issue
Block a user