day15_common.carbon 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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/15
  5. library "day15_common";
  6. import Core library "io";
  7. import library "io_utils";
  8. // TODO: Use a choice type.
  9. class Square {
  10. adapt char;
  11. impl as Core.Copy {
  12. fn Op[self: Self]() -> Self {
  13. return (self as char).(Core.Copy.Op)() as Self;
  14. }
  15. }
  16. impl as Core.EqWith(Square) {
  17. fn Equal[self: Self](other: Self) -> bool {
  18. // TODO: Use a `char` comparison when it's supported.
  19. return (self as u8) == (other as u8);
  20. }
  21. fn NotEqual[self: Self](other: Self) -> bool {
  22. // TODO: Use a `char` comparison when it's supported.
  23. return (self as u8) != (other as u8);
  24. }
  25. }
  26. fn Make(c: CharOrEOF) -> Square {
  27. // TODO: Use `match`.
  28. if (c == '#') { return ('#' as char) as Square; }
  29. if (c == 'O') { return ('O' as char) as Square; }
  30. if (c == '.') { return ('.' as char) as Square; }
  31. if (c == '@') { return ('@' as char) as Square; }
  32. return ('!' as char) as Square;
  33. }
  34. }
  35. let Wall: Square = ('#' as char) as Square;
  36. let Box: Square = ('O' as char) as Square;
  37. let Empty: Square = ('.' as char) as Square;
  38. let Robot: Square = ('@' as char) as Square;
  39. class Grid {
  40. impl as Core.UnformedInit {}
  41. fn Read() -> Grid {
  42. returned var me: Grid;
  43. var y: i32 = 0;
  44. while (y < 50) {
  45. var x: i32 = 0;
  46. while (x < 50) {
  47. me.data[x][y] = Square.Make(ReadChar());
  48. if (me.data[x][y] == Robot) {
  49. me.robot = (x, y);
  50. }
  51. ++x;
  52. }
  53. SkipNewline();
  54. ++y;
  55. }
  56. return var;
  57. }
  58. fn Move[ref self: Self](d: (i32, i32)) {
  59. var distance: i32 = 1;
  60. while (self.data[self.robot.0 + distance * d.0][self.robot.1 + distance * d.1] == Box) {
  61. ++distance;
  62. }
  63. if (self.data[self.robot.0 + distance * d.0][self.robot.1 + distance * d.1] == Empty) {
  64. self.data[self.robot.0][self.robot.1] = Empty;
  65. self.data[self.robot.0 + distance * d.0][self.robot.1 + distance * d.1] = Box;
  66. self.data[self.robot.0 + d.0][self.robot.1 + d.1] = Robot;
  67. self.robot.0 += d.0;
  68. self.robot.1 += d.1;
  69. }
  70. }
  71. fn Print[self: Self]() {
  72. var y: i32 = 0;
  73. while (y < 50) {
  74. var x: i32 = 0;
  75. while (x < 50) {
  76. Core.PrintChar(self.data[x][y] as char);
  77. ++x;
  78. }
  79. Core.PrintChar('\n');
  80. ++y;
  81. }
  82. Core.PrintChar('\n');
  83. }
  84. fn Signature[self: Self]() -> i32 {
  85. var s: i32 = 0;
  86. var y: i32 = 0;
  87. while (y < 50) {
  88. var x: i32 = 0;
  89. while (x < 50) {
  90. if (self.data[x][y] == Box) {
  91. s += y * 100 + x;
  92. }
  93. ++x;
  94. }
  95. ++y;
  96. }
  97. return s;
  98. }
  99. var data: array(array(Square, 50), 50);
  100. var robot: (i32, i32);
  101. }
  102. fn ReadAndExecuteActions(ref g: Grid) {
  103. while (true) {
  104. var m: CharOrEOF = ReadChar();
  105. // To watch the progress, uncomment the following:
  106. // g.Print();
  107. // Core.PrintChar(((m as i32) as u8) as char);
  108. // Core.PrintChar('\n');
  109. // TODO: Use `match` once it's available.
  110. if (m == '^') {
  111. g.Move((0, -1));
  112. } else if (m == '<') {
  113. g.Move((-1, 0));
  114. } else if (m == '>') {
  115. g.Move((1, 0));
  116. } else if (m == 'v') {
  117. g.Move((0, 1));
  118. } else if (m == CharOrEOF.EOF()) {
  119. return;
  120. }
  121. }
  122. }