From 0de2729b5382097c76d6a25522c26719e196dae7 Mon Sep 17 00:00:00 2001
From: Steven Le Rouzic <steven.lerouzic@gmail.com>
Date: Sat, 7 Dec 2024 16:38:30 +0100
Subject: Day 7

---
 day7/main.go | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 111 insertions(+)
 create mode 100644 day7/main.go

(limited to 'day7/main.go')

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
+}
-- 
cgit