BlueRains

AdventOfCode C 2024 day 11

Dec 11th, 2024
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.47 KB | Source Code | 0 0
  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. #include <math.h>
  4. #define SIZE 100000
  5. typedef long int num;
  6.  
  7.  
  8. typedef struct {
  9. num number;
  10. int blinks_rem;
  11. num total_stones;
  12. } state_t;
  13.  
  14.  
  15.  
  16.  
  17. /**
  18. * @brief check how many digits num has
  19. * @note Assumes positive number
  20. * @param number: The number to check
  21. * @retval Number of digits
  22. */
  23. int get_digits(num number) {
  24. int count = floor(log10l(number)) + 1;
  25. return count;
  26. }
  27.  
  28. num get_res(num number, int blinks, state_t *saved, int *size) {
  29. for (size_t i = 0; i < *size; i++) {
  30. if ((saved + i)->number == number && (saved + i)->blinks_rem == blinks) {
  31. return (saved + i)->total_stones;
  32. }
  33. }
  34. return -1;
  35. }
  36. /**
  37. * @brief Save the state in the cache
  38. * @note Assumes this state is not saved yet. Does not save if cache is full
  39. */
  40. void add_res(num number, int blinks, num res, state_t *saved, int *size) {
  41. if (*size >= SIZE) {
  42. // Prevent cache overflow.
  43. return;
  44. }
  45. state_t state = { number, blinks, res };
  46. *(saved + *size) = state;
  47. (*size)++;
  48. }
  49.  
  50. num count_stones_saved(num number, int blinks, state_t *saved, int *size, int *hit, int *miss) {
  51. num res = get_res(number, blinks, saved, size);
  52. if (res != -1) {
  53. (*hit)++;
  54. return res;
  55. }
  56. (*miss)++;
  57. if (blinks == 0) {
  58. add_res(number, blinks, 1, saved, size);
  59. return 1;
  60. }
  61. if (number < 0) {
  62. printf("Overflow error occured: %ld\n", number);
  63. }
  64. if (number == 0) {
  65. res = count_stones_saved(1, blinks - 1, saved, size, hit, miss);
  66. add_res(number, blinks, res, saved, size);
  67. return res;
  68. }
  69. int digits = get_digits(number);
  70. if (digits % 2) {
  71. // Odd number of digits
  72. res = count_stones_saved(number * 2024, blinks - 1, saved, size, hit, miss);
  73. add_res(number, blinks, res, saved, size);
  74. return res;
  75. }
  76. int half = digits / 2;
  77. // Ex the number is 12.
  78. // then half = 1
  79. // mod = 10^1 = 10
  80. // 12 / 10 = 1
  81. // 12 % 10 = 2
  82. int mod = pow(10, half);
  83. int num1 = number % mod;
  84. int num2 = number / mod;
  85. res = count_stones_saved(num1, blinks - 1, saved, size, hit, miss) + count_stones_saved(num2, blinks - 1, saved, size, hit, miss);
  86. add_res(number, blinks, res, saved, size);
  87. return res;
  88. }
  89.  
  90. num do_blinks(num *stones, int size, int blinks) {
  91. num total = 0;
  92. state_t states[SIZE] = { 0 };
  93. int state_size = 0;
  94. int cache_miss = 0;
  95. int cache_hit = 0;
  96. int old_miss = 0;
  97. int old_hit = 0;
  98. for (size_t i = 0; i < size; i++) {
  99. printf("Testing %ld: ", *(stones + i));
  100. num res = count_stones_saved(*(stones + i), blinks, states, &state_size, &cache_hit, &cache_miss);
  101. total += res;
  102. printf("%d sub cache hits. %d sub cache misses.\n", cache_hit - old_hit, cache_miss - old_miss);
  103. old_hit = cache_hit;
  104. old_miss = cache_miss;
  105. }
  106. printf("%d cache hits. %d cache misses.\n", cache_hit, cache_miss);
  107. return total;
  108. }
  109.  
  110. int main() {
  111. num test[2] = { 125, 17 };
  112. num stones[8] = { 5, 127, 680267, 39260, 0, 26, 3553, 5851995 };
  113. num test2[5] = { 0, 1, 10, 99, 999 };
  114. printf("Part one test: %ld\n\n", do_blinks(test, 2, 25));
  115. printf("Part two test: %ld\n\n", do_blinks(test, 2, 75));
  116. printf("Part one: %ld\n\n", do_blinks(stones, 8, 25));
  117. printf("Part two: %ld\n\n", do_blinks(stones, 8, 75));
  118. }
  119.  
Advertisement
Add Comment
Please, Sign In to add comment