1
+ package com .macasaet ;
2
+
3
+ import java .util .ArrayList ;
4
+ import java .util .List ;
5
+ import java .util .stream .Collectors ;
6
+ import java .util .stream .Stream ;
7
+ import java .util .stream .StreamSupport ;
8
+
9
+ import org .junit .jupiter .api .Test ;
10
+
11
+ /**
12
+ * --- Day 3: Binary Diagnostic ---
13
+ */
14
+ public class Day03 {
15
+
16
+ /**
17
+ * @return "a list of binary numbers which, when decoded properly, can tell you many useful things about the
18
+ * conditions of the submarine"
19
+ */
20
+ protected Stream <byte []> getDiagnosticReport () {
21
+ return StreamSupport
22
+ .stream (new LineSpliterator ("day-03.txt" ),
23
+ false )
24
+ .map (string -> {
25
+ final var chars = string .toCharArray ();
26
+ final var bits = new byte [chars .length ];
27
+ for (int i = chars .length ; --i >= 0 ; bits [i ] = chars [i ] == '0' ? (byte ) 0 : (byte ) 1 ) ;
28
+ return bits ;
29
+ });
30
+ }
31
+
32
+ protected int toUnsignedInt (final byte [] bits ) {
33
+ int result = 0 ;
34
+ for (int i = bits .length ; --i >= 0 ; result += bits [i ] * Math .pow (2 , bits .length - i - 1 )) ;
35
+ return result ;
36
+ }
37
+
38
+ @ Test
39
+ public final void part1 () {
40
+ final var list = getDiagnosticReport ().collect (Collectors .toList ());
41
+ final int width = list .get (0 ).length ;
42
+ final int [] zeroCounts = new int [width ];
43
+ for (int i = zeroCounts .length ; --i >= 0 ; zeroCounts [i ] = 0 ) ;
44
+ final int [] oneCounts = new int [width ];
45
+ for (int i = oneCounts .length ; --i >= 0 ; oneCounts [i ] = 0 ) ;
46
+ for (final var array : list ) {
47
+ for (int j = 0 ; j < width ; j ++) {
48
+ if (array [j ] == 0 ) {
49
+ zeroCounts [j ] += 1 ;
50
+ } else {
51
+ oneCounts [j ] += 1 ;
52
+ }
53
+ }
54
+ }
55
+ final byte [] gammaArray = new byte [width ];
56
+ final byte [] epsilonArray = new byte [width ];
57
+ for (int i = gammaArray .length ; --i >= 0 ; ) {
58
+ gammaArray [i ] = zeroCounts [i ] > oneCounts [i ] ? (byte ) 0 : (byte ) 1 ;
59
+ epsilonArray [i ] = zeroCounts [i ] > oneCounts [i ] ? (byte ) 1 : (byte ) 0 ;
60
+ }
61
+
62
+ final int gammaRate = toUnsignedInt (gammaArray );
63
+ final int epsilonRate = toUnsignedInt (epsilonArray );
64
+ System .out .println ("Part 1: " + (gammaRate * epsilonRate ));
65
+ }
66
+
67
+ @ Test
68
+ public final void part2 () {
69
+ final var list = getDiagnosticReport ().collect (Collectors .toList ());
70
+ final int width = list .get (0 ).length ;
71
+ List <byte []> oxygenCandidates = new ArrayList <>(list );
72
+ for (int i = 0 ; i < width && oxygenCandidates .size () > 1 ; i ++) {
73
+ int zeros = 0 ;
74
+ int ones = 0 ;
75
+ for (final var value : oxygenCandidates ) {
76
+ if (value [i ] == 0 ) {
77
+ zeros ++;
78
+ } else {
79
+ ones ++;
80
+ }
81
+ }
82
+ final int index = i ;
83
+ if (ones >= zeros ) {
84
+ oxygenCandidates = oxygenCandidates .stream ().filter (value -> value [index ] == 1 ).collect (Collectors .toList ());
85
+ } else {
86
+ oxygenCandidates = oxygenCandidates .stream ().filter (value -> value [index ] == 0 ).collect (Collectors .toList ());
87
+ }
88
+ }
89
+ if (oxygenCandidates .size () > 1 ) {
90
+ throw new IllegalStateException ("Too many oxygen candidates" );
91
+ }
92
+ List <byte []> co2Candidates = new ArrayList <>(list );
93
+ for (int i = 0 ; i < width && co2Candidates .size () > 1 ; i ++) {
94
+ int zeros = 0 ;
95
+ int ones = 0 ;
96
+ for (final var value : co2Candidates ) {
97
+ if (value [i ] == 0 ) {
98
+ zeros ++;
99
+ } else {
100
+ ones ++;
101
+ }
102
+ }
103
+ final int index = i ;
104
+ if (zeros <= ones ) {
105
+ co2Candidates = co2Candidates .stream ().filter (value -> value [index ] == 0 ).collect (Collectors .toList ());
106
+ } else {
107
+ co2Candidates = co2Candidates .stream ().filter (value -> value [index ] == 1 ).collect (Collectors .toList ());
108
+ }
109
+ }
110
+ if (co2Candidates .size () > 1 ) {
111
+ throw new IllegalStateException ("Too many CO2 candidates" );
112
+ }
113
+ final byte [] oxyArray = oxygenCandidates .get (0 );
114
+ final byte [] co2Array = co2Candidates .get (0 );
115
+ final int oxygenGeneratorRating = toUnsignedInt (oxyArray );
116
+ final int co2ScrubberRating = toUnsignedInt (co2Array );
117
+ System .out .println ("Part 2: " + (oxygenGeneratorRating * co2ScrubberRating ));
118
+ }
119
+
120
+ }
0 commit comments