-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDay05.java
More file actions
121 lines (107 loc) · 4.25 KB
/
Day05.java
File metadata and controls
121 lines (107 loc) · 4.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Day05 {
public static void Run(List<String> input) {
IngredientDb db = new IngredientDb(input);
part1(db);
part2(db);
}
private static void part1(IngredientDb db) {
long freshCount = 0;
for (long ingredient : db.ingredients) {
// check if the ingredient is in any of the ranges
for (int rangeIndex = 0; rangeIndex < db.freshRanges.size(); rangeIndex++) {
IdRange range = db.freshRanges.get(rangeIndex);
if (Long.compareUnsigned(ingredient, range.min) < 0) {
// ingredient is less than the minimum of this range, so it can't be in any
// further ranges
break;
}
if (Long.compareUnsigned(ingredient, range.max) <= 0) {
// ingredient is in this range
freshCount++;
break;
}
}
}
System.out.println("5.1: fresh count: " + freshCount);
}
private static void part2(IngredientDb db) {
ArrayList<IdRange> uniqueRanges = new ArrayList<IdRange>();
for (int i=0; i < db.freshRanges.size(); i++) {
ArrayList<IdRange> newRanges = new ArrayList<IdRange>();
newRanges.add( db.freshRanges.get(i));
while(!newRanges.isEmpty()){
IdRange candidate = newRanges.remove(0);
boolean isUnique = true;
for(IdRange existing : uniqueRanges){
if (candidate.overlaps(existing)){
isUnique = false;
// split candidate into non-overlapping parts
if (Long.compareUnsigned(candidate.min, existing.min) < 0){
newRanges.add( new IdRange(candidate.min + "-" + (existing.min - 1)));
}
if (Long.compareUnsigned(candidate.max, existing.max) > 0){
newRanges.add( new IdRange((existing.max + 1) + "-" + candidate.max));
}
break;
}
}
if (isUnique) {
uniqueRanges.add(candidate);
}
}
}
long freshCount = 0;
for(IdRange range : uniqueRanges){
freshCount += range.count();
}
System.out.println("5.2: fresh count: " + Long.toUnsignedString(freshCount));
}
private static class IngredientDb {
public List<IdRange> freshRanges;
public long[] ingredients;
public IngredientDb(List<String> input) {
super();
int lineIndex;
String line;
// read ranges
freshRanges = new ArrayList<IdRange>();
for (lineIndex = 0; lineIndex < input.size(); lineIndex++) {
line = input.get(lineIndex);
if (line.isBlank())
break;
freshRanges.add(new IdRange(line));
}
// sort by minimums to make searching easier
freshRanges.sort((a,b) -> Long.compare(a.min, b.min));
// skip the blank line
lineIndex++;
// read ingredients
ingredients = new long[input.size() - lineIndex];
for (int i = 0; lineIndex < input.size(); lineIndex++, i++) {
line = input.get(lineIndex);
ingredients[i] = Long.parseLong(line);
}
Arrays.sort(ingredients);
}
}
private static class IdRange{
public long min;
public long max;
public IdRange(String rangeString) {
super();
String[] tokens = rangeString.split("-");
min=Long.parseLong(tokens[0]);
max=Long.parseLong(tokens[1]);
}
public boolean overlaps(IdRange other){
return Long.compareUnsigned(this.min, other.max) <= 0 &&
Long.compareUnsigned(other.min, this.max) <= 0;
}
public long count(){
return (max - min + 1);
}
}
}