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 }