Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 84d347b

Browse filesBrowse files
committed
Day 9
1 parent 721dc53 commit 84d347b
Copy full SHA for 84d347b

File tree

Expand file treeCollapse file tree

2 files changed

+182
-0
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+182
-0
lines changed

‎src/test/java/com/macasaet/Day09.java

Copy file name to clipboard
+177Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
package com.macasaet;
2+
3+
import java.util.*;
4+
import java.util.function.Function;
5+
import java.util.stream.Collectors;
6+
import java.util.stream.IntStream;
7+
import java.util.stream.Stream;
8+
import java.util.stream.StreamSupport;
9+
10+
import org.junit.jupiter.api.Test;
11+
12+
/**
13+
* --- Day 9: Smoke Basin ---
14+
*/
15+
public class Day09 {
16+
17+
protected Stream<String> getInput() {
18+
return StreamSupport
19+
.stream(new LineSpliterator("day-09.txt"),
20+
false);
21+
}
22+
23+
public HeightMap getHeightMap() {
24+
final var list = getInput().map(line -> {
25+
final var chars = line.toCharArray();
26+
final var ints = new int[chars.length];
27+
for (int i = chars.length; --i >= 0; ints[i] = chars[i] - '0') ;
28+
return ints;
29+
}).collect(Collectors.toList());
30+
final int[][] grid = new int[list.size()][];
31+
for (int i = list.size(); --i >= 0; grid[i] = list.get(i)) ;
32+
return new HeightMap(grid);
33+
}
34+
35+
/**
36+
* A height map of the floor of the nearby caves generated by the submarine
37+
*/
38+
public record HeightMap(int[][] grid) { // FIXME use bytes
39+
40+
public Stream<Point> points() {
41+
return IntStream.range(0, grid().length)
42+
.boxed()
43+
.flatMap(i -> IntStream.range(0, grid()[i].length)
44+
.mapToObj(j -> new Point(i, j)));
45+
}
46+
47+
/**
48+
* A location on the floor of a nearby cave
49+
*/
50+
public class Point {
51+
final int x;
52+
final int y;
53+
54+
public Point(final int x, final int y) {
55+
this.x = x;
56+
this.y = y;
57+
}
58+
59+
public int x() {
60+
return this.x;
61+
}
62+
63+
public int y() {
64+
return this.y;
65+
}
66+
67+
public int getBasinSize() {
68+
return getBasinPoints().size();
69+
}
70+
71+
/**
72+
* Identify all the higher points that are also part of the same basin, assuming this location is part of a
73+
* basin.
74+
*
75+
* @return all the higher points, if any, that are part of the same basin.
76+
*/
77+
public Set<Point> getBasinPoints() {
78+
if (getHeight() >= 9) {
79+
return Collections.emptySet();
80+
}
81+
final var result = new HashSet<Point>();
82+
result.add(this);
83+
final Function<Point, Stream<Point>> basinPointRetriever = neighbour -> {
84+
if (neighbour.getHeight() >= 9 || neighbour.getHeight() <= getHeight() || result.contains(neighbour)) {
85+
return Stream.empty();
86+
}
87+
return neighbour.getBasinPoints().stream();
88+
};
89+
above().stream().flatMap(basinPointRetriever).forEach(result::add);
90+
below().stream().flatMap(basinPointRetriever).forEach(result::add);
91+
left().stream().flatMap(basinPointRetriever).forEach(result::add);
92+
right().stream().flatMap(basinPointRetriever).forEach(result::add);
93+
return Collections.unmodifiableSet(result);
94+
}
95+
96+
/**
97+
* @return true if and only if this location is lower than all of its adjacent locations (up to four,
98+
* diagonals do not count)
99+
*/
100+
public boolean isLowPoint() {
101+
final var compareTo = new ArrayList<Point>(4);
102+
above().ifPresent(compareTo::add);
103+
below().ifPresent(compareTo::add);
104+
left().ifPresent(compareTo::add);
105+
right().ifPresent(compareTo::add);
106+
return compareTo.stream().allMatch(neighbour -> neighbour.getHeight() > getHeight());
107+
}
108+
109+
/**
110+
* @return an assessment of the risk from smoke flowing through the cave
111+
*/
112+
public int getRiskLevel() {
113+
return getHeight() + 1;
114+
}
115+
116+
/**
117+
* @return the height of this particular location, from 0-9
118+
*/
119+
public int getHeight() {
120+
return grid()[x()][y()];
121+
}
122+
123+
public Optional<Point> above() {
124+
return x() > 0 ? Optional.of(new Point(x() - 1, y())) : Optional.empty();
125+
}
126+
127+
public Optional<Point> below() {
128+
return x() < grid().length - 1 ? Optional.of(new Point(x() + 1, y())) : Optional.empty();
129+
}
130+
131+
public Optional<Point> left() {
132+
return y() > 0 ? Optional.of(new Point(x(), y() - 1)) : Optional.empty();
133+
}
134+
135+
public Optional<Point> right() {
136+
return y() < grid()[x()].length - 1 ? Optional.of(new Point(x(), y() + 1)) : Optional.empty();
137+
}
138+
139+
public int hashCode() {
140+
return Objects.hash(x(), y());
141+
}
142+
143+
public boolean equals(final Object o) {
144+
try {
145+
final Point other = (Point) o;
146+
return this.x() == other.x() && this.y() == other.y();
147+
} catch (final ClassCastException cce) {
148+
return false;
149+
}
150+
}
151+
}
152+
153+
}
154+
155+
@Test
156+
public final void part1() {
157+
final var map = getHeightMap();
158+
final int sum = map.points()
159+
.filter(HeightMap.Point::isLowPoint)
160+
.mapToInt(HeightMap.Point::getRiskLevel)
161+
.sum();
162+
System.out.println("Part 1: " + sum);
163+
}
164+
165+
@Test
166+
public final void part2() {
167+
final var map = getHeightMap();
168+
final var basinSizes = map.points()
169+
.filter(HeightMap.Point::isLowPoint)
170+
.mapToInt(HeightMap.Point::getBasinSize)
171+
.collect(() -> new TreeSet<Integer>(Comparator.reverseOrder()), SortedSet::add, SortedSet::addAll);
172+
final var iterator = basinSizes.iterator();
173+
final var result = iterator.next() * iterator.next() * iterator.next();
174+
System.out.println("Part 2: " + result);
175+
}
176+
177+
}

‎src/test/resources/sample/day-09.txt

Copy file name to clipboard
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2199943210
2+
3987894921
3+
9856789892
4+
8767896789
5+
9899965678

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.