summaryrefslogtreecommitdiff
path: root/2024/go/src/day11
diff options
context:
space:
mode:
authoromagdy <omar.professional8777@gmail.com>2024-12-12 18:31:50 +0200
committeromagdy <omar.professional8777@gmail.com>2024-12-12 18:31:50 +0200
commit0cb12b95ef11fe283731e862e3953f27eeea8757 (patch)
tree66d54e44b821073ddf6381bf9b3d9d55b3d86c31 /2024/go/src/day11
parent93cc02c058f39d370472dfe7d667ae7a2f6396b3 (diff)
downloadaoc-0cb12b95ef11fe283731e862e3953f27eeea8757.tar.xz
aoc-0cb12b95ef11fe283731e862e3953f27eeea8757.zip
Day 11 done.
Diffstat (limited to '2024/go/src/day11')
-rw-r--r--2024/go/src/day11/main.go107
1 files changed, 107 insertions, 0 deletions
diff --git a/2024/go/src/day11/main.go b/2024/go/src/day11/main.go
new file mode 100644
index 0000000..afe54c9
--- /dev/null
+++ b/2024/go/src/day11/main.go
@@ -0,0 +1,107 @@
+package main
+
+import (
+ "fmt"
+ "math"
+ "os"
+ "strconv"
+ "strings"
+)
+
+func FileRead(path string) string {
+ file, err := os.ReadFile(path)
+ if err != nil {
+ fmt.Println("Couldn't Read file: ", err)
+ }
+ return string(file)
+}
+
+func parseInput(data string) []int {
+ var stones []int
+ for _, x := range strings.Split(data, " ") {
+ x := strings.TrimRight(x, "\n")
+ stone, _ := strconv.Atoi(x)
+ stones = append(stones, stone)
+ }
+ return stones
+}
+
+func insert(slice []int, index int, value int) []int {
+ if index < 0 || index > len(slice) {
+ return slice // Or handle the error as you prefer
+ }
+ return append(slice[:index], append([]int{value}, slice[index:]...)...)
+}
+
+func getNumDigits(digit int) int {
+ cnt := 0
+ for digit != 0 {
+ digit /= 10
+ cnt++
+ }
+ return cnt
+}
+
+func splitNumber(num int) (int, int) {
+ digits := getNumDigits(num)
+ divisor := int(math.Pow10(digits / 2))
+ left := num / divisor
+ right := num % divisor
+ return left, right
+}
+
+func isEvenDigits(digit int) bool {
+ return getNumDigits(digit)%2 == 0
+}
+
+func processStone(cache *map[[2]int]int, stone, blinks int) int {
+ result := 0
+ if blinks == 0 {
+ return 1
+ } else {
+ _, exists := (*cache)[[2]int{stone, blinks}]
+ if !exists {
+ if stone == 0 {
+ result = processStone(cache, 1, blinks-1)
+ } else if isEvenDigits(stone) {
+ left, right := splitNumber(stone)
+ result += processStone(cache, left, blinks-1)
+ result += processStone(cache, right, blinks-1)
+ } else {
+ result = processStone(cache, stone*2024, blinks-1)
+ }
+ (*cache)[[2]int{stone, blinks}] = result
+ }
+ return (*cache)[[2]int{stone, blinks}]
+ }
+}
+func processStones(stones []int, blinks int) int {
+ cache := make(map[[2]int]int)
+ ans := 0
+ n := len(stones)
+ for j := 0; j < n; j++ {
+ ans += processStone(&cache, stones[j], blinks)
+ }
+ return ans
+}
+
+func solve_part_one(data string) int {
+ stones := parseInput(data)
+ ans := processStones(stones, 25)
+ return ans
+}
+
+func solve_part_two(data string) int {
+ stones := parseInput(data)
+ ans := processStones(stones, 75)
+ return ans
+}
+
+func main() {
+ test := FileRead("../input/day11.test")
+ prod := FileRead("../input/day11.prod")
+ fmt.Println("Part_1 test: ", solve_part_one(test))
+ fmt.Println("Part_1 prod: ", solve_part_one(prod))
+ fmt.Println("Part_2 test: ", solve_part_two(test))
+ fmt.Println("Part_2 prod: ", solve_part_two(prod))
+}