Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commit3207f46

Browse files
committed
day 15
1 parent360dc68 commit3207f46

File tree

11 files changed

+353
-0
lines changed

11 files changed

+353
-0
lines changed

‎README.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,7 @@ Today I randomly discovered
8080
[local classes](https://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html) and
8181
[records](https://docs.oracle.com/en/java/javase/17/language/records.html). This allows you to scope, say, an intermediate record for a stream transformation, to a single method
8282
and avoid clutter at the class level. Pretty cool!
83+
84+
###12/15/2024
85+
86+
Day 14 Part 2 had me stumped, at least for now. Moving on to Day 15.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
packagecom.codefork.aoc2024.day15;
2+
3+
publicrecordBox(Positionpos,intwidth) {
4+
5+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
packagecom.codefork.aoc2024.day15;
2+
3+
publicenumDirection {
4+
Up,Right,Down,Left;
5+
6+
publicstaticDirectionparse(Strings) {
7+
returnswitch (s) {
8+
case"^" ->Up;
9+
case">" ->Right;
10+
case"v" ->Down;
11+
case"<" ->Left;
12+
default ->thrownewRuntimeException("unrecognized direction");
13+
};
14+
}
15+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
packagecom.codefork.aoc2024.day15;
2+
3+
importcom.codefork.aoc2024.util.WithIndex;
4+
5+
importjava.util.ArrayList;
6+
importjava.util.HashSet;
7+
importjava.util.List;
8+
importjava.util.stream.Stream;
9+
10+
importstaticcom.codefork.aoc2024.util.FoldLeft.foldLeft;
11+
12+
publicrecordDocument(Warehousewarehouse,List<Direction>moves) {
13+
14+
privatestaticfinalList<String>mapChars =List.of("O","#","@",".");
15+
16+
/**
17+
* @param data
18+
* @param width interpret walls and boxes to be as wide as this value
19+
* @return
20+
*/
21+
publicstaticDocumentparse(Stream<String>data,intwidth) {
22+
returndata
23+
.map(WithIndex.indexed())
24+
.filter(lineWithIndex -> !lineWithIndex.value().isEmpty())
25+
.collect(foldLeft(
26+
() ->newDocument(newWarehouse(newHashSet<>(),newHashSet<>(),newPosition(-1, -1)),newArrayList<>()),
27+
(acc,lineWithIndex) -> {
28+
vary =lineWithIndex.index();
29+
varline =lineWithIndex.value();
30+
if (mapChars.stream().anyMatch(line::contains)) {
31+
returnline.chars()
32+
.boxed()
33+
.map(WithIndex.indexed())
34+
.collect(foldLeft(
35+
() ->acc,
36+
(acc2,chWithIndex) -> {
37+
varx =chWithIndex.index() *width;
38+
varch =String.valueOf((char)chWithIndex.value().intValue());
39+
varpos =newPosition(x,y);
40+
switch (ch) {
41+
case"#" -> {
42+
varnewWalls =newHashSet<>(acc2.warehouse().walls());
43+
for (varn =0;n <width;n++) {
44+
newWalls.add(newPosition(pos.x() +n,pos.y()));
45+
}
46+
returnnewDocument(acc2.warehouse().withWalls(newWalls),acc2.moves());
47+
}
48+
case"O" -> {
49+
varnewBoxes =newHashSet<>(acc2.warehouse().boxes());
50+
newBoxes.add(newBox(pos,width));
51+
returnnewDocument(acc2.warehouse().withBoxes(newBoxes),acc2.moves());
52+
}
53+
case"@" -> {
54+
returnnewDocument(acc2.warehouse().withRobot(pos),acc2.moves());
55+
}
56+
}
57+
returnacc2;
58+
})
59+
);
60+
}else {
61+
returnline.chars()
62+
.boxed()
63+
.collect(foldLeft(
64+
() ->acc,
65+
(acc2,charInt) -> {
66+
varch =String.valueOf((char)charInt.intValue());
67+
vardir =Direction.parse(ch);
68+
varnewMoves =acc2.moves();
69+
newMoves.add(dir);
70+
returnnewDocument(acc2.warehouse(),newMoves);
71+
})
72+
);
73+
}
74+
})
75+
);
76+
}
77+
78+
/**
79+
* do all the moves and return the final state of the warehouse
80+
**/
81+
publicWarehousedoMoves() {
82+
returnmoves().stream()
83+
.collect(foldLeft(
84+
this::warehouse,
85+
Warehouse::move)
86+
);
87+
}
88+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
packagecom.codefork.aoc2024.day15;
2+
3+
importcom.codefork.aoc2024.Problem;
4+
importcom.codefork.aoc2024.util.Assert;
5+
6+
importjava.util.stream.Stream;
7+
8+
publicclassPart01extendsProblem {
9+
10+
publicStringsolve(Stream<String>data) {
11+
vardocument =Document.parse(data,1);
12+
varfinalWarehouse =document.doMoves();
13+
returnString.valueOf(finalWarehouse.getSumBoxCoordinates());
14+
}
15+
16+
@Override
17+
publicStringsolve() {
18+
Assert.assertEquals("2028",solve(getFileAsStream("small_sample")));
19+
Assert.assertEquals("10092",solve(getSampleInput()));
20+
returnsolve(getInput());
21+
}
22+
23+
publicstaticvoidmain(String[]args) {
24+
newPart01().run();
25+
}
26+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
packagecom.codefork.aoc2024.day15;
2+
3+
importcom.codefork.aoc2024.Problem;
4+
importcom.codefork.aoc2024.util.Assert;
5+
6+
importjava.util.stream.Stream;
7+
8+
publicclassPart02extendsProblem {
9+
10+
publicStringsolve(Stream<String>data) {
11+
vardocument =Document.parse(data,2);
12+
varfinalWarehouse =document.doMoves();
13+
returnString.valueOf(finalWarehouse.getSumBoxCoordinates());
14+
}
15+
16+
@Override
17+
publicStringsolve() {
18+
Assert.assertEquals("9021",solve(getSampleInput()));
19+
returnsolve(getInput());
20+
}
21+
22+
publicstaticvoidmain(String[]args) {
23+
newPart02().run();
24+
}
25+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
packagecom.codefork.aoc2024.day15;
2+
3+
publicrecordPosition(intx,inty) {
4+
5+
publicPositionwithChangedX(intdX) {
6+
returnnewPosition(x() +dX,y());
7+
}
8+
9+
publicPositionwithChangedY(intdY) {
10+
returnnewPosition(x(),y() +dY);
11+
}
12+
13+
}
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
packagecom.codefork.aoc2024.day15;
2+
3+
importjava.util.ArrayList;
4+
importjava.util.HashSet;
5+
importjava.util.List;
6+
importjava.util.Set;
7+
importjava.util.stream.IntStream;
8+
importjava.util.stream.Stream;
9+
10+
publicrecordWarehouse(Set<Position>walls,Set<Box>boxes,Positionrobot) {
11+
12+
publicWarehousewithWalls(Set<Position>newWalls) {
13+
returnnewWarehouse(newWalls,boxes,robot);
14+
}
15+
16+
publicWarehousewithBoxes(Set<Box>newBoxes) {
17+
returnnewWarehouse(walls,newBoxes,robot);
18+
}
19+
20+
publicWarehousewithRobot(PositionnewRobot) {
21+
returnnewWarehouse(walls,boxes,newRobot);
22+
}
23+
24+
/**
25+
* return true if any of the positions are walls
26+
*/
27+
publicbooleanareWalls(List<Position>positions) {
28+
returnpositions.stream().anyMatch(walls::contains);
29+
}
30+
31+
publicWarehousemoveVertical(intdY) {
32+
varboxWidth =boxes.stream().findFirst().orElseThrow().width();
33+
varfoundEmpty =false;
34+
// order matters for boxesToMove, so it's a List
35+
varboxesToMove =newArrayList<Box>();
36+
varboxesToCheck =IntStream.range(0,boxWidth).boxed().map(i ->
37+
newPosition(robot.x() -i,robot.y() +dY)
38+
).toList();
39+
varwallsToCheck =List.of(newPosition(robot.x(),robot.y() +dY));
40+
while (!areWalls(wallsToCheck)) {
41+
// check if boxesToCheck are boxes
42+
finalvar_toCheck =boxesToCheck;
43+
varfoundBoxes =boxes.stream().filter(box ->_toCheck.contains(box.pos())).toList();
44+
// no boxes found? we're done, we can move!
45+
if(foundBoxes.isEmpty()) {
46+
foundEmpty =true;
47+
break;
48+
}
49+
boxesToMove.addAll(foundBoxes);
50+
// set boxesToCheck for the boxes we just found
51+
boxesToCheck =foundBoxes.stream().flatMap(box -> {
52+
// TODO: I hard coded these possibilities because I'm tired,
53+
// but they should really be calculated based on boxWidth
54+
if(boxWidth ==1) {
55+
returnStream.of(box.pos().withChangedY(dY));
56+
}elseif(boxWidth ==2) {
57+
returnStream.of(
58+
box.pos().withChangedY(dY).withChangedX(-1),
59+
box.pos().withChangedY(dY),
60+
box.pos().withChangedY(dY).withChangedX(1)
61+
);
62+
}
63+
thrownewRuntimeException("can't handle boxWidth=" +boxWidth);
64+
}).toList();
65+
wallsToCheck =foundBoxes.stream().flatMap(box -> {
66+
// TODO: I hard coded these possibilities because I'm tired,
67+
// but they should really be calculated based on boxWidth
68+
if(boxWidth ==1) {
69+
returnStream.of(box.pos().withChangedY(dY));
70+
}elseif(boxWidth ==2) {
71+
returnStream.of(box.pos().withChangedY(dY),box.pos().withChangedY(dY).withChangedX(1));
72+
}
73+
thrownewRuntimeException("can't handle boxWidth=" +boxWidth);
74+
}).toList();
75+
}
76+
if (foundEmpty) {
77+
varnewBoxes =newHashSet<>(boxes);
78+
for (varbox :boxesToMove.reversed()) {
79+
newBoxes.remove(box);
80+
newBoxes.add(newBox(newPosition(box.pos().x(),box.pos().y() +dY),boxWidth));
81+
}
82+
returnnewWarehouse(walls,newBoxes,newPosition(robot.x(),robot.y() +dY));
83+
}else {
84+
returnthis;
85+
}
86+
}
87+
88+
publicWarehousemoveHorizontal(intdX) {
89+
varboxWidth =boxes.stream().findFirst().orElseThrow().width();
90+
varfoundEmpty =false;
91+
// order matters for boxesToMove, so it's a List
92+
varboxesToMove =newArrayList<Box>();
93+
varboxToCheck =dX <0 ?
94+
newBox(newPosition(robot.x() + (dX *boxWidth),robot.y()),boxWidth) :
95+
newBox(newPosition(robot.x() +dX,robot.y()),boxWidth);
96+
varwallsToCheck =List.of(newPosition(robot.x() +dX,robot.y()));
97+
while (!areWalls(wallsToCheck)) {
98+
varisBox =boxes.contains(boxToCheck);
99+
// not a box? we found empty space, so we can move
100+
if(!isBox) {
101+
foundEmpty =true;
102+
break;
103+
}
104+
boxesToMove.add(boxToCheck);
105+
106+
boxToCheck =newBox(newPosition(boxToCheck.pos().x() + (dX *boxWidth),boxToCheck.pos().y()),boxWidth);
107+
// TODO: I hard coded these possibilities because I'm tired,
108+
// but they should really be calculated based on boxWidth
109+
if(boxWidth ==1) {
110+
wallsToCheck =List.of(boxToCheck.pos());
111+
}elseif (boxWidth ==2) {
112+
wallsToCheck =dX <0 ?
113+
List.of(boxToCheck.pos().withChangedX(1)) :
114+
List.of(boxToCheck.pos());
115+
}
116+
}
117+
if (foundEmpty) {
118+
varnewBoxes =newHashSet<>(boxes);
119+
for (varbox :boxesToMove.reversed()) {
120+
newBoxes.remove(box);
121+
varmoved =newBox(newPosition(box.pos().x() +dX,box.pos().y()),boxWidth);
122+
newBoxes.add(moved);
123+
}
124+
returnnewWarehouse(walls,newBoxes,newPosition(robot.x() +dX,robot.y()));
125+
}else {
126+
returnthis;
127+
}
128+
}
129+
130+
/**
131+
* move the robot in the specified direction and return the new state of the warehouse
132+
* @param direction
133+
* @return
134+
*/
135+
publicWarehousemove(Directiondirection) {
136+
varnewWarehouse =switch (direction) {
137+
caseDirection.Up ->moveVertical(-1);
138+
caseDirection.Down ->moveVertical(1);
139+
caseDirection.Right ->moveHorizontal(1);
140+
caseDirection.Left ->moveHorizontal(-1);
141+
};
142+
//System.out.println("moved " + direction + ":");
143+
//newWarehouse.print();
144+
returnnewWarehouse;
145+
}
146+
147+
publicintgetSumBoxCoordinates() {
148+
returnboxes.stream()
149+
.map(box ->100 *box.pos().y() +box.pos().x())
150+
.mapToInt(i ->i)
151+
.sum();
152+
}
153+
154+
publicvoidprint() {
155+
intheight =walls.stream().map(Position::y).max(Integer::compareTo).orElseThrow() +1;
156+
intwidth =walls.stream().map(Position::x).max(Integer::compareTo).orElseThrow() +1;
157+
158+
for (vary =0;y <height;y++) {
159+
for (varx =0;x <width;x++) {
160+
varpos =newPosition(x,y);
161+
if (walls.contains(pos)) {
162+
System.out.print("#");
163+
}elseif (boxes.contains(newBox(pos,1))) {
164+
System.out.print("O");
165+
}elseif (boxes.contains(newBox(pos,2))) {
166+
System.out.print("[]");
167+
x +=1;
168+
}elseif (pos.equals(robot)) {
169+
System.out.print("@");
170+
}else {
171+
System.out.print(".");
172+
}
173+
}
174+
System.out.println();
175+
}
176+
}
177+
}

‎src/main/resources/day15/input‎

22.1 KB
Binary file not shown.

‎src/main/resources/day15/sample‎

843 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp