From 17e5d18ffc77c16998b9183dd1073000c0f866a8 Mon Sep 17 00:00:00 2001 From: Scott McKendry <39483124+scottmckendry@users.noreply.github.com> Date: Mon, 9 Dec 2024 09:18:29 +1300 Subject: [PATCH] improve day 6 pt 2 execution time --- 2024/06p1.odin | 15 +++++++++---- 2024/06p2.odin | 47 ++++++++++++++++++----------------------- 2024/tests/06_test.odin | 2 +- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/2024/06p1.odin b/2024/06p1.odin index 8e77c25..80a2a0a 100644 --- a/2024/06p1.odin +++ b/2024/06p1.odin @@ -16,17 +16,23 @@ 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]) + unique_guard_positions, throw_away := get_unique_guard_positions(lines[:len(lines) - 1]) + delete(throw_away) fmt.printf("Unique guard positions: %d\n", unique_guard_positions) } -get_unique_guard_positions :: proc(lines: []string) -> int { +get_unique_guard_positions :: proc( + lines: []string, +) -> ( + visited_count: int, + unique_positions: [dynamic]vec2, +) { lab_map, guard_position, max_x, max_y := parse_lab_map(lines) defer delete(lab_map) guard_direction := vec2{0, -1} - visited_count := 1 + visited_count = 1 on_map := true for on_map { @@ -50,6 +56,7 @@ get_unique_guard_positions :: proc(lines: []string) -> int { guard_position = next_position if !lab_map[guard_position].visited { visited_count += 1 + append(&unique_positions, guard_position) guard_map_coord := lab_map[guard_position] guard_map_coord.visited = true lab_map[guard_position] = guard_map_coord @@ -72,7 +79,7 @@ get_unique_guard_positions :: proc(lines: []string) -> int { } } - return visited_count + return } parse_lab_map :: proc( diff --git a/2024/06p2.odin b/2024/06p2.odin index 105ebf0..824b817 100644 --- a/2024/06p2.odin +++ b/2024/06p2.odin @@ -3,7 +3,7 @@ package main import "core:fmt" import "core:strings" -type_visited :: struct { +position_state :: struct { position, direction: vec2, } @@ -17,33 +17,32 @@ D06P2 :: proc() { get_loop_causing_obstacles :: proc(lines: []string) -> int { original_map, guard_position, max_x, max_y := parse_lab_map(lines) + _, positions_to_check := get_unique_guard_positions(lines) defer delete(original_map) + defer delete(positions_to_check) 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 - } + for position in positions_to_check { + if (position.x == guard_position.x && position.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) + // 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 + // update the new position + coord_to_update := lab_map[position] + coord_to_update.is_obstacle = true + lab_map[position] = coord_to_update - if check_for_loop(lab_map, guard_position, max_x, max_y) { - loop_count += 1 - } + if check_for_loop(lab_map, guard_position, max_x, max_y) { + loop_count += 1 } } @@ -58,17 +57,13 @@ check_for_loop :: proc( guard_direction := vec2{0, -1} guard_pos := guard_position - Position_State :: struct { - pos: vec2, - dir: vec2, - } - visited_states := make(map[Position_State]bool) + 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} + current_state := position_state{guard_pos, guard_direction} if visited_states[current_state] { return true } diff --git a/2024/tests/06_test.odin b/2024/tests/06_test.odin index f04d5b4..b5a3971 100644 --- a/2024/tests/06_test.odin +++ b/2024/tests/06_test.odin @@ -18,7 +18,7 @@ d06p1 :: proc(t: ^testing.T) { "......#...", } want := 41 - got := get_unique_guard_positions(lab_map) + got, _ := get_unique_guard_positions(lab_map) testing.expect(t, got == want, fmt.aprintf("Got: %v | Want: %v", got, want)) free_all()