Skip to content

Commit bfe31dc

Browse files
committed
Day 9
1 parent a685df3 commit bfe31dc

File tree

2 files changed

+178
-0
lines changed

2 files changed

+178
-0
lines changed

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

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
package com.macasaet;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import java.util.Set;
6+
import java.util.SortedMap;
7+
import java.util.TreeMap;
8+
import java.util.TreeSet;
9+
import java.util.stream.Stream;
10+
import java.util.stream.StreamSupport;
11+
12+
/**
13+
* --- Day 9: Rope Bridge ---
14+
* <a href="https://adventofcode.com/2022/day/9">https://adventofcode.com/2022/day/9</a>
15+
*/
16+
public class Day09 {
17+
18+
record Coordinate(int x, int y) {
19+
20+
public int distance(final Coordinate other) {
21+
return (int)Math.sqrt(Math.pow((double)x() - (double)other.x(), 2.0) + Math.pow((double)y() - (double)other.y(), 2.0));
22+
}
23+
24+
public Coordinate step(final int xDistance, final int yDistance) {
25+
return new Coordinate(x() + xDistance, y + yDistance);
26+
}
27+
public Coordinate stepTowards(final Coordinate leader) {
28+
final var xDistance = Integer.compare(leader.x(), x());
29+
final var yDistance = Integer.compare(leader.y(), y());
30+
return step(xDistance, yDistance);
31+
}
32+
}
33+
34+
public static class Rope {
35+
36+
Coordinate[] knotCoordinates;
37+
38+
final SortedMap<Integer, Set<Integer>> visited = new TreeMap<>();
39+
40+
public Rope(final int knots) {
41+
knotCoordinates = new Coordinate[knots];
42+
for(int i = knots; --i >= 0; knotCoordinates[i] = new Coordinate(0, 0));
43+
visited.computeIfAbsent(0, (key) -> new TreeSet<>()).add(0);
44+
}
45+
46+
public int countVisited() {
47+
int result = 0;
48+
for( final var map : visited.values() ) {
49+
result += map.size();
50+
}
51+
return result;
52+
}
53+
54+
public void process(final Instruction instruction) {
55+
final int xStep = instruction.direction().xStep();
56+
final int yStep = instruction.direction().yStep();
57+
58+
for(int i = instruction.distance(); --i >= 0; ) {
59+
knotCoordinates[0] = knotCoordinates[0].step(xStep, yStep);
60+
for(int j = 1; j < knotCoordinates.length; j++) {
61+
moveKnot(j);
62+
}
63+
}
64+
}
65+
66+
protected void moveKnot(int knotIndex) {
67+
if(knotIndex <= 0) {
68+
throw new IllegalArgumentException("Cannot move head");
69+
}
70+
final var leader = knotCoordinates[knotIndex - 1];
71+
var follower = knotCoordinates[knotIndex];
72+
73+
if(leader.equals(follower)) {
74+
return;
75+
} else if (leader.distance(follower) <= 1) {
76+
return;
77+
}
78+
79+
follower = follower.stepTowards(leader);
80+
knotCoordinates[knotIndex] = follower;
81+
82+
if(knotIndex == knotCoordinates.length - 1) {
83+
visited.computeIfAbsent(follower.x(), (key) -> new TreeSet<>()).add(follower.y());
84+
}
85+
}
86+
87+
}
88+
89+
enum Direction {
90+
Up {
91+
int xStep() {
92+
return -1;
93+
}
94+
int yStep() {
95+
return 0;
96+
}
97+
},
98+
Down {
99+
int xStep() {
100+
return 1;
101+
}
102+
int yStep() {
103+
return 0;
104+
}
105+
},
106+
Left {
107+
int xStep() {
108+
return 0;
109+
}
110+
int yStep() {
111+
return -1;
112+
}
113+
},
114+
Right {
115+
int xStep() {
116+
return 0;
117+
}
118+
int yStep() {
119+
return 1;
120+
}
121+
};
122+
123+
abstract int xStep();
124+
abstract int yStep();
125+
126+
static Direction parse(final String string) {
127+
return switch(string.trim()) {
128+
case "U" -> Up;
129+
case "D" -> Down;
130+
case "L" -> Left;
131+
case "R" -> Right;
132+
default -> throw new IllegalArgumentException("Invalid direction: " + string);
133+
};
134+
}
135+
}
136+
137+
record Instruction(Direction direction, int distance) {
138+
static Instruction parse(final String string) {
139+
final var components = string.split(" ");
140+
final var direction = Direction.parse(components[0]);
141+
final var distance = Integer.parseInt(components[1]);
142+
return new Instruction(direction, distance);
143+
}
144+
}
145+
146+
protected Stream<Instruction> getInput() {
147+
return StreamSupport
148+
.stream(new LineSpliterator("day-09.txt"),
149+
false)
150+
.map(Instruction::parse);
151+
}
152+
153+
@Test
154+
public final void part1() {
155+
final var rope = new Rope(2);
156+
getInput().forEach(rope::process);
157+
final var result = rope.countVisited();
158+
System.out.println("Part 1: " + result);
159+
// NOT 7017
160+
}
161+
162+
@Test
163+
public final void part2() {
164+
final var rope = new Rope(10);
165+
getInput().forEach(rope::process);
166+
final var result = rope.countVisited();
167+
System.out.println("Part 2: " + result);
168+
}
169+
170+
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
R 4
2+
U 4
3+
L 3
4+
D 1
5+
R 4
6+
D 1
7+
L 5
8+
R 2

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy