Skip to content

Commit b501922

Browse files
committed
Advent of Code 2021 - Day 9
1 parent ec8786c commit b501922

File tree

6 files changed

+287
-4
lines changed

6 files changed

+287
-4
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@ Last year I ran a [cruise log for my 25 days competing in the Advent of Code](ht
2525
- [The Advent of Code 2021 Day 5 log, pointless points](https://www.codingnagger.com/2021/12/05/the-advent-of-code-2021-day-5-log-pointless-points/)
2626
- [The Advent of Code 2021 Day 6 log, plenty of fish](https://www.codingnagger.com/2021/12/06/the-advent-of-code-2021-day-6-log-plenty-of-fish/)
2727
- [The Advent of Code 2021 Day 7 log, return of the crab](https://www.codingnagger.com/2021/12/07/the-advent-of-code-2021-day-7-log-return-of-the-crab/)
28-
- [The Advent of Code 2021 Day 8, Bruteforce for the win](https://www.codingnagger.com/2021/12/08/the-advent-of-code-2021-day-8-bruteforce-for-the-win/)
28+
- [The Advent of Code 2021 Day 8, Bruteforce for the win](https://www.codingnagger.com/2021/12/08/the-advent-of-code-2021-day-8-bruteforce-for-the-win/)
29+
- [The Advent of Code 2021 Day 9, quiet before the storm?](https://www.codingnagger.com/2021/12/09/the-advent-of-code-2021-day-9-quiet-before-the-storm/)

src/main/java/com/codingnagger/App.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.codingnagger;
22

33
import com.codingnagger.days.Day;
4-
import com.codingnagger.days.Day8;
4+
import com.codingnagger.days.Day9;
55
import com.codingnagger.utils.InputLoader;
66

77
import java.io.IOException;
@@ -14,9 +14,9 @@ public class App {
1414
public static void main(String[] args) throws IOException {
1515
System.out.println("Advent of Code 2021");
1616

17-
List<String> input = InputLoader.Load("day8.txt");
17+
List<String> input = InputLoader.Load("day9.txt");
1818

19-
Day day = new Day8();
19+
Day day = new Day9();
2020

2121
System.out.println("Part 1:");
2222
System.out.println(day.partOne(input));
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package com.codingnagger.days;
2+
3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.Collections;
6+
import java.util.List;
7+
import java.util.Objects;
8+
import java.util.stream.Collectors;
9+
10+
public class Day9 implements Day {
11+
@Override
12+
public String partOne(List<String> input) {
13+
Integer[][] locations = parseLocations(input);
14+
List<Integer> lowestPoints = findLowestPoints(locations);
15+
return String.valueOf(lowestPoints.size() + lowestPoints.stream().mapToInt(i -> i).sum());
16+
}
17+
18+
private List<Integer> findLowestPoints(Integer[][] locations) {
19+
List<Integer> lowestPoints = new ArrayList<>();
20+
21+
for (int y = 0; y < locations.length; y++) {
22+
for (int x = 0; x < locations[y].length; x++) {
23+
if (isLowestPoint(x, y, locations)) {
24+
lowestPoints.add(locations[y][x]);
25+
}
26+
}
27+
}
28+
29+
return lowestPoints;
30+
}
31+
32+
private boolean isLowestPoint(int x, int y, Integer[][] locations) {
33+
int minX = Math.max(0, x - 1);
34+
int maxX = Math.min(locations[y].length - 1, x + 1);
35+
int minY = Math.max(0, y - 1);
36+
int maxY = Math.min(locations.length - 1, y + 1);
37+
38+
int location = locations[y][x];
39+
40+
for (int cy = minY; cy <= maxY; cy++) {
41+
for (int cx = minX; cx <= maxX; cx++) {
42+
if (cx == x && cy == y) {
43+
continue;
44+
}
45+
46+
if (locations[cy][cx] <= location) {
47+
return false;
48+
}
49+
}
50+
}
51+
52+
return true;
53+
}
54+
55+
private Integer[][] parseLocations(List<String> input) {
56+
int maxY = input.size();
57+
58+
Integer[][] locations = new Integer[maxY][];
59+
60+
for (int i = 0; i < maxY; i++) {
61+
locations[i] = Arrays.stream(input.get(i).split("")).map(Integer::parseInt).toArray(Integer[]::new);
62+
}
63+
64+
return locations;
65+
}
66+
67+
@Override
68+
public String partTwo(List<String> input) {
69+
List<List<Position>> basins = findBasins(input);
70+
basins.sort((b1, b2) -> b2.size() - b1.size());
71+
return String.valueOf(basins.get(0).size() * basins.get(1).size() * basins.get(2).size());
72+
}
73+
74+
private List<List<Position>> findBasins(List<String> input) {
75+
Integer[][] locations = parseLocations(input);
76+
List<Position> lowestPointPositions = findLowestPointPositions(locations);
77+
return lowestPointPositions.stream().map(p -> findBasin(p, locations, Collections.emptyList())).collect(Collectors.toList());
78+
}
79+
80+
private List<Position> findBasin(Position current, Integer[][] locations, List<Position> explored) {
81+
if (explored.contains(current) || locations[current.y][current.x] == 9) {
82+
return Collections.emptyList();
83+
}
84+
85+
int x = current.x;
86+
int y = current.y;
87+
int minX = Math.max(0, x - 1);
88+
int maxX = Math.min(locations[y].length - 1, x + 1);
89+
int minY = Math.max(0, y - 1);
90+
int maxY = Math.min(locations.length - 1, y + 1);
91+
92+
List<Position> basin = new ArrayList<>(explored);
93+
94+
basin.add(current);
95+
96+
if (y != minY) {
97+
basin.addAll(findBasin(new Position(x, minY), locations, basin));
98+
}
99+
100+
if (y != maxY) {
101+
basin.addAll(findBasin(new Position(x, maxY), locations, basin));
102+
}
103+
104+
if (x != minX) {
105+
basin.addAll(findBasin(new Position(minX, y), locations, basin));
106+
}
107+
108+
if (x != maxX) {
109+
basin.addAll(findBasin(new Position(maxX, y), locations, basin));
110+
}
111+
112+
return basin.stream().distinct().collect(Collectors.toList());
113+
}
114+
115+
private List<Position> findLowestPointPositions(Integer[][] locations) {
116+
List<Position> lowestPointsPositions = new ArrayList<>();
117+
118+
for (int y = 0; y < locations.length; y++) {
119+
for (int x = 0; x < locations[y].length; x++) {
120+
if (isLowestPoint(x, y, locations)) {
121+
lowestPointsPositions.add(new Position(x, y));
122+
}
123+
}
124+
}
125+
126+
return lowestPointsPositions;
127+
}
128+
129+
public class Position {
130+
private final int x, y;
131+
132+
public Position(int x, int y) {
133+
this.x = x;
134+
this.y = y;
135+
}
136+
137+
@Override
138+
public boolean equals(Object o) {
139+
if (this == o) return true;
140+
if (o == null || getClass() != o.getClass()) return false;
141+
Position position = (Position) o;
142+
return x == position.x && y == position.y;
143+
}
144+
145+
@Override
146+
public int hashCode() {
147+
return Objects.hash(x, y);
148+
}
149+
}
150+
}

src/main/resources/day9.txt

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
3235678976543234569109899875456987676387679999878953234987656895457998743212347892123999912987632489
2+
2124899989932145698998789994329876545235567899768995349898546789346987654423656789339889899986541678
3+
1012567897898756797987678989212985432103458987656789456789435691235998775634987897998776798775430567
4+
2343489956789987976798899578901299654512578998545899567894326890449899896845898945899655987654321378
5+
3455697645678999875679965467892398999323456789656798998952018921598799987896789235789544398765435459
6+
4589789432567987764597654358679497878954578996987987999543459433697689899987892123498732129879646589
7+
5678994321456976543989543236568986769895989654599876789765569555987578778999989014987653234998789678
8+
6789875432349897659878943123459875458789996543298765678987678976899434569019878925998754345679898789
9+
7894987654599798798768932012598766345678997692199854567898789987998923978998767899899987456789989899
10+
9993298765987689988957899129679953237899989989987623456789898698987899899998756798789896588899878967
11+
8989109876796569977845678998998767129949876979798544587899954569876786799987546989656799679999865456
12+
7678912987965498765434567897899643298939965765679656798998768998765125899997639876545678996598754321
13+
6567894599876329896545878976987654987898954354598787899999879129654014768998549865434568995439863210
14+
5456789678997547989656789454598767976767976123459898976799989098643123456789998754323456789521994921
15+
4347998799987656978967894323789879765656891012567999765789899987654354799999876543212368996542989899
16+
3298949898998799867899965434678998654346789123458998654576789298966455678935987654345679987759878788
17+
4989534987899987656789879765799998743235679254569876543445679019878766789124598775656799999898765667
18+
9878921256999876546899989878987879865123789365678989521234695434989899893012349987878898989987654545
19+
9967892345987655434989999989876565986239895478789998432345696549999989932123457898999947678998943234
20+
8756793496796542323478999898785454987645996589893987643456789698999878943934578999986434567899932123
21+
4345789989987641014567896797685323498656789699912397654567999987899867999895689598765323456997821012
22+
3234699879876532123479965986543212349987899898901469895689109876987656789789791459853212349876543156
23+
0134589965998743234569534598655304558998910967893456976789999965496544345678992398654101256997643245
24+
1234567894569854375678976789766412367899321256789569987896789896986432234569989987653212397987656356
25+
2547678923456975676989997999896567898996432345679678998935698789876531023789877999765323989998975457
26+
3458789212689876989299989123987878979987593958798989899123987678987632234989765789876439879899876568
27+
5569896345678987892109878994698989767998989899997898789239899568998544345678954567999949768799987679
28+
6789965456789998943498767789899694545899878789986787679398798457899765459899543456798798656689998989
29+
8992986767898969894989345699986543236789765699875656568997656356789876567989212378999659543567899992
30+
9901299878987656789875234599997654697999873987654343459789543235899989678978934567998943212578923901
31+
7899988989876545678984123678939765789876542198843212345678910124589998789567895979876432101458939892
32+
6798767998783234569873234569219896899965431097652101234889321234678999893459976789987943242357898789
33+
7987657789656123698764675678909987939878592198963213455695432348989876932347997895699894343456789678
34+
9876546678943234999878786789698998921989989999984323567789543567898765421286789934598789658767893467
35+
9965436567894549898989897896567899993998767899876544568897654578919976982345690129987678969878912345
36+
9894325476789698787898999965456789989897656791987675689999879989102989876456789398776579899989423456
37+
8763212345998789656797897654239999976798745690998786789899998996212399988767891987654456779997678967
38+
7654323466789899645685679793198898765679659989879897896789987895475498999898910399743234568998789878
39+
8876434578899998921434998989987679954549798878764998945698976796786987989979521249432123456789892989
40+
9987545699998987890129897678976567893234987654353459936987895989899896878965434598543234587899921094
41+
1099786789997876789298786567897789964645898983232345899876764878998795769896545697654355699999992123
42+
2199899899896765678999543498999899875776789872101236789965743767896543456789676898768456789998989934
43+
3987989998765434567895432345699912986989899654312345679874232456965432345678987999899567899987679895
44+
9876378987654323456989541016989993997893998765459569797662101247894321234569998999999698919876567789
45+
8765459876543212345678952345679889898912999877568678989543212348973210123459899989998789909865434697
46+
9896567997654101456789763456798768789909899989679789978965343459765421234598768978999897898954323456
47+
3987678998783216598899874567987654567899769998789898869897654789987532345987659767893956797895412345
48+
2198789659854427689976985678995453478999878919899987656798765678998743456976745457891045976589101956
49+
1019894345967838798765696789984322246789989434989998745689977899987654579875432345679134989678999897
50+
2129943259878545897654987899876510135678998765678986534567898945998775689976543678989245698789989789
51+
3498899198989656976543498998765421234569999878789198645778999439899976789989774567899876789999877676
52+
9987788987698767897662349899896544346789789989891099876889789598789997898798765679943989899998764565
53+
8976547896549878999743456789987675487895679797992987989997678987678989998549978789952199978999543634
54+
7987436789432989987654589992398789598934589656789976599986569876569878987634599897893298767997432123
55+
6798545697653498998765678990999897679545678934699954349875498765498767896545987956789987659876541012
56+
5569658789894567899878799789897998798696799129789897598764349854323458997659876545678998434989752123
57+
3498767999965678945989895699766569999989894298998789987543212976212356789998987676799129323499843234
58+
2349879569876789234997964578957346988778995987688678999674309765301235789897698987899997434568974365
59+
1234989435989892199875453689541239879569789876576567898764312943213376898767539398999876567899765486
60+
0145895323499953987654312795432498765489678965435456999985429894524567999754321239899987678969876597
61+
2256789212989879876543201976643987654344567894324345899876998789634789698765210156799998789943987678
62+
3457894109876989987859349897656996432253456799210236789989897678945797549874321234567899999899998789
63+
7568943298765799998998998799787897641012345678921234999896789567896965434989939545689949876788999899
64+
8678954369934678999897687678998999832243658789762349896765689456789876629897898956893235965457999999
65+
9889876459895799999765458567899998954354567899943498775674578967899997898766757897932101294356789998
66+
2999987598789899987654323457899987895465678999899987654323789878998798987654646798943912989245679987
67+
1989998997678989987543212346789896789878789989768999765454789999997669597543434789799899878968798766
68+
9978999986569678998654343677898785698989899877657898986565678999976543496532323597698798967899999854
69+
8867898765474567898767654578998674567899998765434587897878989989898932989421014976597677657999878975
70+
7656569876343569999898767689776543456789679879523456789989999879789891978993429897989556547689969989
71+
6547434987212345899999878797654312367996567997612346789599899965656789767989598789876443234567898795
72+
5432129998323456789785989896543201498923489876324457893456789654345698654678987698654321015798997654
73+
7321098999974567897674599987654432349314567965435678932969898769296987563567897549976572123456789543
74+
5432987898765678976553678998865543458909689976645679659899999898989995432456789432987654234569899654
75+
7649876549989989865442345679976754567898990987876789798789999987678986321568897643498765365878978985
76+
8998765430199998754321256989987866678987891298987899898698789876569854310978998756789876476989767976
77+
9987654321248999987532347899998978989876789459998923999569656965498765423989989867899989588995456897
78+
3298765442357897598675456999899989896765678999879212679678949854349876534599878989989997678985345789
79+
4109877675456789459986587899788998765634789989765424598789799765456988545679767495678998789873276789
80+
5298988786767894367987898997697989654325699978996876969897678976567997657889654323567899898762177899
81+
6987699887878985499098999876586478999438798767889989853934569989698998768999767015678976999654567977
82+
7996567998989876989139798965432367878949899848779998762123493194989879879999899524569345999965678956
83+
9875456789991989878945697654331456567899995437567899643434789012978767989989998434679999889876789545
84+
3984345678910198867896989963210123458999876523458998755645678999767856899978987678798788768989897632
85+
1296456789321997457997979894523236569996543212568979877876799987653345678969998989989678456896999743
86+
3989587898459876346789868789754347678987954323678965989987894699542126789458999899876543267895989654
87+
9878999996598754265697754699965498789599875434567894395998913398653234892347898757995432126789878965
88+
8767898789987662154986543659876789894323987565678943214879901298764345891276789549876574235678969897
89+
8656797678996543012965432348997898965634598986789432102367892989865456789345678932997865348789556798
90+
6545689589898784329876541557889967996789679797899543223456999879876869995457799321099876789894346789
91+
5432123497659895839865432345678959889898797698998674334567896567987878976569899932989987899921256999
92+
6563234987643976749877565456789545678999896549019775476878923456798989987878979893978598978932349898
93+
7854599865532397956988987667896734567899975432129896587889212769899690198989458789867439569899998767
94+
8965987654321298967899998778954323479989876543599987898992101278943591989693245698754523498788897656
95+
9876998765434349879998999899655212345678987655989998999653234568932989876562134987643212989697789643
96+
9987899876545656989587899976542103456789198779878999998765356789549979989431023987654109878576679932
97+
9898943999856767895456789989653214567891019889767899979976487899998768999545124598543298765434567893
98+
9769432349767878974367895397654323456789326998752398765987599959897656598657234987654998654323478954
99+
8754321239879999865458943239765464567895445987631259854398910145789543498765345698769876543212356799
100+
9653210123989439876789432129896875689976556796532349876459321234895432349877456789878987643101234678
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.codingnagger.days;
2+
3+
import com.codingnagger.utils.InputLoader;
4+
import org.junit.jupiter.api.Test;
5+
6+
import java.util.List;
7+
8+
import static org.assertj.core.api.Assertions.assertThat;
9+
10+
public class Day9Test {
11+
private static final List<String> INPUT = InputLoader.LoadTest("day9.txt");
12+
private static final Day DAY = new Day9();
13+
14+
@Test
15+
public void partOne_shouldReturnIncreaseCount() {
16+
String result = DAY.partOne(INPUT);
17+
18+
assertThat(result).isEqualTo("15");
19+
}
20+
21+
@Test
22+
public void partTwo_shouldReturnSlidingIncreaseCount() {
23+
String result = DAY.partTwo(INPUT);
24+
25+
assertThat(result).isEqualTo("1134");
26+
}
27+
}

src/test/resources/day9.txt

Lines 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)