Guest User

Untitled

a guest
Dec 13th, 2021
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.06 KB | None | 0 0
  1. package fr.ela.aoc2021;
  2.  
  3. import java.nio.file.Path;
  4. import java.util.ArrayList;
  5. import java.util.Arrays;
  6. import java.util.HashSet;
  7. import java.util.List;
  8. import java.util.Map;
  9. import java.util.function.BiFunction;
  10. import java.util.function.BiPredicate;
  11. import java.util.regex.Matcher;
  12. import java.util.regex.Pattern;
  13. import java.util.stream.Collectors;
  14.  
  15. public class D13 extends AoC {
  16.  
  17.     private static final Pattern FOLD_PATTERN = Pattern.compile("fold along ([xy])=([0-9]+)");
  18.  
  19.     @Override
  20.     public void run() {
  21.         process(getTestInputPath(), "Test");
  22.         process(getInputPath(), "Real");
  23.     }
  24.  
  25.     public void process(Path input, String name) {
  26.         Map<Boolean, List<String>> linesSorted = stream(input)
  27.                 .filter(s -> !s.isEmpty())
  28.                 .collect(Collectors.groupingBy(l -> l.charAt(0) == 'f'));
  29.  
  30.         Grid grid = new Grid();
  31.         linesSorted.get(Boolean.FALSE).stream()
  32.                 .map(Point::fromLine).forEach(grid::add);
  33.         List<FoldingInstruction> folds = linesSorted.get(Boolean.TRUE).stream()
  34.                 .map(FoldingInstruction::fromLine).collect(Collectors.toList());
  35.  
  36.         grid.fold(folds.get(0));
  37.  
  38.         System.out.println(name + " grid has " + grid.size() + " visible dots after first fold");
  39.  
  40.         folds.stream().skip(1).forEach(grid::fold);
  41.  
  42.         System.out.println(name + " Grid after all folding instructions : ");
  43.         System.out.println(grid);
  44.  
  45.     }
  46.  
  47.  
  48.     public class Grid extends HashSet<Point> {
  49.  
  50.         public void fold(FoldingInstruction fold) {
  51.             List<Point> toRemove = stream().filter(fold::moves).collect(Collectors.toList());
  52.             toRemove.forEach(this::remove);
  53.             toRemove.stream().map(fold::fold).forEach(this::add);
  54.         }
  55.  
  56.         public String toString() {
  57.             int maxCol = stream().mapToInt(p -> p.col).max().orElseThrow() + 1;
  58.             int maxRow = stream().mapToInt(p -> p.row).max().orElseThrow() + 1;
  59.  
  60.             List<char[]> s = new ArrayList<>();
  61.             for (int row = 0; row < maxRow + 1; row++) {
  62.                 char[] chars = new char[maxCol + 1];
  63.                 Arrays.fill(chars, '.');
  64.                 s.add(chars);
  65.             }
  66.             for (Point p : this) {
  67.                 s.get(p.row)[p.col] = '#';
  68.             }
  69.             StringBuilder sb = new StringBuilder("----------\n");
  70.             for (int i = 0; i < s.size(); i++) {
  71.                 sb.append(i).append("\t").append(new String(s.get(i))).append("\n");
  72.             }
  73.             return sb.toString();
  74.         }
  75.  
  76.     }
  77.  
  78.     public enum Direction {
  79.         X((p, value) -> p.col > value,
  80.                 (p, value) -> new Point(p.row, 2 * value - p.col)),
  81.         Y((p, value) -> p.row > value,
  82.                 (p, value) -> new Point(2 * value - p.row, p.col));
  83.  
  84.         final BiFunction<Point, Integer, Point> foldAlong;
  85.         final BiPredicate<Point, Integer> folds;
  86.  
  87.         Direction(BiPredicate<Point, Integer> folds, BiFunction<Point, Integer, Point> foldAlong) {
  88.             this.folds = folds;
  89.             this.foldAlong = foldAlong;
  90.         }
  91.     }
  92.  
  93.     public record FoldingInstruction(Direction axis, int value) {
  94.         public static FoldingInstruction fromLine(String line) {
  95.             Matcher matcher = FOLD_PATTERN.matcher(line);
  96.             if (matcher.matches()) {
  97.                 Direction d = matcher.group(1).charAt(0) == 'x' ? Direction.X : Direction.Y;
  98.                 return new FoldingInstruction(d, Integer.parseInt(matcher.group(2)));
  99.             }
  100.             throw new IllegalArgumentException(line);
  101.         }
  102.  
  103.         public boolean moves(Point p) {
  104.             return axis.folds.test(p, value);
  105.         }
  106.  
  107.         public Point fold(Point p) {
  108.             return axis.foldAlong.apply(p, value);
  109.         }
  110.     }
  111.  
  112.     record Point(int row, int col) {
  113.         public static Point fromLine(String line) {
  114.             String[] coords = line.split(",");
  115.             return new Point(Integer.parseInt(coords[1]), Integer.parseInt(coords[0]));
  116.         }
  117.     }
  118.  
  119. }
  120.  
Advertisement
Add Comment
Please, Sign In to add comment