diff --git a/2024/gareth/day11/day11.go b/2024/gareth/day11/day11.go new file mode 100644 index 0000000..4876cac --- /dev/null +++ b/2024/gareth/day11/day11.go @@ -0,0 +1,89 @@ +package day11 + +import ( + "strconv" + "strings" +) + +func Part1(input string) int { + stones := ParseInput(input) + return len(blinkTimes(stones, 25)) +} + +func Part2(input string) int { + stones := ParseInput(input) + return getNumStones(stones, 75) +} + +func ParseInput(input string) []int { + strStones := strings.Split(strings.TrimSpace(input), " ") + stones := make([]int, 0, len(strStones)) + for _, s := range strStones { + num, _ := strconv.Atoi(s) + stones = append(stones, num) + } + return stones +} + +// Part 1 initial thought of recursion +func blinkTimes(stones []int, times int) []int { + if times <= 0 { + return stones + } + result := blink(stones) + return blinkTimes(result, times-1) +} + +func blink(stones []int) []int { + result := make([]int, 0) + for _, stone := range stones { + strStone := strconv.Itoa(stone) + if stone == 0 { + result = append(result, 1) + } else if len(strStone)%2 == 0 { + mid := len(strStone) / 2 + firstHalf, _ := strconv.Atoi(strStone[:mid]) + secondHalf, _ := strconv.Atoi(strStone[mid:]) + result = append(result, firstHalf, secondHalf) + } else { + result = append(result, stone*2024) + } + } + return result +} + +// Part 2 with maps since blinkTimes(75) would set my computer on fire +func getNumStones(s []int, times int) int { + stoneMap := make(map[int]int) + for _, stone := range s { + stoneMap[stone] = stoneMap[stone] + 1 + } + + for i := 0; i < times; i++ { + stoneMap2 := make(map[int]int) + for stone, count := range stoneMap { + stones := make([]int, 0) + strStone := strconv.Itoa(stone) + if stone == 0 { + stones = append(stones, 1) + } else if len(strStone)%2 == 0 { + mid := len(strStone) / 2 + firstHalf, _ := strconv.Atoi(strStone[:mid]) + secondHalf, _ := strconv.Atoi(strStone[mid:]) + stones = append(stones, firstHalf, secondHalf) + } else { + stones = append(stones, stone*2024) + } + for _, newStone := range stones { + stoneMap2[newStone] = stoneMap2[newStone] + count + } + } + stoneMap = stoneMap2 + } + + result := 0 + for _, count := range stoneMap { + result += count + } + return result +} diff --git a/2024/gareth/day11/day11_test.go b/2024/gareth/day11/day11_test.go new file mode 100644 index 0000000..56c3825 --- /dev/null +++ b/2024/gareth/day11/day11_test.go @@ -0,0 +1,12 @@ +package day11 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPart1(t *testing.T) { + r := Part1(`125 17`) + assert.Equal(t, 55312, r) +} diff --git a/2024/gareth/day11/input.txt b/2024/gareth/day11/input.txt new file mode 100644 index 0000000..ae72b37 --- /dev/null +++ b/2024/gareth/day11/input.txt @@ -0,0 +1 @@ +965842 9159 3372473 311 0 6 86213 48 \ No newline at end of file diff --git a/2024/gareth/main.go b/2024/gareth/main.go index 21ec5bb..2ce8458 100644 --- a/2024/gareth/main.go +++ b/2024/gareth/main.go @@ -1,7 +1,7 @@ package main import ( - "aoc2024/day07" + "aoc2024/day11" "fmt" "os" "time" @@ -9,9 +9,9 @@ import ( func main() { start := time.Now() - data, _ := os.ReadFile("day07/input.txt") - fmt.Printf("part 1: %d\n", day07.Part1(string(data))) - fmt.Printf("part 2: %d\n", day07.Part2(string(data))) + data, _ := os.ReadFile("day11/input.txt") + fmt.Printf("part 1: %d\n", day11.Part1(string(data))) + fmt.Printf("part 2: %d\n", day11.Part2(string(data))) elapsed := time.Since(start) fmt.Printf("Execution time: %s\n", elapsed) }