day11_part2.carbon 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. // https://adventofcode.com/2024/day/11
  5. import Core library "io";
  6. import library "day11_common";
  7. import library "io_utils";
  8. class Digits {
  9. fn Make() -> Digits {
  10. returned var me: Digits;
  11. var digit: i32 = 0;
  12. while (digit < 10) {
  13. var depth: i32 = 0;
  14. while (depth < 75) {
  15. me.count[digit][depth] = 0;
  16. ++depth;
  17. }
  18. ++digit;
  19. }
  20. return var;
  21. }
  22. fn Print[self: Self](max_depth: i32) {
  23. var digit: i32 = 0;
  24. while (digit < 10) {
  25. Core.PrintChar(digit + 0x30);
  26. Core.PrintChar(0x3A);
  27. var depth: i32 = 0;
  28. while (depth <= max_depth) {
  29. Core.PrintChar(0x20);
  30. PrintInt64NoNewline(self.count[digit][depth]);
  31. ++depth;
  32. }
  33. Core.PrintChar(0x0A);
  34. ++digit;
  35. }
  36. Core.PrintChar(0x0A);
  37. }
  38. var count: [[i64; 75]; 10];
  39. }
  40. // TODO: Add a builtin to perform integer conversion / truncation.
  41. fn I64DigitToI32(a: i64) -> i32 {
  42. if (a == 0) { return 0; }
  43. if (a == 1) { return 1; }
  44. if (a == 2) { return 2; }
  45. if (a == 3) { return 3; }
  46. if (a == 4) { return 4; }
  47. if (a == 5) { return 5; }
  48. if (a == 6) { return 6; }
  49. if (a == 7) { return 7; }
  50. if (a == 8) { return 8; }
  51. return 9;
  52. }
  53. fn ReduceToDigits(n: i64, depth: i32, multiplicity: i64, digits: Digits*) -> i64 {
  54. if (n == -1) { return 0; }
  55. if (depth == 0) { return multiplicity; }
  56. if (n < 10) {
  57. let count: i64* = &digits->count[I64DigitToI32(n)][depth - 1];
  58. *count = *count + multiplicity;
  59. return 0;
  60. }
  61. let next: (i64, i64) = Next(n);
  62. return ReduceToDigits(next.0, depth - 1, multiplicity, digits) +
  63. ReduceToDigits(next.1, depth - 1, multiplicity, digits);
  64. }
  65. fn Run() {
  66. let max_depth: i32 = 75;
  67. var total: i64 = 0;
  68. var digits: Digits = Digits.Make();
  69. var n: i64;
  70. while (ReadInt64(&n)) {
  71. total = total + ReduceToDigits(n, max_depth, 1, &digits);
  72. PrintInt64(total);
  73. digits.Print(max_depth - 1);
  74. SkipSpaces();
  75. }
  76. var depth: i32 = max_depth - 1;
  77. while (depth >= 0) {
  78. PrintInt64(total);
  79. digits.Print(depth);
  80. var digit: i64 = 0;
  81. while (digit < 10) {
  82. let m: i64 = digits.count[I64DigitToI32(digit)][depth];
  83. if (m > 0) {
  84. let next: (i64, i64) = Next(digit);
  85. total = total +
  86. ReduceToDigits(next.0, depth, m, &digits) +
  87. ReduceToDigits(next.1, depth, m, &digits);
  88. }
  89. digit = digit + 1;
  90. }
  91. --depth;
  92. }
  93. PrintInt64(total);
  94. }