8000 Day 5 · l0s/advent-of-code-java@7c8ccb9 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7c8ccb9

Browse files
committed
Day 5
1 parent 1a9177a commit 7c8ccb9

File tree

2 files changed

+198
-0
lines changed

2 files changed

+198
-0
lines changed

src/test/java/com/macasaet/Day05.java

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
package com.macasaet;
2+
3+
import java.util.function.Predicate;
4+
import java.util.stream.Collectors;
5+
import java.util.stream.Stream;
6+
import java.util.stream.StreamSupport;
7+
8+
import org.junit.jupiter.api.Test;
9+
10+
/**
11+
* --- Day 5: Hydrothermal Venture ---
12+
*/
13+
public class Day05 {
14+
15+
/**
16+
* A point on the ocean floor
17+
*/
18+
public static record Point(int x, int y) {
19+
public static Point parse(final String string) {
20+
final var components = string.split(",");
21+
return new Point(Integer.parseInt(components[0]), Integer.parseInt(components[1]));
22+
}
23+
24+
}
25+
26+
/**
27+
* A portion of the ocean floor on which there are hydrothermal vents, which produce large, opaque clouds
28+
*/
29+
public static record LineSegment(Point start, Point end) {
30+
public static LineSegment parse(final String string) {
31+
final var components = string.split(" -> ");
32+
return new LineSegment(Point.parse(components[0]), Point.parse(components[1]));
33+
}
34+
35+
/**
36+
* Highlight the location of this line segment on the diagram. Each cell that this segment covers will have its
37+
* value incremented. The higher the number, the more vents cover the cell.
38+
*
39+
* @param diagram A map of the ocean floor which will be updated by this call.
40+
*/
41+
public void update(final int[][] diagram) {
42+
/*
43+
"Because of the limits of the hydrothermal vent mapping system, the lines in your list will only ever be
44+
horizontal, vertical, or a diagonal line at exactly 45 degrees."
45+
*/
46+
final int horizontalStep = start().x() == end().x()
47+
? 0
48+
: start().x() < end().x()
49+
? 1
50+
: -1;
51+
final int verticalStep = start().y() == end().y()
52+
? 0
53+
: start().y() < end().y()
54+
? 1
55+
: -1;
56+
final Predicate<Integer> xTester = start().x() == end().x()
57+
? x -> true
58+
: start().x() < end().x()
59+
? x -> x <= end().x()
60+
: x -> x >= end().x();
61+
final Predicate<Integer> yTester = start().y() == end().y()
62+
? y -> true
63+
: start().y() < end().y()
64+
? y -> y <= end().y()
65+
: y -> y >= end().y();
66+
67+
for (int i = start().x(), j = start().y();
68+
xTester.test(i) && yTester.test(j);
69+
i += horizontalStep, j += verticalStep) {
70+
diagram[i][j]++;
71+
}
72+
}
73+
74+
public int lowestX() {
75+
return Math.min(start().x(), end().x());
76+
}
77+
78+
public int highestX() {
79+
return Math.max(start().x(), end().x());
80+
}
81+
82+
public int lowestY() {
83+
return Math.min(start().y(), end().y());
84+
}
85+
86+
public int highestY() {
87+
return Math.max(start().y(), end().y());
88+
}
89+
90+
public String toString() {
91+
return start() + " -> " + end();
92+
}
93+
}
94+
95+
protected Stream<LineSegment> getInput() {
96+
return StreamSupport
97+
.stream(new LineSpliterator("day-05.txt"),
98+
false)
99+
.map(LineSegment::parse);
100+
}
101+
102+
protected record Extremes(int lowestX, int lowestY, int highestX, int highestY) {
103+
public Extremes combine(final LineSegment segment) {
104+
return new Extremes(Math.min(lowestX(), segment.lowestX()),
105+
Math.min(lowestY(), segment.lowestY()),
106+
Math.max(highestX(), segment.highestX()),
107+
Math.max(highestY(), segment.highestY()));
108+
}
109+
110+
public Extremes combine(final Extremes other) {
111+
return new Extremes(Math.min(lowestX(), other.lowestX()),
112+
Math.min(lowestY(), other.lowestY()),
113+
Math.max(highestX(), other.highestX()),
114+
Math.max(highestY(), other.highestY()));
115+
}
116+
117+
public int[][] createBlankDiagram() {
118+
final int[][] result = new int[highestX() + 1][];
119+
for (int i = result.length; --i >= 0; result[i] = new int[highestY() + 1]) ;
120+
return result;
121+
}
122+
}
123+
124+
@Test
125+
public final void part1() {
126+
final var segments = getInput()
127+
// "For now, only consider horizontal and vertical lines: lines where either x1 = x2 or y1 = y2."
128+
.filter(segment -> segment.start().x() == segment.end().x() || segment.start().y() == segment.end().y())
129+
.collect(Collectors.toList());
130+
131+
final var extremes = segments
132+
.stream()
133+
.reduce(new Extremes(0, 0, 0, 0),
134+
Extremes::combine,
135+
Extremes::combine);
136+
// there are no negative values
137+
// Note, we could save a little bit of space and time by using a smaller map since none of the line segments
138+
// need point 0,0. However, the savings are likely negligible.
139+
final int[][] diagram = extremes.createBlankDiagram();
140+
141+
for (final var segment : segments) {
142+
segment.update(diagram);
143+
}
144+
int sum = 0;
145+
for (int i = diagram.length; --i >= 0; ) {
146+
final var row = diagram[i];
147+
for (int j = row.length; --j >= 0; ) {
148+
if (row[j] >= 2) {
149+
sum++;
150+
}
151+
}
152+
}
153+
System.out.println("Part 1: " + sum);
154+
}
155+
156+
@Test
157+
public final void part2() {
158+
/*
159+
"Unfortunately, considering only horizontal and vertical lines doesn't give you the full picture; you need to
160+
also consider diagonal lines."
161+
*/
162+
final var segments = getInput()
163+
.collect(Collectors.toList());
164+
final var extremes = segments
165+
.stream()
166+
.reduce(new Extremes(0, 0, 0, 0),
167+
Extremes::combine,
168+
Extremes::combine);
169+
// there are no negative values
170+
// Note, we could save a little bit of space and time by using a smaller map since none of the line segments
171+
// need point 0,0. However, the savings are likely negligible.
172+
final int[][] diagram = extremes.createBlankDiagram();
173+
for (final var segment : segments) {
174+
segment.update(diagram);
175+
}
176+
int sum = 0;
177+
for (int i = diagram.length; --i >= 0; ) {
178+
final var row = diagram[i];
179+
for (int j = row.length; --j >= 0; ) {
180+
if (row[j] >= 2) {
181+
sum++;
182+
}
183+
}
184+
}
185+
System.out.println("Part 2: " + sum);
186+
}
187+
188+
}

src/test/resources/sample/day-05.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
0,9 -> 5,9
2+
8,0 -> 0,8
3+
9,4 -> 3,4
4+
2,2 -> 2,1
5+
7,0 -> 7,4
6+
6,4 -> 2,0
7+
0,9 -> 2,9
8+
3,4 -> 1,4
9+
0,0 -> 8,8
10+
5,5 -> 8,2

0 commit comments

Comments
 (0)
0