From c0922af98af7c6415ebcbd34a4c8f9782afbd5cc Mon Sep 17 00:00:00 2001 From: Michael Adler Date: Fri, 15 Dec 2023 22:19:57 +0100 Subject: [PATCH] find cycle --- src/day14/solve.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/day14/solve.c b/src/day14/solve.c index 47119cf..48cb9c7 100644 --- a/src/day14/solve.c +++ b/src/day14/solve.c @@ -137,8 +137,6 @@ void solve(const char *buf, size_t buf_size, Solution *result) { i64 part1, part2 = 0; - int total_cycles = 1000000000; - XXH128_hash_t hashes[MAX_CYCLE_LEN]; int hashes_count = 0; _cleanup_(ust_XXH128_hash_t_free) ust_XXH128_hash_t seen = ust_XXH128_hash_t_init(hash, equal); @@ -148,9 +146,9 @@ void solve(const char *buf, size_t buf_size, Solution *result) { int duplicates_count = 0; // find cycle - for (int cycle = 1; cycle <= MAX_CYCLE_LEN; cycle++) { + for (int cycle = 0; cycle < MAX_CYCLE_LEN; cycle++) { tilt_north(rows, cols); - if (cycle == 1) { part1 = compute_total_load(rows, cols); } + if (cycle == 0) { part1 = compute_total_load(rows, cols); } tilt_west(rows, cols); tilt_south(rows, cols); @@ -161,17 +159,30 @@ void solve(const char *buf, size_t buf_size, Solution *result) { ust_XXH128_hash_t_node *node = ust_XXH128_hash_t_find(&seen, value); if (node != NULL) { - log_debug("cycle %d seen before", cycle); duplicates[duplicates_count++] = value; } else { ust_XXH128_hash_t_insert(&seen, value); } } - for (int i = 0; i < duplicates_count; i++) { - // printf("duplicate %d: %lu%lu\n", i, duplicates[i].low64, duplicates[i].high64); + int cycle_start = 0; + while (!equal(&hashes[cycle_start], &duplicates[0])) { cycle_start++; } + int cycle_len = 1; + while (!equal(&hashes[cycle_start + cycle_len], &duplicates[0])) { cycle_len++; } + log_debug("cycle starts at %d and has length %d", cycle_start, cycle_len); + + // sanity check + for (int i = 0; i < cycle_len; i++) { + assert(equal(&hashes[cycle_start + i], &hashes[cycle_start + cycle_len + i])); } + // from here on we know we have to compute: + // 1) Compute the first `cycle_start` cycles + // 2) Compute rem = total_cycles % cycle_len. + // 3) Compute the next `rem` cycles + + int total_cycles = 1000000000; + // print_platform(rows, cols); snprintf(result->part1, sizeof(result->part1), "%ld", part1);