Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdbool.h>
- #include <math.h>
- #define SIZE 100000
- typedef long int num;
- typedef struct {
- num number;
- int blinks_rem;
- num total_stones;
- } state_t;
- /**
- * @brief check how many digits num has
- * @note Assumes positive number
- * @param number: The number to check
- * @retval Number of digits
- */
- int get_digits(num number) {
- int count = floor(log10l(number)) + 1;
- return count;
- }
- num get_res(num number, int blinks, state_t *saved, int *size) {
- for (size_t i = 0; i < *size; i++) {
- if ((saved + i)->number == number && (saved + i)->blinks_rem == blinks) {
- return (saved + i)->total_stones;
- }
- }
- return -1;
- }
- /**
- * @brief Save the state in the cache
- * @note Assumes this state is not saved yet. Does not save if cache is full
- */
- void add_res(num number, int blinks, num res, state_t *saved, int *size) {
- if (*size >= SIZE) {
- // Prevent cache overflow.
- return;
- }
- state_t state = { number, blinks, res };
- *(saved + *size) = state;
- (*size)++;
- }
- num count_stones_saved(num number, int blinks, state_t *saved, int *size, int *hit, int *miss) {
- num res = get_res(number, blinks, saved, size);
- if (res != -1) {
- (*hit)++;
- return res;
- }
- (*miss)++;
- if (blinks == 0) {
- add_res(number, blinks, 1, saved, size);
- return 1;
- }
- if (number < 0) {
- printf("Overflow error occured: %ld\n", number);
- }
- if (number == 0) {
- res = count_stones_saved(1, blinks - 1, saved, size, hit, miss);
- add_res(number, blinks, res, saved, size);
- return res;
- }
- int digits = get_digits(number);
- if (digits % 2) {
- // Odd number of digits
- res = count_stones_saved(number * 2024, blinks - 1, saved, size, hit, miss);
- add_res(number, blinks, res, saved, size);
- return res;
- }
- int half = digits / 2;
- // Ex the number is 12.
- // then half = 1
- // mod = 10^1 = 10
- // 12 / 10 = 1
- // 12 % 10 = 2
- int mod = pow(10, half);
- int num1 = number % mod;
- int num2 = number / mod;
- res = count_stones_saved(num1, blinks - 1, saved, size, hit, miss) + count_stones_saved(num2, blinks - 1, saved, size, hit, miss);
- add_res(number, blinks, res, saved, size);
- return res;
- }
- num do_blinks(num *stones, int size, int blinks) {
- num total = 0;
- state_t states[SIZE] = { 0 };
- int state_size = 0;
- int cache_miss = 0;
- int cache_hit = 0;
- int old_miss = 0;
- int old_hit = 0;
- for (size_t i = 0; i < size; i++) {
- printf("Testing %ld: ", *(stones + i));
- num res = count_stones_saved(*(stones + i), blinks, states, &state_size, &cache_hit, &cache_miss);
- total += res;
- printf("%d sub cache hits. %d sub cache misses.\n", cache_hit - old_hit, cache_miss - old_miss);
- old_hit = cache_hit;
- old_miss = cache_miss;
- }
- printf("%d cache hits. %d cache misses.\n", cache_hit, cache_miss);
- return total;
- }
- int main() {
- num test[2] = { 125, 17 };
- num stones[8] = { 5, 127, 680267, 39260, 0, 26, 3553, 5851995 };
- num test2[5] = { 0, 1, 10, 99, 999 };
- printf("Part one test: %ld\n\n", do_blinks(test, 2, 25));
- printf("Part two test: %ld\n\n", do_blinks(test, 2, 75));
- printf("Part one: %ld\n\n", do_blinks(stones, 8, 25));
- printf("Part two: %ld\n\n", do_blinks(stones, 8, 75));
- }
Advertisement
Add Comment
Please, Sign In to add comment