OrangoMango

Day 10 AdventOfCode 2023

Dec 10th, 2023
498
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.89 KB | None | 0 0
  1. import java.util.*;
  2.  
  3. public class Day10{
  4.     private static class Pipe{
  5.         private int directions; // 4bit: N E S W
  6.         private boolean visited;
  7.         private String type;
  8.         private int x, y;
  9.         private int distance = 0;
  10.  
  11.         public Pipe(int x, int y, String type){
  12.             this.x = x;
  13.             this.y = y;
  14.             this.type = type;
  15.             if (this.type.equals("|")){
  16.                 this.directions = 10;
  17.             } else if (this.type.equals("-")){
  18.                 this.directions = 5;
  19.             } else if (this.type.equals("L")){
  20.                 this.directions = 12;
  21.             } else if (this.type.equals("J")){
  22.                 this.directions = 9;
  23.             } else if (this.type.equals("7")){
  24.                 this.directions = 3;
  25.             } else if (this.type.equals("F")){
  26.                 this.directions = 6;
  27.             }
  28.         }
  29.  
  30.         public void applyStartConnections(Pipe[][] map){
  31.             if (this.type.equals("S")){
  32.                 Pipe p1 = getPipeAt(map, this.x, this.y-1);
  33.                 Pipe p2 = getPipeAt(map, this.x, this.y+1);
  34.                 Pipe p3 = getPipeAt(map, this.x-1, this.y);
  35.                 Pipe p4 = getPipeAt(map, this.x+1, this.y);
  36.                 if (p1 != null && (p1.type.equals("|") || p1.type.equals("7") || p1.type.equals("F"))){
  37.                     this.directions |= 8;
  38.                 }
  39.                 if (p2 != null && (p2.type.equals("|") || p2.type.equals("L") || p2.type.equals("J"))){
  40.                     this.directions |= 2;
  41.                 }
  42.                 if (p3 != null && (p3.type.equals("-") || p3.type.equals("L") || p3.type.equals("F"))){
  43.                     this.directions |= 1;
  44.                 }
  45.                 if (p4 != null && (p4.type.equals("-") || p4.type.equals("J") || p4.type.equals("7"))){
  46.                     this.directions |= 4;
  47.                 }
  48.             }
  49.         }
  50.  
  51.         public static Pipe getPipeAt(Pipe[][] map, int x, int y){
  52.             if (x >= 0 && y >= 0 && x < map.length && y < map[0].length){
  53.                 return map[x][y];
  54.             } else return null;
  55.         }
  56.  
  57.         public static void setPipeAt(Pipe[][] map, Pipe pipe){
  58.             if (pipe.x >= 0 && pipe.y >= 0 && pipe.x < map.length && pipe.y < map[0].length){
  59.                 map[pipe.x][pipe.y] = pipe;
  60.             }
  61.         }
  62.     }
  63.  
  64.     public static void main(String[] args){
  65.         List<String> lines = InputManager.getInput("../input/input10.txt");
  66.  
  67.         Pipe[][] map = new Pipe[lines.get(0).length()][lines.size()];
  68.         int startX = 0, startY = 0;
  69.  
  70.         for (int y = 0; y < lines.size(); y++){
  71.             String line = lines.get(y);
  72.             for (int x = 0; x < line.length(); x++){
  73.                 String p = String.valueOf(line.charAt(x));
  74.                 if (p.equals("S")){
  75.                     startX = x;
  76.                     startY = y;
  77.                 }
  78.                 map[x][y] = new Pipe(x, y, p);
  79.             }
  80.         }
  81.  
  82.         map[startX][startY].applyStartConnections(map);
  83.  
  84.         // Calculate distance
  85.         walk(map, startX, startY);
  86.         int maxDistance = 0;
  87.         for (int x = 0; x < map.length; x++){
  88.             for (int y = 0; y < map[x].length; y++){
  89.                 Pipe pipe = map[x][y];
  90.                 if (!pipe.type.equals(".") && pipe.distance > maxDistance){
  91.                     maxDistance = pipe.distance;
  92.                 }
  93.             }
  94.         }
  95.  
  96.         System.out.println(maxDistance);
  97.  
  98.         // Delete the pipes that are not in the mainloop
  99.         for (int y = 0; y < map[0].length; y++){
  100.             for (int x = 0; x < map.length; x++){
  101.                 Pipe pipe = map[x][y];
  102.                 if (!pipe.visited){
  103.                     map[x][y] = new Pipe(x, y, ".");
  104.                 }
  105.             }
  106.         }
  107.  
  108.         // Calculate the area
  109.         Pipe[][] zoomed = zoom(map); // x2 zoom
  110.         boolean[][] outside = new boolean[zoomed.length][zoomed[0].length];
  111.         makeOutsideMap(zoomed, 0, 0, outside);
  112.  
  113.         int area = 0;
  114.         for (int y = 0; y < outside[0].length; y++){
  115.             for (int x = 0; x < outside.length; x++){
  116.                 if (!(outside[x][y] && zoomed[x][y].type.equals("."))){ // it's inside and it's not a pipe
  117.                     Pipe pipe = map[(x-1)/2][(y-1)/2];
  118.                     if (pipe.type.equals(".") && x % 2 == 1 && y % 2 == 1){
  119.                         area++;
  120.                     }
  121.                 }
  122.             }
  123.         }
  124.  
  125.         System.out.println(area);
  126.     }
  127.  
  128.     private static void makeOutsideMap(Pipe[][] zoomed, int x, int y, boolean[][] outside){
  129.         Pipe pipe = Pipe.getPipeAt(zoomed, x, y);
  130.         List<Pipe> pipes = new ArrayList<>();
  131.         if (pipe != null){
  132.             pipes.add(pipe);
  133.             while (pipes.size() != 0){
  134.                 Pipe p = pipes.remove(0);
  135.                 if (p.visited) continue;
  136.                 p.visited = true;
  137.                 outside[p.x][p.y] = true;
  138.  
  139.                 Pipe n = Pipe.getPipeAt(zoomed, p.x, p.y-1);
  140.                 Pipe e = Pipe.getPipeAt(zoomed, p.x+1, p.y);
  141.                 Pipe s = Pipe.getPipeAt(zoomed, p.x, p.y+1);
  142.                 Pipe w = Pipe.getPipeAt(zoomed, p.x-1, p.y);
  143.                 if (n != null && n.type.equals(".") && !n.visited){
  144.                     pipes.add(n);
  145.                 }
  146.                 if (e != null && e.type.equals(".") && !e.visited){
  147.                     pipes.add(e);
  148.                 }
  149.                 if (s != null && s.type.equals(".") && !s.visited){
  150.                     pipes.add(s);
  151.                 }
  152.                 if (w != null && w.type.equals(".") && !w.visited){
  153.                     pipes.add(w);
  154.                 }
  155.             }
  156.         }
  157.     }
  158.  
  159.     private static Pipe[][] zoom(Pipe[][] map){
  160.         Pipe[][] output = new Pipe[map.length*2+1][map[0].length*2+1];
  161.         for (int x = 0; x < map.length; x++){
  162.             for (int y = 0; y < map[x].length; y++){
  163.                 int px = x*2+1;
  164.                 int py = y*2+1;
  165.                 if (!map[x][y].type.equals(".")){
  166.                     output[px][py] = new Pipe(px, py, map[x][y].type);
  167.                     if (map[x][y].type.equals("|")){
  168.                         Pipe.setPipeAt(output, new Pipe(px, py-1, "|"));
  169.                         Pipe.setPipeAt(output, new Pipe(px, py+1, "|"));
  170.                     } else if (map[x][y].type.equals("-")){
  171.                         Pipe.setPipeAt(output, new Pipe(px-1, py, "-"));
  172.                         Pipe.setPipeAt(output, new Pipe(px+1, py, "-"));
  173.                     } else if (map[x][y].type.equals("L")){
  174.                         Pipe.setPipeAt(output, new Pipe(px, py-1, "|"));
  175.                         Pipe.setPipeAt(output, new Pipe(px+1, py, "-"));
  176.                     } else if (map[x][y].type.equals("J")){
  177.                         Pipe.setPipeAt(output, new Pipe(px, py-1, "|"));
  178.                         Pipe.setPipeAt(output, new Pipe(px-1, py, "-"));
  179.                     } else if (map[x][y].type.equals("7")){
  180.                         Pipe.setPipeAt(output, new Pipe(px, py+1, "|"));
  181.                         Pipe.setPipeAt(output, new Pipe(px-1, py, "-"));
  182.                     } else if (map[x][y].type.equals("F")){
  183.                         Pipe.setPipeAt(output, new Pipe(px, py+1, "|"));
  184.                         Pipe.setPipeAt(output, new Pipe(px+1, py, "-"));
  185.                     }
  186.                 }
  187.             }
  188.         }
  189.  
  190.         for (int x = 0; x < output.length; x++){
  191.             for (int y = 0; y < output[x].length; y++){
  192.                 if (output[x][y] == null){ // Null pipes are empty tiles ('.')
  193.                     output[x][y] = new Pipe(x, y, ".");
  194.                 }
  195.             }
  196.         }
  197.  
  198.         return output;
  199.     }
  200.  
  201.     private static void walk(Pipe[][] map, int x, int y){
  202.         Pipe pipe = Pipe.getPipeAt(map, x, y);
  203.         List<Pipe> pipes = new ArrayList<>();
  204.         if (pipe != null && !pipe.type.equals(".")){
  205.             pipes.add(pipe);
  206.             while (pipes.size() != 0){
  207.                 Pipe p = pipes.remove(0);
  208.                 if (p.visited) continue;
  209.                 p.visited = true;
  210.  
  211.                 Pipe n = Pipe.getPipeAt(map, p.x, p.y-1);
  212.                 Pipe e = Pipe.getPipeAt(map, p.x+1, p.y);
  213.                 Pipe s = Pipe.getPipeAt(map, p.x, p.y+1);
  214.                 Pipe w = Pipe.getPipeAt(map, p.x-1, p.y);
  215.                 if ((p.directions & 8) == 8 && !n.visited){
  216.                     n.distance = p.distance+1;
  217.                     pipes.add(n);
  218.                 }
  219.                 if ((p.directions & 4) == 4 && !e.visited){
  220.                     e.distance = p.distance+1;
  221.                     pipes.add(e);
  222.                 }
  223.                 if ((p.directions & 2) == 2 && !s.visited){
  224.                     s.distance = p.distance+1;
  225.                     pipes.add(s);
  226.                 }
  227.                 if ((p.directions & 1) == 1 && !w.visited){
  228.                     w.distance = p.distance+1;
  229.                     pipes.add(w);
  230.                 }
  231.             }
  232.         }
  233.     }
  234. }
Add Comment
Please, Sign In to add comment