-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHydrothermalVentSaver.java
More file actions
182 lines (165 loc) · 6.04 KB
/
HydrothermalVentSaver.java
File metadata and controls
182 lines (165 loc) · 6.04 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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Solution to Day 5: Hydrothermal Venture.
*
* @author bluebillxp
*/
public class HydrothermalVentSaver {
private static class Coordinate {
int x;
int y;
int overlaps;
Coordinate(int x, int y) {
this.x = x;
this.y = y;
overlaps = 1;
}
}
private static class Line {
Coordinate start;
Coordinate end;
Line(Coordinate start, Coordinate end) {
this.start = start;
this.end = end;
}
}
private static class Route {
Coordinate[][] coordinates = new Coordinate[1000][1000];
Set<Coordinate> overlappedCoordinates = new HashSet<>();
}
public static void main(String[] args) {
List<String> input = AdventHelper.readInput("input-day5-hydrothermal-venture.txt");
List<Line> lines = parseLines(input);
System.out.println("Day 5: Hydrothermal Venture. " + lines.size() + " lines loaded.");
System.out.println("Day 5: Hydrothermal Venture. --- Part One ---");
System.out.println("Consider only horizontal and vertical lines. At how many points do at least two lines overlap?");
final int answerOne = solutionPartOne(lines);
System.out.println("Answer: " + answerOne);
System.out.println("\nDay 5: Hydrothermal Venture. --- Part Two ---");
System.out.println("Consider all of the lines. At how many points do at least two lines overlap?");
final int answerTwo = solutionPartTwo(lines);
System.out.println("Answer: " + answerTwo);
}
/**
* Calculates how many points do at least two lines overlap
* when consider only horizontal and vertical lines.
*
* @param lines Defined lines from the challenge.
*
* @return answer
*/
private static int solutionPartOne(List<Line> lines) {
Route route = new Route();
for (Line line : lines) {
drawLine(route, line, false);
}
return computePoints(route);
}
/**
* Calculates how many points do at least two lines overlap
* when consider all of the lines.
*
* @param lines Defined lines from the challenge.
*
* @return answer
*/
private static int solutionPartTwo(List<Line> lines) {
Route route = new Route();
for (Line line : lines) {
drawLine(route, line, true);
}
return computePoints(route);
}
private static void drawLine(Route route, Line line, boolean diagonal) {
if (line.start.x == line.end.x) {
int startY = Math.min(line.start.y, line.end.y);
int endY = Math.max(line.start.y, line.end.y);
for (int i = startY; i <= endY; i++) {
Coordinate coordinate = route.coordinates[line.start.x][i];
// Already lined.
if (coordinate != null) {
coordinate.overlaps++;
route.overlappedCoordinates.add(coordinate);
} else {
coordinate = new Coordinate(line.start.x, i);
route.coordinates[line.start.x][i] = coordinate;
}
}
}
if (line.start.y == line.end.y) {
int startX = Math.min(line.start.x, line.end.x);
int endX = Math.max(line.start.x, line.end.x);
for (int i = startX; i <= endX; i++) {
Coordinate coordinate = route.coordinates[i][line.start.y];
// Already lined.
if (coordinate != null) {
coordinate.overlaps++;
route.overlappedCoordinates.add(coordinate);
} else {
coordinate = new Coordinate(i, line.start.y);
route.coordinates[i][line.start.y] = coordinate;
}
}
}
if (!diagonal) {
return;
}
int sideX = Math.abs(line.start.x - line.end.x);
int sideY = Math.abs(line.start.y - line.end.y);
if (sideX == sideY) {
for (int i = 0; i <= sideX; i++) {
int movingX = line.start.x;
int movingY = line.start.y;
if (line.start.x >= line.end.x) {
movingX -= i;
} else {
movingX += i;
}
if (line.start.y >= line.end.y) {
movingY -= i;
} else {
movingY += i;
}
Coordinate coordinate = route.coordinates[movingX][movingY];
// Already lined.
if (coordinate != null) {
coordinate.overlaps++;
route.overlappedCoordinates.add(coordinate);
} else {
coordinate = new Coordinate(movingX, movingY);
route.coordinates[movingX][movingY] = coordinate;
}
}
}
}
private static List<Line> parseLines(List<String> input) {
List<Line> lines = new ArrayList<>(input.size());
for (String raw : input) {
if (raw.isEmpty()) {
continue;
}
String[] splits = raw.split("->");
int x = Integer.valueOf(splits[0].split(",")[0].trim());
int y = Integer.valueOf(splits[0].split(",")[1].trim());
Coordinate start = new Coordinate(x, y);
x = Integer.valueOf(splits[1].split(",")[0].trim());
y = Integer.valueOf(splits[1].split(",")[1].trim());
Coordinate end = new Coordinate(x, y);
Line line = new Line(start, end);
lines.add(line);
}
return lines;
}
private static int computePoints(Route route) {
int points = 0;
for (Coordinate coordinate : route.overlappedCoordinates) {
if (coordinate.overlaps >= 2) {
points++;
}
}
return points;
}
}