Skip to content

Commit de8df96

Browse files
committed
Implement Day 4 solution
1 parent 3fbc3f7 commit de8df96

File tree

1 file changed

+50
-31
lines changed
  • src/main/java/com/sbaars/adventofcode/year16/days

1 file changed

+50
-31
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
package com.sbaars.adventofcode.year16.days;
22

33
import com.sbaars.adventofcode.year16.Day2016;
4-
import java.util.Map;
5-
import java.util.Arrays;
4+
import java.util.*;
65
import java.util.stream.Collectors;
76

87
public class Day4 extends Day2016 {
9-
108
public Day4() {
119
super(4);
1210
}
@@ -15,44 +13,65 @@ public static void main(String[] args) {
1513
new Day4().printParts();
1614
}
1715

18-
private boolean isRealRoom(String name, String checksum) {
19-
// Remove dashes and count letter frequencies
20-
Map<Character, Long> freq = name.replace("-", "").chars()
21-
.mapToObj(c -> (char) c)
22-
.collect(Collectors.groupingBy(c -> c, Collectors.counting()));
23-
24-
// Get top 5 most common letters, breaking ties alphabetically
25-
String calculatedChecksum = freq.entrySet().stream()
26-
.sorted((a, b) -> {
27-
int freqCompare = b.getValue().compareTo(a.getValue());
28-
return freqCompare != 0 ? freqCompare : a.getKey().compareTo(b.getKey());
29-
})
30-
.limit(5)
31-
.map(e -> String.valueOf(e.getKey()))
32-
.collect(Collectors.joining());
16+
private record Room(String name, int sectorId, String checksum) {
17+
public boolean isReal() {
18+
Map<Character, Integer> freq = new HashMap<>();
19+
for (char c : name.replaceAll("-", "").toCharArray()) {
20+
freq.merge(c, 1, Integer::sum);
21+
}
22+
23+
String calculatedChecksum = freq.entrySet().stream()
24+
.sorted((a, b) -> {
25+
int comp = b.getValue().compareTo(a.getValue());
26+
return comp != 0 ? comp : a.getKey().compareTo(b.getKey());
27+
})
28+
.limit(5)
29+
.map(e -> String.valueOf(e.getKey()))
30+
.collect(Collectors.joining());
31+
32+
return calculatedChecksum.equals(checksum);
33+
}
34+
35+
public String decrypt() {
36+
StringBuilder result = new StringBuilder();
37+
for (char c : name.toCharArray()) {
38+
if (c == '-') {
39+
result.append(' ');
40+
} else {
41+
int shifted = ((c - 'a' + sectorId) % 26) + 'a';
42+
result.append((char) shifted);
43+
}
44+
}
45+
return result.toString();
46+
}
47+
}
3348

34-
return calculatedChecksum.equals(checksum);
49+
private Room parseRoom(String line) {
50+
String[] parts = line.split("\\[");
51+
String checksum = parts[1].substring(0, parts[1].length() - 1);
52+
String[] nameParts = parts[0].split("-(?=\\d)");
53+
String name = nameParts[0];
54+
int sectorId = Integer.parseInt(nameParts[1]);
55+
return new Room(name, sectorId, checksum);
3556
}
3657

3758
@Override
3859
public Object part1() {
3960
return dayStream()
40-
.map(line -> {
41-
// Parse room string into components
42-
int checksumStart = line.indexOf('[');
43-
String checksum = line.substring(checksumStart + 1, line.length() - 1);
44-
String[] parts = line.substring(0, checksumStart).split("-");
45-
int sectorId = Integer.parseInt(parts[parts.length - 1]);
46-
String name = String.join("-", Arrays.copyOf(parts, parts.length - 1));
47-
48-
return isRealRoom(name, checksum) ? sectorId : 0;
49-
})
50-
.mapToInt(Integer::intValue)
61+
.map(this::parseRoom)
62+
.filter(Room::isReal)
63+
.mapToInt(Room::sectorId)
5164
.sum();
5265
}
5366

5467
@Override
5568
public Object part2() {
56-
return "";
69+
return dayStream()
70+
.map(this::parseRoom)
71+
.filter(Room::isReal)
72+
.filter(room -> room.decrypt().contains("northpole"))
73+
.findFirst()
74+
.map(Room::sectorId)
75+
.orElse(0);
5776
}
5877
}

0 commit comments

Comments
 (0)