Guest User

Advent of Code 2021 - Day 3

a guest
Dec 3rd, 2021
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.47 KB | None | 0 0
  1. ///usr/bin/env jbang "$0" "$@" ; exit $?
  2.  
  3.  
  4. import static java.lang.System.*;
  5.  
  6. import java.nio.file.Files;
  7. import java.nio.file.Paths;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10. import java.util.function.Predicate;
  11.  
  12. public class Day3 {
  13.  
  14.  
  15.     static class BitCount {
  16.         final int p;
  17.         final Predicate<Integer> t;
  18.         int c0;
  19.         int c1;
  20.  
  21.         BitCount(final int p) {
  22.             this.p = p;
  23.             t = i -> (i & p) == p;
  24.         }
  25.  
  26.        
  27.         void add(int i) {
  28.             if (t.test(i)) c1++; else c0++;
  29.         }
  30.  
  31.         void combine(BitCount bc) {
  32.             c0 = c0 + bc.c0;
  33.             c1 = c1 + bc.c1;
  34.         }
  35.  
  36.         int epsilon() {
  37.             return c1 < c0 ? p : 0;
  38.         }
  39.  
  40.         int gamma() {
  41.             return c1 > c0 ? p : 0;
  42.         }
  43.  
  44.         Predicate<Integer> oxygen() {
  45.             return c1 >= c0 ? t: t.negate();
  46.         }
  47.  
  48.         Predicate<Integer> scrubber() {
  49.             return oxygen().negate();
  50.         }
  51.     }
  52.  
  53.     static class Count {
  54.         List<Integer> values = new ArrayList<>();
  55.  
  56.         BitCount b12 = new BitCount((int) Math.pow(2, 11));        
  57.         BitCount b11 = new BitCount((int) Math.pow(2, 10));
  58.         BitCount b10 = new BitCount((int) Math.pow(2, 9));        
  59.         BitCount b09 = new BitCount((int) Math.pow(2, 8));
  60.         BitCount b08 = new BitCount((int) Math.pow(2, 7));        
  61.         BitCount b07 = new BitCount((int) Math.pow(2, 6));
  62.         BitCount b06 = new BitCount((int) Math.pow(2, 5));
  63.         BitCount b05 = new BitCount((int) Math.pow(2, 4));
  64.         BitCount b04 = new BitCount((int) Math.pow(2, 3));
  65.         BitCount b03 = new BitCount((int) Math.pow(2, 2));
  66.         BitCount b02 = new BitCount((int) Math.pow(2, 1));
  67.         BitCount b01 = new BitCount((int) Math.pow(2, 0));
  68.  
  69.         void add(int i) {
  70.             b12.add(i);
  71.             b11.add(i);
  72.             b10.add(i);
  73.             b09.add(i);
  74.             b08.add(i);
  75.             b07.add(i);
  76.             b06.add(i);
  77.             b05.add(i);
  78.             b04.add(i);
  79.             b03.add(i);
  80.             b02.add(i);
  81.             b01.add(i);
  82.  
  83.             values.add(i);
  84.         }
  85.  
  86.         void combine(Count c) {
  87.             b12.combine(c.b12);
  88.             b11.combine(c.b11);
  89.             b10.combine(c.b10);
  90.             b09.combine(c.b09);
  91.             b08.combine(c.b08);
  92.             b07.combine(c.b07);
  93.             b06.combine(c.b06);
  94.             b05.combine(c.b05);
  95.             b04.combine(c.b04);
  96.             b03.combine(c.b03);
  97.             b02.combine(c.b02);
  98.             b01.combine(c.b01);
  99.  
  100.             values.addAll(c.values);
  101.         }
  102.  
  103.         int gamma() {
  104.             return 0
  105.                 + b12.gamma()
  106.                 + b11.gamma()
  107.                 + b10.gamma()
  108.                 + b09.gamma()
  109.                 + b08.gamma()
  110.                 + b07.gamma()
  111.                 + b06.gamma()
  112.                 + b05.gamma()
  113.                 + b04.gamma()
  114.                 + b03.gamma()
  115.                 + b02.gamma()
  116.                 + b01.gamma()
  117.                 ;
  118.         }
  119.  
  120.         int epsilon() {
  121.             return 0
  122.                 + b12.epsilon()
  123.                 + b11.epsilon()
  124.                 + b10.epsilon()
  125.                 + b09.epsilon()
  126.                 + b08.epsilon()
  127.                 + b07.epsilon()
  128.                 + b06.epsilon()
  129.                 + b05.epsilon()
  130.                 + b04.epsilon()
  131.                 + b03.epsilon()
  132.                 + b02.epsilon()
  133.                 + b01.epsilon()
  134.                 ;            
  135.         }
  136.        
  137.         int consumption() {
  138.             return epsilon() * gamma();
  139.         }
  140.  
  141.         Predicate<Integer> oxygen(int i) {
  142.             return switch (i) {
  143.                 case 12 -> b12.oxygen();
  144.                 case 11 -> b11.oxygen();
  145.                 case 10 -> b10.oxygen();
  146.                 case 9 -> b09.oxygen();
  147.                 case 8 -> b08.oxygen();
  148.                 case 7 -> b07.oxygen();
  149.                 case 6 -> b06.oxygen();
  150.                 case 5 -> b05.oxygen();
  151.                 case 4 -> b04.oxygen();
  152.                 case 3 -> b03.oxygen();
  153.                 case 2 -> b02.oxygen();
  154.                 case 1 -> b01.oxygen();
  155.                 default -> throw new RuntimeException();
  156.             };
  157.         }
  158.  
  159.         Predicate<Integer> scrubber(int i) {
  160.             return switch (i) {
  161.                 case 12 -> b12.scrubber();
  162.                 case 11 -> b11.scrubber();
  163.                 case 10 -> b10.scrubber();
  164.                 case 9 -> b09.scrubber();
  165.                 case 8 -> b08.scrubber();
  166.                 case 7 -> b07.scrubber();
  167.                 case 6 -> b06.scrubber();
  168.                 case 5 -> b05.scrubber();
  169.                 case 4 -> b04.scrubber();
  170.                 case 3 -> b03.scrubber();
  171.                 case 2 -> b02.scrubber();
  172.                 case 1 -> b01.scrubber();
  173.                 default -> throw new RuntimeException();
  174.             };
  175.         }
  176.  
  177.     }
  178.  
  179.     static List<Integer> lines() {
  180.         try  {
  181.             return Files.readAllLines(Paths.get("input.txt")).stream().map(s -> Integer.parseInt(s, 2)).toList();
  182.         } catch (Exception ex) {
  183.             ex.printStackTrace();
  184.         }
  185.         throw new RuntimeException();
  186.     }
  187.  
  188.  
  189.     static Count count(List<Integer> lines) {
  190.         return lines.stream().collect(Count::new, Count::add, Count::combine);
  191.     }
  192.  
  193.  
  194.     static int oxygen(Count bc) {
  195.         return oxygen(bc, 12);
  196.     }
  197.  
  198.     static int oxygen(Count bc, int b) {
  199.         final Predicate<Integer> filter = bc.oxygen(b);
  200.         final Count nbc = count(bc.values.stream().filter(filter).toList());
  201.  
  202.         if (nbc.values.size() == 1)
  203.             return nbc.values.get(0);
  204.  
  205.         return oxygen(nbc, --b);        
  206.     }
  207.  
  208.     static int scrubber(Count bc) {
  209.         return scrubber(bc, 12);
  210.     }
  211.  
  212.     static int scrubber(Count bc, int b) {
  213.         final Predicate<Integer> filter = bc.scrubber(b);
  214.         final Count nbc = count(bc.values.stream().filter(filter).toList());
  215.  
  216.         if (nbc.values.size() == 1)
  217.             return nbc.values.get(0);
  218.  
  219.         return scrubber(nbc, --b);        
  220.     }
  221.  
  222.    
  223.     public static void main(String... args) {
  224.         final List<Integer> lines = lines();
  225.         final Count bc = count(lines);
  226.         out.println(bc.consumption());
  227.  
  228.         int oxygen = oxygen(bc);
  229.         int scrubber = scrubber(bc);
  230.        
  231.         out.println(oxygen * scrubber);
  232.  
  233.     }
  234. }
  235.  
Advertisement
Add Comment
Please, Sign In to add comment