day6_common.carbon 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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/6
  5. library "day6_common";
  6. import Core library "io";
  7. import library "io_utils";
  8. // TODO: Use a choice type.
  9. fn Empty() -> i8 { return 0; }
  10. fn Visited() -> i8 { return 1; }
  11. fn Wall() -> i8 { return 2; }
  12. class Maze {
  13. impl as Core.UnformedInit {}
  14. fn Read() -> Maze {
  15. returned var me: Maze;
  16. var y: i32 = 0;
  17. while (y < 130) {
  18. var x: i32 = 0;
  19. while (x < 130) {
  20. var cell: i32 = Core.ReadChar();
  21. if (cell == 0x23) {
  22. me.data[x][y] = Wall();
  23. } else if (cell == 0x5E) {
  24. // TODO: Handle other starting directions?
  25. me.data[x][y] = Visited();
  26. me.loc = (x, y);
  27. me.dir = (0, -1);
  28. } else {
  29. me.data[x][y] = Empty();
  30. }
  31. ++x;
  32. }
  33. SkipNewline();
  34. ++y;
  35. }
  36. return var;
  37. }
  38. fn Copy[self: Self]() -> Maze {
  39. returned var copy: Maze;
  40. var y: i32 = 0;
  41. while (y < 130) {
  42. var x: i32 = 0;
  43. while (x < 130) {
  44. copy.data[x][y] = self.data[x][y];
  45. ++x;
  46. }
  47. ++y;
  48. }
  49. copy.loc = self.loc;
  50. copy.dir = self.dir;
  51. return var;
  52. }
  53. fn Step[ref self: Self]() -> bool {
  54. let x: i32 = self.loc.0 + self.dir.0;
  55. let y: i32 = self.loc.1 + self.dir.1;
  56. if (x < 0 or x >= 130 or y < 0 or y >= 130) {
  57. return false;
  58. }
  59. if (self.data[x][y] == Wall()) {
  60. // TODO: Should this work?
  61. // self.dir = (-self.dir.1, self.dir.0);
  62. let d: (i32, i32) = self.dir;
  63. self.dir = (-d.1, d.0);
  64. } else {
  65. self.loc = (x, y);
  66. self.data[x][y] = Visited();
  67. }
  68. return true;
  69. }
  70. fn AddObstacle[ref self: Self]() -> bool {
  71. let x: i32 = self.loc.0 + self.dir.0;
  72. let y: i32 = self.loc.1 + self.dir.1;
  73. if (x < 0 or x >= 130 or y < 0 or y >= 130) {
  74. return false;
  75. }
  76. if (self.data[x][y] != Empty()) {
  77. return false;
  78. }
  79. self.data[x][y] = Wall();
  80. return true;
  81. }
  82. fn CountVisited[self: Self]() -> i32 {
  83. var total: i32 = 0;
  84. var y: i32 = 0;
  85. while (y < 130) {
  86. var x: i32 = 0;
  87. while (x < 130) {
  88. if (self.data[x][y] == Visited()) {
  89. ++total;
  90. }
  91. ++x;
  92. }
  93. ++y;
  94. }
  95. return total;
  96. }
  97. var data: array(array(i8, 130), 130);
  98. var loc: (i32, i32);
  99. var dir: (i32, i32);
  100. }