Skip to content
Snippets Groups Projects
Commit 000fb434 authored by Christopher Bohn's avatar Christopher Bohn :thinking:
Browse files

Day 3 complete

parent 24e81aea
Branches
No related tags found
No related merge requests found
......@@ -10,3 +10,8 @@ get to use Java's new multiline strings.
Can we follow instructions? Yes we can. This isn't a particularly challenging
problem. Beside using Java's new Records, I'm also using Java's new style of
switch statements.
## Day 3
My CSCE 231 students should be able to do this problem in their sleep -- bit
masks are cool.
\ No newline at end of file
package edu.unl.cse.bohn.year2021;
import edu.unl.cse.bohn.Puzzle;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiPredicate;
import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class Day3 extends Puzzle {
private List<Integer> diagnosticReports;
private int reportLength;
private int[] ones, zeroes;
public Day3() {
day = 3;
sampleData = """
00100
11110
10110
10111
10101
01111
00111
11100
10000
11001
00010
01010""";
isProductionReady = true;
}
@Override
public int computePart1(List<String> data) {
diagnosticReports = data.stream().map(report -> Integer.parseInt(report, 2)).collect(Collectors.toList());
reportLength = data.get(0).length();
ones = new int[]{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0};
zeroes = new int[]{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0};
for (int report : diagnosticReports) {
for (int bit = 0; bit < reportLength; bit++) {
if ((report & (1 << bit)) == 0) {
zeroes[bit]++;
} else {
ones[bit]++;
}
}
}
int gamma = 0;
int epsilon = 0;
for (int bit = 0; bit < reportLength; bit++) {
if (ones[bit] > zeroes[bit]) {
gamma |= (1 << bit);
} else {
epsilon |= (1 << bit);
}
}
return gamma * epsilon;
}
private Integer filterReports(int[] onesArray, int[] zeroesArray, BiPredicate<Integer, Integer> predicate) {
List<Integer> workingSet = new ArrayList<>(diagnosticReports);
int bit = reportLength - 1;
int numberOfOnes = onesArray[bit];
int numberOfZeroes = zeroesArray[bit];
while (workingSet.size() > 1) {
int mask = 1 << bit;
if (predicate.test(numberOfOnes, numberOfZeroes)) {
workingSet = workingSet.stream()
.filter(report -> (report & mask) != 0)
.collect(Collectors.toList());
} else {
workingSet = workingSet.stream()
.filter(report -> (report & mask) == 0)
.collect(Collectors.toList());
}
bit--;
// Need to re-count the ones and zeroes since the old counts are now wrong
if (bit >= 0) {
numberOfOnes = numberOfZeroes = 0;
for (int report : workingSet) {
if ((report & (1 << bit)) == 0) {
numberOfZeroes++;
} else {
numberOfOnes++;
}
}
}
}
return workingSet.get(0);
}
@Override
public int computePart2(List<String> data) {
Integer oxygenGeneratorRating = filterReports(ones, zeroes,
(numberOfOnes, numberOfZeroes) -> numberOfOnes >= numberOfZeroes);
Integer co2ScrubberRating = filterReports(ones, zeroes,
(numberOfOnes, numberOfZeroes) -> numberOfOnes < numberOfZeroes);
return oxygenGeneratorRating * co2ScrubberRating;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment