From 8e6be56ce2755587bd3c53a190deeb940fd62ba6 Mon Sep 17 00:00:00 2001 From: Christopher De Vries Date: Thu, 28 Dec 2023 15:18:30 -0500 Subject: [PATCH] wip day 21 where I left things --- README.md | 12 ++- day21p2/solution.go | 186 +++++++++++++++++++++++++++++++++++++++ day21p2/solution_test.go | 50 +++++++++++ 3 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 day21p2/solution.go create mode 100644 day21p2/solution_test.go diff --git a/README.md b/README.md index 8cf76e9..c7915ac 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Advent of Code 2023 [![Tests](https://github.com/devries/advent_of_code_2023/actions/workflows/main.yml/badge.svg)](https://github.com/devries/advent_of_code_2023/actions/workflows/main.yml) -[![Stars: 40](https://img.shields.io/badge/⭐_Stars-40-yellow)](https://adventofcode.com/2023) +[![Stars: 41](https://img.shields.io/badge/⭐_Stars-41-yellow)](https://adventofcode.com/2023) ## Plan for This Year @@ -321,3 +321,13 @@ the third run of my solution after compilation on my Raspberry Pi. examining the structure of the gates to form a solution. I only did the solution for my particular arrangement. The code to part two does produce a visualization which can be used to change the final 4 binary entries in the program. + +- [Day 21: Step Counter](https://adventofcode.com/2023/day/21) - [⭐ part 1](day21p1/solution.go), [part 2](day21p2/solution.go) + + I did part 1 of this probem and then put aside part 2 for later in the day. I + was working on adding up all the maps in a diamond with alternating odd square + and even square map counts, but I had some arithmatic errors and offset issues. + Eventually I decided to put it aside. Some other issues started taking up my + time including a large refactoring project at work and my children arriving for + Christmas, so I didn't get back to it this year. I will probably finish things + up in the new year. diff --git a/day21p2/solution.go b/day21p2/solution.go new file mode 100644 index 0000000..f683487 --- /dev/null +++ b/day21p2/solution.go @@ -0,0 +1,186 @@ +package day21p2 + +import ( + "fmt" + "io" + + "aoc/utils" +) + +func Solve(r io.Reader) any { + return solveSteps(r, 26501365) +} + +// 3456789 +// 2#6789 +2 +// 1#56789 +2 +// 0#456789 +2 +// 123456789 +// 2#456789 +// 3456789 + +func solveSteps(r io.Reader, steps int) uint64 { + lines := utils.ReadLines(r) + + garden := Maze{ + positions: make(map[utils.Point]rune), + bfs: utils.NewBFS[utils.Point](), + steps: 0, // start without a step limit to get available squares + width: len(lines[0]), + height: len(lines), + } + + fmt.Printf("%#v\n", garden) + + for j, ln := range lines { + for i, r := range ln { + p := utils.Point{X: i, Y: j} + garden.positions[p] = r + if r == 'S' { + garden.start = p + } + } + } + + // for j := 0; j < garden.width; j += 2 { + // for i := 0; i < garden.height; i += 2 { + // fmt.Printf("%c", garden.positions[utils.Point{X: i, Y: j}]) + // } + // fmt.Println() + // } + // fmt.Println() + + // for j := 1; j < garden.width; j += 2 { + // for i := 1; i < garden.height; i += 2 { + // fmt.Printf("%c", garden.positions[utils.Point{X: i, Y: j}]) + // } + // fmt.Println() + // } + // fmt.Println() + + // Get number of even and odd squares + _, err := garden.bfs.Run(garden) + if err != utils.BFSNotFound { + panic("this should end when points are exhausted") + } + + var even uint64 + var odd uint64 + + for _, d := range garden.bfs.Distance { + if d%2 == 0 { + even++ + } else { + odd++ + } + } + + var count uint64 + // How many maps fit within the total steps from S? + fmt.Println("start:", garden.start, "width:", garden.width, "height", garden.height) + fmt.Println("even:", even, "odd:", odd) + + mapNumber := (steps - garden.start.X) / garden.width + + additionalStepsDirect := steps - garden.start.X - mapNumber*garden.width + additionalStepsDiag := steps - garden.start.X + garden.start.Y - (mapNumber-1)*garden.width + fmt.Println("Maps:", mapNumber, "Extra:", additionalStepsDirect, "Extra diag:", additionalStepsDiag) + + evenmaps := 1 + oddmaps := 0 + for i := 1; i <= mapNumber; i++ { + amt := i / 2 + if i%2 == 0 { + evenmaps += 8 * amt + } else { + oddmaps += 8*amt + 4 + } + } + + fmt.Println(evenmaps, oddmaps, even*uint64(evenmaps)+odd*uint64(oddmaps)) + // sp := garden.GetInitial() + // for j := 0; j < garden.width; j++ { + // for i := 0; i < garden.height; i++ { + // pos := utils.Point{X: i, Y: j} + // if pos == sp { + // fmt.Printf("S") + // continue + // } + // if garden.positions[pos] == '.' || garden.positions[pos] == 'S' { + // if stp, ok := garden.bfs.Distance[pos]; ok { + // stp = garden.bfs.Distance[pos] + // expected := uint64(sp.Add(pos.Scale(-1)).Manhattan()) + // if expected != stp { + // fmt.Printf("%d", stp-expected) + // } else { + // fmt.Printf(" ") + // } + // } else { + // fmt.Printf("X") + // } + // } else { + // fmt.Printf("#") + // } + // } + // fmt.Println() + // } + // fmt.Println() + + // var count uint64 + // for _, d := range garden.bfs.Distance { + // if d%2 == 0 { + // count++ + // } + // } + + return count +} + +type Maze struct { + positions map[utils.Point]rune + bfs *utils.BreadthFirstSearch[utils.Point] + steps int + width int + height int + start utils.Point +} + +func (m Maze) GetInitial() utils.Point { + return m.start +} + +func (m Maze) GetNeighbors(pos utils.Point) []utils.Point { + ret := []utils.Point{} + + // if m.bfs.Distance[pos] < uint64(m.steps) { + // for _, dir := range utils.Directions { + // np := pos.Add(dir) + // npmapped := utils.Point{X: np.X % m.width, Y: np.Y % m.height} + // if npmapped.X < 0 { + // npmapped.X += m.width + // } + // if npmapped.Y < 0 { + // npmapped.Y += m.height + // } + + // if m.positions[npmapped] == '.' || m.positions[npmapped] == 'S' { + // ret = append(ret, np) + // } + // } + // } + + // Let's get distance to every point in map + if m.steps == 0 || m.bfs.Distance[pos] < uint64(m.steps) { + for _, dir := range utils.Directions { + np := pos.Add(dir) + if m.positions[np] == '.' || m.positions[np] == 'S' { + ret = append(ret, np) + } + } + } + return ret +} + +func (m Maze) IsFinal(pos utils.Point) bool { + return false +} diff --git a/day21p2/solution_test.go b/day21p2/solution_test.go new file mode 100644 index 0000000..91e9ee8 --- /dev/null +++ b/day21p2/solution_test.go @@ -0,0 +1,50 @@ +package day21p2 + +import ( + "strings" + "testing" + + "aoc/utils" +) + +var testInput = `........... +.....###.#. +.###.##..#. +..#.#...#.. +....#.#.... +.##..S####. +.##..#...#. +.......##.. +.##.#.####. +.##..##.##. +...........` + +func TestSolve(t *testing.T) { + tests := []struct { + input string + steps int + answer uint64 + }{ + {testInput, 6, 16}, + {testInput, 10, 50}, + {testInput, 50, 1594}, + {testInput, 100, 6536}, + {testInput, 500, 167004}, + {testInput, 1000, 668697}, + {testInput, 5000, 16733044}, + } + + if testing.Verbose() { + utils.Verbose = true + } + + for _, test := range tests { + r := strings.NewReader(test.input) + + result := solveSteps(r, test.steps) + + if result != test.answer { + t.Errorf("Expected %d, got %d", test.answer, result) + } + } +}