day10_part1.carbon 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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/10
  5. import Core library "io";
  6. import library "day10_common";
  7. import library "io_utils";
  8. // TODO: Add this to the prelude.
  9. fn PopCount(n: u256) -> i32 {
  10. var bit: u256 = 1;
  11. var total: i32 = 0;
  12. while (bit != 0) {
  13. if (n & bit != 0) {
  14. ++total;
  15. }
  16. bit = bit << 1;
  17. }
  18. return total;
  19. }
  20. class Reachable {
  21. fn Make(terrain: Terrain) -> Reachable {
  22. returned var me: Reachable;
  23. var next: u256 = 1;
  24. var y: i32 = 0;
  25. while (y < 43) {
  26. var x: i32 = 0;
  27. while (x < 43) {
  28. if (terrain.height[x][y] == 0) {
  29. me.trailheads[x][y] = next;
  30. next = next << 1;
  31. }
  32. ++x;
  33. }
  34. ++y;
  35. }
  36. return var;
  37. }
  38. fn AddLevel[addr self: Self*](terrain: Terrain, level: i32) {
  39. let adj: [(i32, i32); 4] = ((-1, 0), (0, -1), (1, 0), (0, 1));
  40. var y: i32 = 0;
  41. while (y < 43) {
  42. var x: i32 = 0;
  43. while (x < 43) {
  44. if (terrain.height[x][y] == level) {
  45. var reach: u256 = 0;
  46. var i: i32 = 0;
  47. while (i < 4) {
  48. let adj_x: i32 = x + adj[i].0;
  49. let adj_y: i32 = y + adj[i].1;
  50. if (adj_x >= 0 and adj_x < 43 and
  51. adj_y >= 0 and adj_y < 43 and
  52. terrain.height[adj_x][adj_y] == level - 1) {
  53. reach = reach | self->trailheads[adj_x][adj_y];
  54. }
  55. ++i;
  56. }
  57. self->trailheads[x][y] = reach;
  58. }
  59. ++x;
  60. }
  61. ++y;
  62. }
  63. }
  64. fn Count[self: Self](terrain: Terrain, level: i32) -> i32 {
  65. var total: i32 = 0;
  66. var y: i32 = 0;
  67. while (y < 43) {
  68. var x: i32 = 0;
  69. while (x < 43) {
  70. if (terrain.height[x][y] == level) {
  71. total += PopCount(self.trailheads[x][y]);
  72. }
  73. ++x;
  74. }
  75. ++y;
  76. }
  77. return total;
  78. }
  79. var trailheads: [[u256; 43]; 43];
  80. }
  81. fn Run() {
  82. var terrain: Terrain = Terrain.Read();
  83. var reachable: Reachable = Reachable.Make(terrain);
  84. var i: i32 = 1;
  85. while (i <= 9) {
  86. reachable.AddLevel(terrain, i);
  87. ++i;
  88. }
  89. Core.Print(reachable.Count(terrain, 9));
  90. }