From b34b241aa51a52ab967e817ec50c9337afc0bb5c Mon Sep 17 00:00:00 2001 From: Scott McKendry <39483124+scottmckendry@users.noreply.github.com> Date: Sun, 8 Dec 2024 09:15:26 +1300 Subject: [PATCH] add day 6 solutions and tests use old odin release to fix ci error --- .github/workflows/CI.yml | 2 + 2024/06p1.odin | 107 ++++++++++++++++++++++++++++++++ 2024/06p2.odin | 114 ++++++++++++++++++++++++++++++++++ 2024/inputs/06.txt | 130 +++++++++++++++++++++++++++++++++++++++ 2024/main.odin | 2 + 2024/tests/06_test.odin | 78 +++++++++++++++++++++++ 6 files changed, 433 insertions(+) create mode 100644 2024/06p1.odin create mode 100644 2024/06p2.odin create mode 100644 2024/inputs/06.txt create mode 100644 2024/tests/06_test.odin diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 8771eaf..53be759 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -15,6 +15,7 @@ jobs: - uses: laytan/setup-odin@v2 with: token: ${{ secrets.GITHUB_TOKEN }} + release: dev-2024-11 - name: Report run: | odin report ./2021 @@ -34,6 +35,7 @@ jobs: - uses: laytan/setup-odin@v2 with: token: ${{ secrets.GITHUB_TOKEN }} + release: dev-2024-11 - run: cd 2021 && task bench - run: cd 2022 && go build . diff --git a/2024/06p1.odin b/2024/06p1.odin new file mode 100644 index 0000000..8e77c25 --- /dev/null +++ b/2024/06p1.odin @@ -0,0 +1,107 @@ +package main + +import "core:fmt" +import "core:strings" + +vec2 :: struct { + x, y: int, +} + +lab_map_coord :: struct { + is_obstacle: bool, + visited: bool, +} + +D06P1 :: proc() { + input_string := #load("inputs/06.txt", string) + lines := strings.split(input_string, "\n", context.temp_allocator) + + unique_guard_positions := get_unique_guard_positions(lines[:len(lines) - 1]) + fmt.printf("Unique guard positions: %d\n", unique_guard_positions) +} + +get_unique_guard_positions :: proc(lines: []string) -> int { + lab_map, guard_position, max_x, max_y := parse_lab_map(lines) + defer delete(lab_map) + + guard_direction := vec2{0, -1} + + visited_count := 1 + + on_map := true + for on_map { + // walk in direction until obstacle, then turn 90 degrees + for { + next_position: vec2 + next_position.x, next_position.y = + guard_position.x + guard_direction.x, guard_position.y + guard_direction.y + if lab_map[next_position].is_obstacle { + break + } + + if next_position.x < 0 || + next_position.x >= max_x || + next_position.y < 0 || + next_position.y >= max_y { + on_map = false + break + } + + guard_position = next_position + if !lab_map[guard_position].visited { + visited_count += 1 + guard_map_coord := lab_map[guard_position] + guard_map_coord.visited = true + lab_map[guard_position] = guard_map_coord + } + } + + // turn 90 degrees + if guard_direction.x == 0 { + if guard_direction.y == 1 { + guard_direction = vec2{-1, 0} + } else { + guard_direction = vec2{1, 0} + } + } else { + if guard_direction.x == 1 { + guard_direction = vec2{0, 1} + } else { + guard_direction = vec2{0, -1} + } + } + } + + return visited_count +} + +parse_lab_map :: proc( + lines: []string, +) -> ( + lab_map: map[vec2]lab_map_coord, + guard_position: vec2, + max_x: int, + max_y: int, +) { + for line, y in lines { + for char, x in line { + switch char { + case '^': + guard_position = vec2{x, y} + lab_map[vec2{x, y}] = lab_map_coord { + visited = true, + } + case '#': + lab_map[vec2{x, y}] = lab_map_coord { + is_obstacle = true, + } + case: + lab_map[vec2{x, y}] = lab_map_coord{} + } + } + } + + max_x = len(lines[0]) + max_y = len(lines) + return +} diff --git a/2024/06p2.odin b/2024/06p2.odin new file mode 100644 index 0000000..105ebf0 --- /dev/null +++ b/2024/06p2.odin @@ -0,0 +1,114 @@ +package main + +import "core:fmt" +import "core:strings" + +type_visited :: struct { + position, direction: vec2, +} + +D06P2 :: proc() { + input_string := #load("inputs/06.txt", string) + lines := strings.split(input_string, "\n", context.temp_allocator) + + loop_causing_obstacles := get_loop_causing_obstacles(lines[:len(lines) - 1]) + fmt.printf("Number of loop-causing obstacle positions: %d\n", loop_causing_obstacles) +} + +get_loop_causing_obstacles :: proc(lines: []string) -> int { + original_map, guard_position, max_x, max_y := parse_lab_map(lines) + defer delete(original_map) + + loop_count := 0 + + // place a obstable at each possible position, and check if it causes a loop + for y in 0 ..< max_y { + for x in 0 ..< max_x { + if original_map[vec2{x, y}].is_obstacle || + (x == guard_position.x && y == guard_position.y) { + continue + } + + // create a new map and copy all entries + lab_map := make(map[vec2]lab_map_coord) + for k, v in original_map { + lab_map[k] = v + } + defer delete(lab_map) + + // update the new position + coord_to_update := lab_map[vec2{x, y}] + coord_to_update.is_obstacle = true + lab_map[vec2{x, y}] = coord_to_update + + if check_for_loop(lab_map, guard_position, max_x, max_y) { + loop_count += 1 + } + } + } + + return loop_count +} + +check_for_loop :: proc( + lab_map: map[vec2]lab_map_coord, + guard_position: vec2, + max_x, max_y: int, +) -> bool { + guard_direction := vec2{0, -1} + guard_pos := guard_position + + Position_State :: struct { + pos: vec2, + dir: vec2, + } + visited_states := make(map[Position_State]bool) + defer delete(visited_states) + + on_map := true + + for on_map { + current_state := Position_State{guard_pos, guard_direction} + if visited_states[current_state] { + return true + } + + visited_states[current_state] = true + + for { + next_position: vec2 + next_position.x, next_position.y = + guard_pos.x + guard_direction.x, guard_pos.y + guard_direction.y + if lab_map[next_position].is_obstacle { + break + } + + if next_position.x < 0 || + next_position.x >= max_x || + next_position.y < 0 || + next_position.y >= max_y { + on_map = false + break + } + + guard_pos = next_position + } + + // turn 90 degrees (same as before) + if guard_direction.x == 0 { + if guard_direction.y == 1 { + guard_direction = vec2{-1, 0} + } else { + guard_direction = vec2{1, 0} + } + } else { + if guard_direction.x == 1 { + guard_direction = vec2{0, 1} + } else { + guard_direction = vec2{0, -1} + } + } + } + + return false +} diff --git a/2024/inputs/06.txt b/2024/inputs/06.txt new file mode 100644 index 0000000..1f20b72 --- /dev/null +++ b/2024/inputs/06.txt @@ -0,0 +1,130 @@ +..........#.............................#...............#...........#....................#...........#............................ +..............................#.......#...#.....#.....#...............#.#..#.......................#............#................. +.............#...........#.#........#............#..........................#.........#.......#......#............................ +......................................................#....#..#.............#................................#...#............##.. +...............#.....#....................................#......................................................#................ +..................##............#......#...............................................................#...................#...... +.#......#...........................................................#............................#................................ +#..#.............#...............................#.....#....#.............................#....#..............................#... +#...##..........#.........................#.................................................#............#...............#........ +............#...............#..............................................#.................................#..........##........ +..............#...................#......##...#.....#....................#.......................................................# +.#.....#....#......................#...#........................................#.#.............#.........#....................... +#..#...............#........##.........#.....#..........#.....##.........................#.....#.#................................ +...............#...............................#.....#.................................................#..##...................... +......#...................#..........#...........................................#....#........................................... +...............................................#...#....##.................................................#.....#................ +.................#.........#..............................#........#...#...#...................................#.................. +...........#..#.....#...#.........................#..........#.#.............#....#...................##.......................... +.........................................#.........................#.#............#...#...##............................#......... +.....#......................................#....................................................#..............#................. +..................................................#..................#................#.............#.#..#..................#..... +............................................#.....#......................#........#..........................................#.... +.......#..........................#...#...................................#.........................#...#..........#......#....... +............#...........##........................................................................#......................#........ +#.#...............................................#........#..........#.#..#...#................................#................. +..#.........................#.#........................#....##..................................................#............#.... +.....................................................................................#...............#...........#..........#..... +....................#..........#................................#...............................................#................. +#..............#.#...........#.........#..........#..........................#......................##........#.........#......... +....#....#...............................................................................#...#...........#............#...#...#... +.......................................................##......................#...#................................#............. +.......#...........##...........................#..............#..............................#...................#......#........ +......#.........#..............................................................#........#..#..........#.......#..#...#.....#....#. +....#.............................................#........#....#..................................#.............................. +..........#......#...........#....................................#..............#.......#...#............#....................... +...........................................................................................#.......#.............................. +.#..................................................#.............................#..................#...................#........ +......#..#.#................#.....................#..................................#.............#...............#.............. +...............................#..................#........#...................................................................... +......................#..................................................................................#.........#.............. +...............................................................................................................................#.. +.......#..............#...........................................................#......................#.......................# +#...............................#..............................#.......#..............................#...#...#........#.......... +............................#....#...#.........#....#................................................................#............ +.....................#.................................................................#..#....#..................#............... +......................#.............#.............................#...................................................#........... +....#.................#.#.........##................#.....#....................................................#.............#.... +...............................#...#...................#.......................................#......#........................... +....#............................................................................................................................. +...#.......................................................................................................#............#.......#. +..#.............##.............................................................#...#............................#............#.... +......................#.......#............#........................................................#..................#......#... +...................#.............#..................#..............................#............#........#...................#.... +....................#...........#.........................................................#......#.......#...........#.....##..... +...........#.........................................#.............................#..............#..................#............ +......................#.........#...................#......#...........................................#.......................... +..#....#...#.............................#..............#.....................#............#...................................#.. +.....#.............................#....#..................................#...................#...#.............#................ +...................#...#...........#........................#.............#........................#...#.............#..........#. +...#...........#......#.......#..............#......#..........#.....#............................................................ +..#......................................................#......#...........................#...........#......#..#............... +........#............................#.#....................#...#...#......#.....#...............................................# +.............#....#........#.........................................................................................#.........#.. +....................................................................................................#............................. +..#........................#....#............................................................................#.................... +.......................................#.....#.#.......................................#......#........#.#...................#.... +.................#........#....................................#...#..#................................#.......................... +...........#.................................................................................................#.................... +......................#..................#...#.............#................##................#.......#...........#.........#..... +............#..#................#.............................................#............##..................##..........#...... +......#.#.......................#............#...........................................................#........................ +#......................................#.#......^...............................................#................................. +........#...........................................................#...............#............................................. +...#.............................................#.................#...............#.............................#...#.#.......... +....................#........#...........##.......................#.................#..................#................#......... +#................................................................................................................................. +............#.......................................................................................#.#.........#..............#.. +...............#....#............#..................................................#......##.................................#... +.............................#.........#...............#......#.......#.................#........................#........#....... +......................................................#........................................................#.................# +.................#.#...............#......................................................................................#....#.. +........#.............#......................#...........#...........#......................................#..............#...... +......................#......................#...........#.....#.....##............................................#....#......... +.............#................................................................................#..........#.....#.................. +............##...........................#.................................#..#.#....................................#............ +..............................................................................................#............................#...... +...#.............................#..#..#....................................#..............#....#................................. +.....#..........................................................#.....#......#.........#.......................................... +....##......#.....................#..........#..............#..................#.#..............#........#...........#....#....... +.....#...#.........#............#............#.............................................................#...................... +.........#...................................#...........#.....................................##.....#............#.............. +.....##.#............##.....................#..........................#.................................#........#............... +.......................#..............##...#...................................................#.........#........................ +..#........#.......#...#..##............#....................................................................#...........#.....#.. +..#.....................................................................#..............#.............#...................#........ +...........#..........#..........#.....#.................................................................#..#..................... +..........#................#........................................................##.#...............................#.#......#. +#............................................#...........................##...#.......................#.............#............. +..#............#........................................................................................................#......... +....................................................#....................#............#...............#..........................# +........................................................................#.......#.....................................#.#......... +................#..#......................#...........................................#........................................... +........................##............................................#.............##..........................#.......#....#.... +.........#.......#..............................#......#....#............#..................#...#................................. +#.........#............................#....#.#..#.........................................................##..................... +.#..##...............#....#.............................#...............#........#.......................................#......#. +...#............................................................#.....................#.................#.....#................... +...#...........#..#.............................#.....#.............................................................#............. +...#.........................#..............................................................................................##.... +.........................#...........................#.......................#...........#........................................ +.#..................................#............................................................................................. +....................................................................#...........##.....#.#.........#.....#........................ +................#...............................#........#........................................................................ +......#....#.................................#...................................#.#.........#.....#....................#......... +................#..............................#.......................#...#.....#.......#................#....................... +....................#......................................#..#...........#.#.................#...#.......................#....... +.............#..#...#............................#.#...........................................#.......................#.......... +.........#..........#.................#....................................#.#..........................................#......... +....#.............#......................................................#...........#...........................#................ +........#.#............................#...........................................#.................#..............#..........#.. +..............#..........................#............#.........#....#...#.....#.........................#....#...............##.. +...................#.........................................................#.......#........#..............#..........#......... +.#........#....#..................................#..#.#...............#............#...........#................................. +...............................................................................................#.....#....#.............#......... +...........#..........#...........................................#.........#..............#................#..........#.......... +............#.................................###..............#.#...............................................................# +......#...................................................................................#............#...#..........#.....#..... +.............#..................#...................#......#.........#..#.......................#....#................#..........# +..#....##................................#.................#...........................#.......#....#...#..........#.............. +...............................#......................................#.........#.............#......................#..........#. diff --git a/2024/main.odin b/2024/main.odin index e40a794..c1d0ba1 100644 --- a/2024/main.odin +++ b/2024/main.odin @@ -21,6 +21,8 @@ solutions: map[string]proc() = { "04P2:Ceres Search" = D04P2, "05P1:Print Queue" = D05P1, "05P2:Print Queue" = D05P2, + "06P1:Guard Gallivant" = D06P1, + "06P2:Guard Gallivant" = D06P2, } main :: proc() { diff --git a/2024/tests/06_test.odin b/2024/tests/06_test.odin new file mode 100644 index 0000000..f04d5b4 --- /dev/null +++ b/2024/tests/06_test.odin @@ -0,0 +1,78 @@ +package main + +import "core:fmt" +import "core:testing" + +@(test) +d06p1 :: proc(t: ^testing.T) { + lab_map := []string { + "....#.....", + ".........#", + "..........", + "..#.......", + ".......#..", + "..........", + ".#..^.....", + "........#.", + "#.........", + "......#...", + } + want := 41 + got := get_unique_guard_positions(lab_map) + testing.expect(t, got == want, fmt.aprintf("Got: %v | Want: %v", got, want)) + + free_all() +} + +@(test) +d06p2 :: proc(t: ^testing.T) { + lab_map := []string { + "....#.....", + ".........#", + "..........", + "..#.......", + ".......#..", + "..........", + ".#..^.....", + "........#.", + "#.........", + "......#...", + } + want := 6 + got := get_loop_causing_obstacles(lab_map) + testing.expect(t, got == want, fmt.aprintf("Got: %v | Want: %v", got, want)) + + free_all() +} + +test_parse_lab_map :: proc(t: ^testing.T) { + lab_map := []string { + "....#.....", + ".........#", + "..........", + "..#.......", + ".......#..", + "..........", + ".#..^.....", + "........#.", + "#.........", + "......#...", + } + got_lab_map_coords, got_guard_position, _, _ := parse_lab_map(lab_map) + want_guard_position := vec2{4, 6} + example_obtacle := vec2{4, 0} + + testing.expect( + t, + got_guard_position == want_guard_position, + fmt.aprintf("Got: %v | Want: %v", got_guard_position, want_guard_position), + ) + + testing.expect( + t, + got_lab_map_coords[example_obtacle].is_obstacle, + fmt.aprintf("Got: %v | Want: %v", got_lab_map_coords[example_obtacle].is_obstacle, true), + ) + + free_all() +}