From 82d706c64a38f011dafaad4304a9df71778194b9 Mon Sep 17 00:00:00 2001 From: Akuli Date: Fri, 27 Dec 2024 05:29:18 +0200 Subject: [PATCH] cache attempt, not work --- examples/aoc2024/day21/part2.jou | 70 ++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 9 deletions(-) diff --git a/examples/aoc2024/day21/part2.jou b/examples/aoc2024/day21/part2.jou index 12f7b345..5c427419 100644 --- a/examples/aoc2024/day21/part2.jou +++ b/examples/aoc2024/day21/part2.jou @@ -1,4 +1,5 @@ import "stdlib/io.jou" +import "stdlib/mem.jou" import "stdlib/ascii.jou" import "stdlib/math.jou" import "stdlib/str.jou" @@ -31,14 +32,27 @@ class KeyPad: assert False +# cache[nkeypads][key_to_press][old_x][old_y] = return value if not random, 0 if uninitialized +global cache: long[5][5][128][30] + + # Recursive function. Before we recurse, parameters are: # first keypad = the numeric keypad attached to door (the only numeric) # last keypad = the keypad that a human is typing into # # Return value = how many times total the keys on last keypad were pressed. -def press_key(keypads: KeyPad*, nkeypads: int, key_to_press: byte) -> long: -# printf("Press '%c'\n", key_to_press) -# fflush(stdout) +def press_key( + keypads: KeyPad*, + nkeypads: int, + key_to_press: byte, + random_flag: bool* # set to true if randomness is involved, otherwise not used +) -> long: + if nkeypads >= 20: + k = 28-nkeypads + while k --> 0: + printf(" ") + printf("(%d) press '%c'\n", nkeypads, key_to_press) + fflush(stdout) if nkeypads == 1: # Human is typing here, let's simply count the key presses. @@ -56,6 +70,10 @@ def press_key(keypads: KeyPad*, nkeypads: int, key_to_press: byte) -> long: dx = new_x - old_x dy = new_y - old_y + cacheptr = &cache[nkeypads][key_to_press][old_x][old_y] + if *cacheptr != 0: + return *cacheptr + if dx < 0: dx_key = '<' dx_step = -1 @@ -74,6 +92,8 @@ def press_key(keypads: KeyPad*, nkeypads: int, key_to_press: byte) -> long: v_first_blocked = (keypads[0].get(old_x, new_y) == ' ') assert not (h_first_blocked and v_first_blocked) + this_call_is_random = False + if dx == 0 or dy == 0: # order doesn't matter assert not h_first_blocked @@ -88,40 +108,48 @@ def press_key(keypads: KeyPad*, nkeypads: int, key_to_press: byte) -> long: # Let's choose 50% randomly because I can't think of a good way # to figure out what's best. horizontal_first = (rand() % 100 >= 50) + this_call_is_random = True result = 0L if horizontal_first: n = abs(dx) while n --> 0: - result += press_key(&keypads[1], nkeypads - 1, dx_key) + result += press_key(&keypads[1], nkeypads - 1, dx_key, &this_call_is_random) keypads[1].aimed_at_x += dx_step n = abs(dy) while n --> 0: - result += press_key(&keypads[1], nkeypads - 1, dy_key) + result += press_key(&keypads[1], nkeypads - 1, dy_key, &this_call_is_random) keypads[1].aimed_at_y += dy_step else: n = abs(dy) while n --> 0: - result += press_key(&keypads[1], nkeypads - 1, dy_key) + result += press_key(&keypads[1], nkeypads - 1, dy_key, &this_call_is_random) keypads[1].aimed_at_y += dy_step n = abs(dx) while n --> 0: - result += press_key(&keypads[1], nkeypads - 1, dx_key) + result += press_key(&keypads[1], nkeypads - 1, dx_key, &this_call_is_random) keypads[1].aimed_at_x += dx_step assert keypads[1].aimed_at_x == new_x assert keypads[1].aimed_at_y == new_y assert keypads[0].get(new_x, new_y) == key_to_press - result += press_key(&keypads[1], nkeypads - 1, 'A') + result += press_key(&keypads[1], nkeypads - 1, 'A', &this_call_is_random) + + if this_call_is_random: + *random_flag = True +# else: +# *cacheptr = result + return result def main() -> int: srand(123) + memset(&cache, 0, sizeof(cache)) numeric_keypad = KeyPad{ rows = [ @@ -143,6 +171,29 @@ def main() -> int: initial_keypads = [ numeric_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, +# arrow_keypad, arrow_keypad, arrow_keypad, arrow_keypad, @@ -172,7 +223,8 @@ def main() -> int: counter = 0L for i = 0; line[i] != '\0'; i++: - counter += press_key(keypads, sizeof(keypads)/sizeof(keypads[0]) as int, line[i]) + dummy: bool + counter += press_key(keypads, sizeof(keypads)/sizeof(keypads[0]) as int, line[i], &dummy) if best == -1 or counter < best: printf(" (k=%lld) new best: %lld\n", k, counter)