| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
- // Exceptions. See /LICENSE for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- // https://adventofcode.com/2024/day/15
- library "day15_common";
- import Core library "io";
- import library "io_utils";
- // TODO: Use a choice type.
- class Square {
- adapt char;
- impl as Core.Copy {
- fn Op[self: Self]() -> Self {
- return (self as char).(Core.Copy.Op)() as Self;
- }
- }
- impl as Core.EqWith(Square) {
- fn Equal[self: Self](other: Self) -> bool {
- // TODO: Use a `char` comparison when it's supported.
- return (self as u8) == (other as u8);
- }
- fn NotEqual[self: Self](other: Self) -> bool {
- // TODO: Use a `char` comparison when it's supported.
- return (self as u8) != (other as u8);
- }
- }
- fn Make(c: CharOrEOF) -> Square {
- // TODO: Use `match`.
- if (c == '#') { return ('#' as char) as Square; }
- if (c == 'O') { return ('O' as char) as Square; }
- if (c == '.') { return ('.' as char) as Square; }
- if (c == '@') { return ('@' as char) as Square; }
- return ('!' as char) as Square;
- }
- }
- let Wall: Square = ('#' as char) as Square;
- let Box: Square = ('O' as char) as Square;
- let Empty: Square = ('.' as char) as Square;
- let Robot: Square = ('@' as char) as Square;
- class Grid {
- impl as Core.UnformedInit {}
- fn Read() -> Grid {
- returned var me: Grid;
- var y: i32 = 0;
- while (y < 50) {
- var x: i32 = 0;
- while (x < 50) {
- me.data[x][y] = Square.Make(ReadChar());
- if (me.data[x][y] == Robot) {
- me.robot = (x, y);
- }
- ++x;
- }
- SkipNewline();
- ++y;
- }
- return var;
- }
- fn Move[ref self: Self](d: (i32, i32)) {
- var distance: i32 = 1;
- while (self.data[self.robot.0 + distance * d.0][self.robot.1 + distance * d.1] == Box) {
- ++distance;
- }
- if (self.data[self.robot.0 + distance * d.0][self.robot.1 + distance * d.1] == Empty) {
- self.data[self.robot.0][self.robot.1] = Empty;
- self.data[self.robot.0 + distance * d.0][self.robot.1 + distance * d.1] = Box;
- self.data[self.robot.0 + d.0][self.robot.1 + d.1] = Robot;
- self.robot.0 += d.0;
- self.robot.1 += d.1;
- }
- }
- fn Print[self: Self]() {
- var y: i32 = 0;
- while (y < 50) {
- var x: i32 = 0;
- while (x < 50) {
- Core.PrintChar(self.data[x][y] as char);
- ++x;
- }
- Core.PrintChar('\n');
- ++y;
- }
- Core.PrintChar('\n');
- }
- fn Signature[self: Self]() -> i32 {
- var s: i32 = 0;
- var y: i32 = 0;
- while (y < 50) {
- var x: i32 = 0;
- while (x < 50) {
- if (self.data[x][y] == Box) {
- s += y * 100 + x;
- }
- ++x;
- }
- ++y;
- }
- return s;
- }
- var data: array(array(Square, 50), 50);
- var robot: (i32, i32);
- }
- fn ReadAndExecuteActions(ref g: Grid) {
- while (true) {
- var m: CharOrEOF = ReadChar();
- // To watch the progress, uncomment the following:
- // g.Print();
- // Core.PrintChar(((m as i32) as u8) as char);
- // Core.PrintChar('\n');
- // TODO: Use `match` once it's available.
- if (m == '^') {
- g.Move((0, -1));
- } else if (m == '<') {
- g.Move((-1, 0));
- } else if (m == '>') {
- g.Move((1, 0));
- } else if (m == 'v') {
- g.Move((0, 1));
- } else if (m == CharOrEOF.EOF()) {
- return;
- }
- }
- }
|