summaryrefslogtreecommitdiff
path: root/day7/main.go
diff options
context:
space:
mode:
authorSteven Le Rouzic <steven.lerouzic@gmail.com>2024-12-07 16:38:30 +0100
committerSteven Le Rouzic <steven.lerouzic@gmail.com>2024-12-07 16:38:30 +0100
commit0de2729b5382097c76d6a25522c26719e196dae7 (patch)
tree79b0085a4613dfd87f337e6a463f20ff27f9c722 /day7/main.go
parentf1ab08b2a892ca1dda6a46ae9ef03b0e8cf5c9b8 (diff)
Day 7
Diffstat (limited to 'day7/main.go')
-rw-r--r--day7/main.go111
1 files changed, 111 insertions, 0 deletions
diff --git a/day7/main.go b/day7/main.go
new file mode 100644
index 0000000..fd20d4f
--- /dev/null
+++ b/day7/main.go
@@ -0,0 +1,111 @@
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "math"
+ "os"
+ "strconv"
+ "strings"
+)
+
+func main() {
+ fmt.Println(part1(readData("example.txt")))
+ fmt.Println(part1(readData("data.txt")))
+ fmt.Println(part2(readData("example.txt")))
+ fmt.Println(part2(readData("data.txt")))
+}
+
+type Case struct {
+ target int64
+ operands []int64
+}
+
+func part1(cases []Case) (sumOk int64) {
+ for _, c := range cases {
+ if canReach(c.target, 0, c.operands) {
+ sumOk += c.target
+ }
+ }
+ return
+}
+
+func part2(cases []Case) (sumOk int64) {
+ for _, c := range cases {
+ if canReach2(c.target, 0, c.operands) {
+ sumOk += c.target
+ }
+ }
+ return
+}
+
+func concatenate(a int64, b int64) int64 {
+ bDecimalLength := len(strconv.FormatInt(b, 10))
+ return a*int64(math.Pow(10, float64(bDecimalLength))) + b
+}
+
+func canReach(target int64, currentTotal int64, operands []int64) bool {
+ if len(operands) == 0 {
+ return target == currentTotal
+ }
+
+ if currentTotal > target {
+ return false
+ }
+
+ return canReach(target, currentTotal+operands[0], operands[1:]) ||
+ canReach(target, currentTotal*operands[0], operands[1:])
+}
+
+func canReach2(target int64, currentTotal int64, operands []int64) bool {
+ if len(operands) == 0 {
+ return target == currentTotal
+ }
+
+ if currentTotal > target {
+ return false
+ }
+
+ return canReach2(target, currentTotal+operands[0], operands[1:]) ||
+ canReach2(target, currentTotal*operands[0], operands[1:]) ||
+ canReach2(target, concatenate(currentTotal, operands[0]), operands[1:])
+}
+
+func readData(fileName string) (cases []Case) {
+ fp, err := os.Open(fileName)
+ if err != nil {
+ panic(err)
+ }
+
+ scanner := bufio.NewScanner(fp)
+
+ for scanner.Scan() {
+ line := scanner.Text()
+ splitColon := strings.Split(line, ":")
+
+ if len(splitColon) != 2 {
+ panic("Not enough data")
+ }
+
+ target, err := strconv.ParseInt(splitColon[0], 10, 64)
+ if err != nil {
+ panic(err)
+ }
+
+ operandsStr := strings.Split(strings.TrimSpace(splitColon[1]), " ")
+ operands := make([]int64, len(operandsStr))
+
+ for i, s := range operandsStr {
+ n, err := strconv.ParseInt(s, 10, 64)
+ if err != nil {
+ panic(err)
+ }
+
+ operands[i] = n
+ }
+
+ cases = append(cases, Case{target, operands})
+ }
+
+ return
+}