aoc2024

Advent of Code 2024
Log | Files | Refs | README

day15_pt1.java (3592B)


      1 import java.nio.file.Files;
      2 import java.nio.file.Path;
      3 import java.io.IOException;
      4 import java.util.*;
      5 import java.util.stream.*;
      6 import java.util.regex.*;
      7 
      8 
      9 class day15_pt1 {
     10   record Point(int x, int y) {
     11     Point add(Vec v) {
     12       return new Point(this.x + v.x, this.y + v.y);
     13     }
     14   }
     15   record Vec(int x, int y) {}
     16   enum Direction{
     17     North('^'),East('>'),South('v'),West('<');
     18     char c;
     19     Direction(char c) { this.c = c; }
     20     
     21     Vec unitVec() {
     22       return switch (this) {
     23         case North -> new Vec(0, -1);
     24         case East -> new Vec(1, 0)  ;
     25         case South -> new Vec(0, 1);
     26         case West -> new Vec(-1, 0);
     27       };
     28     }
     29     static Direction from(char c) {
     30       for (var d: Direction.values()) {
     31         if (d.c == c) return d;
     32       }
     33       throw new IllegalArgumentException("unrecognised direction %c".formatted(c));
     34     }
     35   }
     36   public static void main(String[] args) throws IOException {
     37     var input = Files.readAllLines(Path.of(args[0]));
     38     var spl = input.indexOf("");
     39     var grid = input.subList(0, spl);
     40     var inst = input.subList(spl+1, input.size()).stream().collect(Collectors.joining(""));
     41     var height = grid.size();
     42     var width = grid.get(0).length();
     43     Point robotPos = null;
     44     var boxes = new HashSet<Point>();
     45     var walls = new HashSet<Point>();
     46     for (var y=0;y<height;y++) {
     47       for (var x=0;x<width;x++) {
     48         var p = new Point(x, y);
     49         var val = gv(grid, p);
     50         if (val == '@') {
     51           robotPos = p; 
     52         } else if (val == 'O') {
     53           boxes.add(p);
     54         } else if (val == '#') {
     55           walls.add(p);
     56         }
     57       }
     58     }
     59     //System.out.printf("RobotPos: %s\n", robotPos);
     60     for (var ch : inst.chars().toArray()) {
     61       var d = Direction.from((char)ch);
     62       var np = robotPos.add(d.unitVec());
     63       if (walls.contains(np)) {
     64         // do nothing
     65       } else if (boxes.contains(np)) {
     66         moveBox(np, d, boxes, walls);
     67         if (boxes.contains(np)) {
     68           // do nothing
     69         } else {
     70           robotPos = np;
     71         }
     72       } else {
     73         robotPos = np;
     74       }
     75       // Debugging...
     76       // System.out.printf("instruction: %c\n", ch);
     77       // for (var y=0;y<height;y++) {
     78       //   for (var x=0;x<width;x++) {
     79       //     var p = new Point(x, y);
     80       //     if (walls.contains(p)) {
     81       //       System.out.print('#');
     82       //     } else if (boxes.contains(p)) {
     83       //       System.out.print('O');
     84       //     } else if (p.equals(robotPos)) {
     85       //       System.out.print('@');
     86       //     } else {
     87       //       System.out.print('.');
     88       //     }
     89       //   }
     90       //   System.out.print('\n');
     91       // }
     92       // System.out.print('\n');
     93     }
     94 
     95     var score = 0;
     96     var res = boxes.stream().mapToInt(b -> 100 * b.y + b.x).sum();
     97     System.out.printf("Day 15 pt1: %d\n", res);
     98   }
     99 
    100   static void moveBox(Point box, Direction d, HashSet<Point> boxes, HashSet<Point> walls) {
    101     var np = box.add(d.unitVec());
    102     if (walls.contains(np)) {
    103       return;
    104     } else if (boxes.contains(np)) {
    105       moveBox(np, d, boxes, walls);
    106       if (boxes.contains(np)) {
    107         // didn't move it,
    108         return;
    109       } else {
    110         boxes.remove(box);
    111         boxes.add(np);
    112       }
    113     } else {
    114       boxes.remove(box);
    115       boxes.add(np);
    116     }
    117   }
    118 
    119   static int gv(List<String> grid, Point p) {
    120     var height = grid.size();
    121     if (p.y < 0 || p.y >= height) return '#'; // treat out of bounds as a wall
    122     var width = grid.get(0).length();
    123     if (p.x < 0 || p.x >= width) return '#';
    124     return grid.get(p.y).charAt(p.x);
    125   }
    126 }