-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
949 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package at.kocmana.aoc23.dec08; | ||
|
||
public enum Direction { | ||
L, R | ||
} |
76 changes: 76 additions & 0 deletions
76
src/main/java/at/kocmana/aoc23/dec08/HauntedWastelandPartOne.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package at.kocmana.aoc23.dec08; | ||
|
||
import at.kocmana.aoc23.common.ResourceToString; | ||
import at.kocmana.aoc23.common.Tuple; | ||
import java.util.AbstractMap; | ||
import java.util.Map; | ||
import java.util.regex.MatchResult; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
import java.util.stream.Collectors; | ||
|
||
public class HauntedWastelandPartOne { | ||
|
||
static final Pattern NETWORK_ENTRY_PATTERN = | ||
Pattern.compile("(?<source>[A-Z]{3}) = \\((?<left>[A-Z]{3}), (?<right>[A-Z]{3})\\)"); | ||
|
||
public static void main(String[] args) { | ||
var puzzleInput = ResourceToString.from("dec08", "HauntedWasteland.txt"); | ||
var map = parseMap(puzzleInput); | ||
var result = traverse(map); | ||
System.out.printf("Result: %d%n", result); | ||
} | ||
|
||
static int traverse(WastelandMap map) { | ||
var directions = map.directions(); | ||
var network = map.network(); | ||
|
||
var numberOfSteps = 0; | ||
var currentNode = "AAA"; | ||
while (!currentNode.equals("ZZZ")) { | ||
var currentDirection = directions.get(numberOfSteps % directions.size()); | ||
System.out.printf("Step %d. Current Node: %s, Possible Directions: %s, Next Move: %s%n", | ||
numberOfSteps, currentNode, network.get(currentNode), currentDirection); | ||
currentNode = network.get(currentNode).move(currentDirection); | ||
numberOfSteps++; | ||
} | ||
return numberOfSteps; | ||
} | ||
|
||
public static WastelandMap parseMap(String input) { | ||
var directionsAndNetwork = input.split("\\n", 3); | ||
|
||
var directions = directionsAndNetwork[0].chars() | ||
.mapToObj(c -> Direction.valueOf(String.valueOf((char) c))) | ||
.toList(); | ||
|
||
var network = directionsAndNetwork[2].lines() | ||
.map(NETWORK_ENTRY_PATTERN::matcher) | ||
.flatMap(Matcher::results) | ||
.map(HauntedWastelandPartOne::toNetworkNode) | ||
.collect(Collectors.toMap(Tuple::key, Tuple::value)); | ||
|
||
return new WastelandMap(directions, network); | ||
} | ||
|
||
static Tuple<String, Node> toNetworkNode(MatchResult matchResult) { | ||
return new Tuple<String, Node>( | ||
matchResult.group("source"), | ||
new Node(matchResult.group("left"), matchResult.group("right"))); | ||
} | ||
|
||
static Map.Entry<String, Node> toMapEntry(String input) { | ||
System.out.printf("Parsing input: %s%n", input); | ||
var result = NETWORK_ENTRY_PATTERN.matcher(input); | ||
|
||
return new AbstractMap.SimpleImmutableEntry<>( | ||
result.group("source"), | ||
new Node( | ||
result.group("left"), | ||
result.group("right") | ||
) | ||
); | ||
} | ||
|
||
|
||
} |
100 changes: 100 additions & 0 deletions
100
src/main/java/at/kocmana/aoc23/dec08/HauntedWastelandPartTwo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package at.kocmana.aoc23.dec08; | ||
|
||
import at.kocmana.aoc23.common.ResourceToString; | ||
import at.kocmana.aoc23.common.Tuple; | ||
import java.util.AbstractMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.regex.MatchResult; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
import java.util.stream.Collectors; | ||
|
||
public class HauntedWastelandPartTwo { | ||
|
||
static final Pattern NETWORK_ENTRY_PATTERN = | ||
Pattern.compile("(?<source>[A-Z]{3}) = \\((?<left>[A-Z]{3}), (?<right>[A-Z]{3})\\)"); | ||
|
||
public static void main(String[] args) { | ||
var puzzleInput = ResourceToString.from("dec08", "HauntedWasteland.txt"); | ||
var map = parseMap(puzzleInput); | ||
var result = play(map); | ||
System.out.printf("Result: %d%n", result); | ||
} | ||
|
||
static Long play(WastelandMap map) { | ||
return traverse(map); | ||
} | ||
|
||
static Long traverse(WastelandMap map) { | ||
var currentNodes = map.network().keySet().stream() | ||
.filter(node -> node.endsWith("A")) | ||
.map(node -> HauntedWastelandPartTwo.traversePerNode(map, node)) | ||
.toList(); | ||
|
||
return lcm(currentNodes); | ||
} | ||
|
||
static Long traversePerNode(WastelandMap map, String startNode) { | ||
var directions = map.directions(); | ||
var network = map.network(); | ||
|
||
var numberOfSteps = 0L; | ||
var currentNode = startNode; | ||
while (!currentNode.endsWith("Z")) { | ||
var currentDirection = directions.get((int) numberOfSteps % directions.size()); | ||
currentNode = network.get(currentNode).move(currentDirection); | ||
numberOfSteps++; | ||
} | ||
return numberOfSteps; | ||
} | ||
|
||
/* LCM Solution for n numbers taken from | ||
https://stackoverflow.com/questions/4201860/how-to-find-gcd-lcm-on-a-set-of-numbers | ||
*/ | ||
private static long gcd(long x, long y) { | ||
return (y == 0) ? x : gcd(y, x % y); | ||
} | ||
|
||
private static long lcm(List<Long> numbers) { | ||
return numbers.stream() | ||
.reduce(1L, (x, y) -> x * (y / gcd(x, y))); | ||
} | ||
|
||
public static WastelandMap parseMap(String input) { | ||
var directionsAndNetwork = input.split("\\n", 3); | ||
|
||
var directions = directionsAndNetwork[0].chars() | ||
.mapToObj(c -> Direction.valueOf(String.valueOf((char) c))) | ||
.toList(); | ||
|
||
var network = directionsAndNetwork[2].lines() | ||
.map(NETWORK_ENTRY_PATTERN::matcher) | ||
.flatMap(Matcher::results) | ||
.map(HauntedWastelandPartTwo::toNetworkNode) | ||
.collect(Collectors.toMap(Tuple::key, Tuple::value)); | ||
|
||
return new WastelandMap(directions, network); | ||
} | ||
|
||
static Tuple<String, Node> toNetworkNode(MatchResult matchResult) { | ||
return new Tuple<String, Node>( | ||
matchResult.group("source"), | ||
new Node(matchResult.group("left"), matchResult.group("right"))); | ||
} | ||
|
||
static Map.Entry<String, Node> toMapEntry(String input) { | ||
System.out.printf("Parsing input: %s%n", input); | ||
var result = NETWORK_ENTRY_PATTERN.matcher(input); | ||
|
||
return new AbstractMap.SimpleImmutableEntry<>( | ||
result.group("source"), | ||
new Node( | ||
result.group("left"), | ||
result.group("right") | ||
) | ||
); | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package at.kocmana.aoc23.dec08; | ||
|
||
public record Node ( | ||
String left, | ||
String right | ||
) { | ||
|
||
String move(Direction direction) { | ||
return switch (direction) { | ||
case L -> left; | ||
case R -> right; | ||
}; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package at.kocmana.aoc23.dec08; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public record WastelandMap( | ||
List<Direction> directions, | ||
Map<String, Node> network | ||
) {} |
Oops, something went wrong.