day6_common.carbon 2.4 KB

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