diff --git a/ReadMe.md b/ReadMe.md index 7f710696..bdfab720 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -6,6 +6,7 @@ | Year-Day | Task | Scala | Rust | Others | |----------|:-------------------------------------------------------------------------------|:-----------------------------------------------------------------------:|:----------------------------------------------:|:----------------------------------------------------------------------:| +| 2024-20 | [Race Condition](https://adventofcode.com/2024/day/20) | [Scala](scala2/src/main/scala/jurisk/adventofcode/y2024/Advent20.scala) | [Rust](rust/y2024/src/bin/solution_2024_20.rs) | | | 2024-19 | [Linen Layout](https://adventofcode.com/2024/day/19) | [Scala](scala2/src/main/scala/jurisk/adventofcode/y2024/Advent19.scala) | [Rust](rust/y2024/src/bin/solution_2024_19.rs) | | | 2024-18 | [RAM Run](https://adventofcode.com/2024/day/18) | [Scala](scala2/src/main/scala/jurisk/adventofcode/y2024/Advent18.scala) | [Rust](rust/y2024/src/bin/solution_2024_18.rs) | | | 2024-17 | [Chronospatial Computer](https://adventofcode.com/2024/day/17) | [Scala](scala2/src/main/scala/jurisk/adventofcode/y2024/Advent17.scala) | [Rust](rust/y2024/src/bin/solution_2024_17.rs) | | diff --git a/rust/y2024/resources/20-test-00.txt b/rust/y2024/resources/20-test-00.txt new file mode 100644 index 00000000..f107d405 --- /dev/null +++ b/rust/y2024/resources/20-test-00.txt @@ -0,0 +1,15 @@ +############### +#...#...#.....# +#.#.#.#.#.###.# +#S#...#.#.#...# +#######.#.#.### +#######.#.#...# +#######.#.###.# +###..E#...#...# +###.#######.### +#...###...#...# +#.#####.#.###.# +#.#...#.#.#...# +#.#.#.#.#.#.### +#...#...#...### +############### \ No newline at end of file diff --git a/rust/y2024/resources/20.txt b/rust/y2024/resources/20.txt new file mode 100644 index 00000000..4d4826d5 --- /dev/null +++ b/rust/y2024/resources/20.txt @@ -0,0 +1,141 @@ +############################################################################################################################################# +###...#.......#.....#...#...#...#.......#.......#.......###...#...###...#...#...#...#.......#...###...#...#...#.....#...#.............#...### +###.#.#.#####.#.###.#.#.#.#.#.#.#.#####.#.#####.#.#####.###.#.#.#.###.#.#.#.#.#.#.#.#.#####.#.#.###.#.#.#.#.#.#.###.#.#.#.###########.#.#.### +#...#.#.....#.#...#...#...#...#.#...#...#.....#.#.#.....#...#...#.#...#...#...#.#.#.#.....#.#.#.....#.#.#.#.#.#.#...#.#...#...#.....#...#...# +#.###.#####.#.###.#############.###.#.#######.#.#.#.#####.#######.#.###########.#.#.#####.#.#.#######.#.#.#.#.#.#.###.#####.#.#.###.#######.# +#...#.###...#.#...#...#...#...#...#.#.#...###.#.#.#.....#...#.....#...#.....#...#.#.....#.#...#.......#.#.#.#.#.#...#...#...#...###.........# +###.#.###.###.#.###.#.#.#.#.#.###.#.#.#.#.###.#.#.#####.###.#.#######.#.###.#.###.#####.#.#####.#######.#.#.#.#.###.###.#.################### +#...#...#...#.#.....#...#...#...#...#...#.#...#.#.#...#.#...#...#...#...###.#...#...#...#.#.....#...#...#.#.#...#...#...#...................# +#.#####.###.#.#################.#########.#.###.#.#.#.#.#.#####.#.#.#######.###.###.#.###.#.#####.#.#.###.#.#####.###.#####################.# +#.....#.#...#...#.........#...#.....#.....#...#.#.#.#...#...#...#.#...###...#...#...#...#.#.#...#.#.#...#...#...#.#...#.....#...#...........# +#####.#.#.#####.#.#######.#.#.#####.#.#######.#.#.#.#######.#.###.###.###.###.###.#####.#.#.#.#.#.#.###.#####.#.#.#.###.###.#.#.#.########### +#...#.#.#.#.....#.......#.#.#.......#...#...#.#...#...#...#.#...#...#...#...#...#...#...#.#.#.#...#...#.#.....#...#...#.###...#...#.........# +#.#.#.#.#.#.###########.#.#.###########.#.#.#.#######.#.#.#.###.###.###.###.###.###.#.###.#.#.#######.#.#.###########.#.###########.#######.# +#.#.#.#...#.#...#.....#.#.#.......#.....#.#.#...#.....#.#...#...###...#.....#...#...#...#.#.#.#.......#.#.#...#...#...#.......#...#.#.....#.# +#.#.#.#####.#.#.#.###.#.#.#######.#.#####.#.###.#.#####.#####.#######.#######.###.#####.#.#.#.#.#######.#.#.#.#.#.#.#########.#.#.#.#.###.#.# +#.#.#.....#.#.#.#...#.#.#.#.....#.#.###...#.....#.#.....#.....#...###.......#...#...#...#.#.#.#.#.....#.#.#.#.#.#.#.#.......#.#.#...#.###...# +#.#.#####.#.#.#.###.#.#.#.#.###.#.#.###.#########.#.#####.#####.#.#########.###.###.#.###.#.#.#.#.###.#.#.#.#.#.#.#.#.#####.#.#.#####.####### +#.#.......#...#.....#...#.#...#.#.#...#.........#.#.#.....###...#...#...#...#...#...#.....#...#...#...#.#.#.#...#...#.....#...#.#.....#.....# +#.#######################.###.#.#.###.#########.#.#.#.#######.#####.#.#.#.###.###.#################.###.#.#.#############.#####.#.#####.###.# +#.#...#...#...#.........#...#.#.#...#.#...#.....#...#...#...#.#.....#.#.#...#.###.......#...........#...#.#...#...........###...#.....#.#...# +#.#.#.#.#.#.#.#.#######.###.#.#.###.#.#.#.#.###########.#.#.#.#.#####.#.###.#.#########.#.###########.###.###.#.#############.#######.#.#.### +#...#...#...#...#.......#...#.#...#.#.#.#.#.....#.......#.#.#.#.#...#.#.#...#...#.......#.....#...###...#.###.#.#...#.......#...#.....#.#...# +#################.#######.###.###.#.#.#.#.#####.#.#######.#.#.#.#.#.#.#.#.#####.#.###########.#.#.#####.#.###.#.#.#.#.#####.###.#.#####.###.# +#.....#...#...###.......#...#...#.#.#.#.#.#...#.#.#.....#.#...#...#.#.#.#...#...#...#.........#.#.....#.#.#...#...#.#.#.....#...#.#...#.#...# +#.###.#.#.#.#.#########.###.###.#.#.#.#.#.#.#.#.#.#.###.#.#########.#.#.###.#.#####.#.#########.#####.#.#.#.#######.#.#.#####.###.#.#.#.#.### +#...#...#.#.#.#...#...#.#...#...#.#.#.#.#.#.#...#.#.#...#...#.....#.#.#.#...#.#...#.#...#...###.#.....#.#.#...#.....#.#.#...#.#...#.#.#.#...# +###.#####.#.#.#.#.#.#.#.#.###.###.#.#.#.#.#.#####.#.#.#####.#.###.#.#.#.#.###.#.#.#.###.#.#.###.#.#####.#.###.#.#####.#.#.#.#.#.###.#.#.###.# +###.#...#...#...#...#...#.###...#.#.#.#.#.#...#...#.#.#.....#...#...#.#.#...#.#.#...#...#.#...#.#...#...#.#...#.#...#.#.#.#...#.#...#...#...# +###.#.#.#################.#####.#.#.#.#.#.###.#.###.#.#.#######.#####.#.###.#.#.#####.###.###.#.###.#.###.#.###.#.#.#.#.#.#####.#.#######.### +#...#.#.............#...#.....#.#.#.#.#.#.###.#.###.#.#...#.....#...#.#.#...#.#...#...###.#...#.#...#.#...#.#...#.#...#.#.#.....#.#.......### +#.###.#############.#.#.#####.#.#.#.#.#.#.###.#.###.#.###.#.#####.#.#.#.#.###.###.#.#####.#.###.#.###.#.###.#.###.#####.#.#.#####.#.######### +#...#.#...........#...#.....#.#.#.#.#.#.#...#.#...#.#...#.#...#...#.#.#...#...###.#.#...#.#...#.#...#.#...#.#.###.#.....#.#.#...#.#.#.......# +###.#.#.#########.#########.#.#.#.#.#.#.###.#.###.#.###.#.###.#.###.#.#####.#####.#.#.#.#.###.#.###.#.###.#.#.###.#.#####.#.#.#.#.#.#.#####.# +###...#.........#.###.......#...#...#.#...#.#.#...#...#.#.#...#.#...#.....#.#...#.#.#.#.#...#.#.#...#.#...#.#.#...#...###.#.#.#.#.#.#.#.....# +###############.#.###.###############.###.#.#.#.#####.#.#.#.###.#.#######.#.#.#.#.#.#.#.###.#.#.#.###.#.###.#.#.#####.###.#.#.#.#.#.#.#.##### +#...#...#.......#.....#.............#.....#.#.#.#...#.#.#.#...#.#.....#...#...#.#.#...#.....#.#.#...#.#...#.#...#...#.....#...#...#...#.#...# +#.#.#.#.#.#############.###########.#######.#.#.#.#.#.#.#.###.#.#####.#.#######.#.###########.#.###.#.###.#.#####.#.###################.#.#.# +#.#...#...#...#...#.....###...#...#.#.....#.#.#.#.#.#.#.#.###.#.....#...#.......#...........#...#...#.#...#.#.....#.........#.........#...#.# +#.#########.#.#.#.#.#######.#.#.#.#.#.###.#.#.#.#.#.#.#.#.###.#####.#####.#################.#####.###.#.###.#.#############.#.#######.#####.# +#.....#...#.#.#.#.#.#.......#...#...#.#...#...#.#.#.#.#.#.#...#...#...###.#.....#.....#...#...###.....#.....#...#.......#...#.......#.#...#.# +#####.#.#.#.#.#.#.#.#.###############.#.#######.#.#.#.#.#.#.###.#.###.###.#.###.#.###.#.#.###.#################.#.#####.#.#########.#.#.#.#.# +#...#...#.#.#...#...#.................#.#...###.#.#.#.#...#...#.#.#...#...#.#...#...#.#.#.#...#...#...........#...#...#.#.#.......#.#...#...# +#.#.#####.#.###########################.#.#.###.#.#.#.#######.#.#.#.###.###.#.#####.#.#.#.#.###.#.#.#########.#####.#.#.#.#.#####.#.######### +#.#.#.....#.#.........................#...#...#.#.#.#.###.....#.#.#.###...#.#.#...#.#...#...#...#...#.......#.......#...#...#.....#...#...### +#.#.#.#####.#.#######################.#######.#.#.#.#.###.#####.#.#.#####.#.#.#.#.#.#########.#######.#####.#################.#######.#.#.### +#.#...#.....#.......................#.#.....#.#.#.#.#.#...#...#.#.#...###...#.#.#.#...#...###.#.......###...###...#...#...###...#...#...#...# +#.#####.###########################.#.#.###.#.#.#.#.#.#.###.#.#.#.###.#######.#.#.###.#.#.###.#.#########.#####.#.#.#.#.#.#####.#.#.#######.# +#.#.....#.....#...........#...#.....#.#...#.#.#.#.#...#.....#.#.#...#...#.....#.#...#...#...#...#...#...#.......#...#...#.....#.#.#...#...#.# +#.#.#####.###.#.#########.#.#.#.#####.###.#.#.#.#.###########.#.###.###.#.#####.###.#######.#####.#.#.#.#####################.#.#.###.#.#.#.# +#...###...#...#.........#...#.#.....#.....#...#.#...###.......#.###.#...#...#...#...#.....#.#.....#...#.................#.....#...#...#.#.#.# +#######.###.###########.#####.#####.###########.###.###.#######.###.#.#####.#.###.###.###.#.#.#########################.#.#########.###.#.#.# +###...#...#.#...#...###.....#.....#.........###...#...#.#.....#.#...#...###.#.###...#...#...#...............#.........#...#.......#.#...#...# +###.#.###.#.#.#.#.#.#######.#####.#########.#####.###.#.#.###.#.#.#####.###.#.#####.###.###################.#.#######.#####.#####.#.#.####### +#...#.....#...#.#.#.#...#...#...#...........#...#.#...#...###...#.#...#...#.#.....#...#.....#.....#.........#.#.....#.#.....#.....#...###...# +#.#############.#.#.#.#.#.###.#.#############.#.#.#.#############.#.#.###.#.#####.###.#####.#.###.#.#########.#.###.#.#.#####.###########.#.# +#.............#...#...#.#.....#...........#...#.#...###..E#.......#.#...#.#...#...###...#...#...#.#...........#...#...#.....#.#...#.....#.#.# +#############.#########.#################.#.###.#######.###.#######.###.#.###.#.#######.#.#####.#.###############.#########.#.#.#.#.###.#.#.# +#...........#.........#...................#.#...#.......###.....#...#...#.###.#.#.....#...#...#.#.......#.......#...###...#.#...#...#...#.#.# +#.#########.#########.#####################.#.###.#############.#.###.###.###.#.#.###.#####.#.#.#######.#.#####.###.###.#.#.#########.###.#.# +#.........#...........#.................###.#.###.###########...#...#...#...#.#.#...#.......#...#.....#...#...#...#...#.#.#.#...#.....###.#.# +#########.#############.###############.###.#.###.###########.#####.###.###.#.#.###.#############.###.#####.#.###.###.#.#.#.#.#.#.#######.#.# +#.........#.....#.......#.........#...#.....#.....###########...#...#...#...#...#...#...#.....#...###.#.....#...#.....#.#.#.#.#...###.....#.# +#.#########.###.#.#######.#######.#.#.#########################.#.###.###.#######.###.#.#.###.#.#####.#.#######.#######.#.#.#.#######.#####.# +#.........#...#.#...#.....#.....#...#S#########################...###...#.....###.....#...###...#...#...#.......###.....#...#.......#.#.....# +#########.###.#.###.#.#####.###.#######################################.#####.###################.#.#####.#########.###############.#.#.##### +#.........#...#.....#.....#.###.............###########################...#...#...#...###.........#.....#...........#.........#.....#.#.#...# +#.#########.#############.#.###############.#############################.#.###.#.#.#.###.#############.#############.#######.#.#####.#.#.#.# +#...#...#...###...#...###...#...............#############################.#...#.#.#.#...#.............#.....#.......#.......#.#...#...#...#.# +###.#.#.#.#####.#.#.#.#######.###########################################.###.#.#.#.###.#############.#####.#.#####.#######.#.###.#.#######.# +###...#...#.....#...#.........#...........###############################.....#.#...#...###...#.....#.....#...#...#.....#...#.....#.#.....#.# +###########.###################.#########.#####################################.#####.#####.#.#.###.#####.#####.#.#####.#.#########.#.###.#.# +#.........#.#...................#.........#...###.......#######################.#...#.#...#.#.#...#.#...#.......#.....#...#####...#.#...#.#.# +#.#######.#.#.###################.#########.#.###.#####.#######################.#.#.#.#.#.#.#.###.#.#.#.#############.#########.#.#.###.#.#.# +#.......#.#...#...#...#...#...###...........#.....#...#.....#################...#.#.#...#...#.....#...#.....#...#...#.#.....#...#...#...#...# +#######.#.#####.#.#.#.#.#.#.#.#####################.#.#####.#################.###.#.#######################.#.#.#.#.#.#.###.#.#######.####### +#.....#.#...#...#...#...#...#...........#...#...#...#.#.....#.......###...###.....#.....#...#...#.........#...#...#...#...#.#...#.....#...### +#.###.#.###.#.#########################.#.#.#.#.#.###.#.#####.#####.###.#.#############.#.#.#.#.#.#######.###############.#.###.#.#####.#.### +#...#.#...#.#.........#.....#...#...###...#...#...###...#...#.#.....#...#.#.............#.#...#...###...#...........###...#.....#.......#...# +###.#.###.#.#########.#.###.#.#.#.#.#####################.#.#.#.#####.###.#.#############.###########.#.###########.###.###################.# +#...#.....#...........#.###.#.#...#...............#...#...#...#...#...#...#...............#...........#.............#...#...#.........#...#.# +#.#####################.###.#.###################.#.#.#.#########.#.###.###################.#########################.###.#.#.#######.#.#.#.# +#.#.....#...........#...#...#.#.......#...........#.#.#...#.......#...#.#.....#.....#...###...#.....#...............#...#.#.#.......#.#.#.#.# +#.#.###.#.#########.#.###.###.#.#####.#.###########.#.###.#.#########.#.#.###.#.###.#.#.#####.#.###.#.#############.###.#.#.#######.#.#.#.#.# +#...###.#.#.........#...#...#.#.#...#...#.......#...#.#...#...#...#...#.#.#...#...#...#.......#.###.#.#.....#.......###.#.#.........#.#.#.#.# +#######.#.#.###########.###.#.#.#.#.#####.#####.#.###.#.#####.#.#.#.###.#.#.#####.#############.###.#.#.###.#.#########.#.###########.#.#.#.# +#.....#.#.#.........#...###...#...#.......#.....#.#...#.....#...#.#...#.#.#.#...#.........#...#.#...#.#...#...#...#.....#...#.......#...#...# +#.###.#.#.#########.#.#####################.#####.#.#######.#####.###.#.#.#.#.#.#########.#.#.#.#.###.###.#####.#.#.#######.#.#####.######### +#.#...#...#.........#.#.....#.............#.#.....#...#...#.#.....#...#.#.#.#.#...#.....#...#.#.#.....###.......#...#.....#...#...#.........# +#.#.#######.#########.#.###.#.###########.#.#.#######.#.#.#.#.#####.###.#.#.#.###.#.###.#####.#.#####################.###.#####.#.#########.# +#.#...#...#.........#.#.#...#...........#.#...#.......#.#...#.#...#...#.#.#...#...#...#...###...#.............#...#...###.#...#.#...........# +#.###.#.#.#########.#.#.#.#############.#.#####.#######.#####.#.#.###.#.#.#####.#####.###.#######.###########.#.#.#.#####.#.#.#.############# +#...#...#.###...###...#.#.............#.#...#...#.....#.....#...#...#.#.#.#.....#...#...#.#.....#...........#...#.#.....#.#.#...###...#...### +###.#####.###.#.#######.#############.#.###.#.###.###.#####.#######.#.#.#.#.#####.#.###.#.#.###.###########.#####.#####.#.#.#######.#.#.#.### +###.....#.....#.........#...........#.#.###...###...#.#...#.#.....#...#...#.......#.#...#.#.#...#.......#...#...#.....#.#...#.......#...#...# +#######.#################.#########.#.#.###########.#.#.#.#.#.###.#################.#.###.#.#.###.#####.#.###.#.#####.#.#####.#############.# +#.......#...#.....#.......#.........#.#.#.......#...#.#.#.#...###.....#.........#...#...#...#.....#...#.#.....#.....#...#...#.#...........#.# +#.#######.#.#.###.#.#######.#########.#.#.#####.#.###.#.#.###########.#.#######.#.#####.###########.#.#.###########.#####.#.#.#.#########.#.# +#.......#.#.#.###...#.....#.........#...#.#.....#...#.#.#.###.....#...#.....###...#...#.............#.#.....#.....#...#...#...#.....#...#...# +#######.#.#.#.#######.###.#########.#####.#.#######.#.#.#.###.###.#.#######.#######.#.###############.#####.#.###.###.#.###########.#.#.##### +#...###...#...#...###...#.#...#.....###...#.....###.#.#.#.#...#...#...#.....#...###.#.###.....#.....#.....#.#...#...#...#...#.....#...#.....# +#.#.###########.#.#####.#.#.#.#.#######.#######.###.#.#.#.#.###.#####.#.#####.#.###.#.###.###.#.###.#####.#.###.###.#####.#.#.###.#########.# +#.#.............#.#...#.#.#.#.#.......#.#.......#...#...#.#.#...#...#.#.....#.#...#.#.#...#...#...#...#...#.....###.......#...###.#...#...#.# +#.###############.#.#.#.#.#.#.#######.#.#.#######.#######.#.#.###.#.#.#####.#.###.#.#.#.###.#####.###.#.#########################.#.#.#.#.#.# +#.#...#.....#...#...#...#...#.........#.#.###...#.......#.#.#.###.#.#.#.....#.#...#.#.#...#.#...#.#...#...........#.........#.....#.#...#.#.# +#.#.#.#.###.#.#.#######################.#.###.#.#######.#.#.#.###.#.#.#.#####.#.###.#.###.#.#.#.#.#.#############.#.#######.#.#####.#####.#.# +#.#.#...###...#...#.............#.....#.#...#.#.#...#...#.#.#...#.#.#.#.....#.#.#...#...#.#.#.#.#.#.....#...#...#...#...#...#.....#.....#.#.# +#.#.#############.#.###########.#.###.#.###.#.#.#.#.#.###.#.###.#.#.#.#####.#.#.#.#####.#.#.#.#.#.#####.#.#.#.#.#####.#.#.#######.#####.#.#.# +#.#.#.............#.#...#.......#...#.#.#...#.#.#.#.#.#...#.#...#.#.#.#.....#.#.#...#...#.#.#.#.#...###.#.#...#.#...#.#...#.....#.#...#.#.#.# +#.#.#.#############.#.#.#.#########.#.#.#.###.#.#.#.#.#.###.#.###.#.#.#.#####.#.###.#.###.#.#.#.###.###.#.#####.#.#.#.#####.###.#.#.#.#.#.#.# +#...#...............#.#.#.......#...#...#.....#.#.#...#.#...#...#.#.#.#...#...#.#...#.....#.#.#.#...#...#...###...#.#.......#...#.#.#.#.#.#.# +#####################.#.#######.#.#############.#.#####.#.#####.#.#.#.###.#.###.#.#########.#.#.#.###.#####.#######.#########.###.#.#.#.#.#.# +#.................#...#.........#.#.............#...#...#.#...#.#.#...#...#...#.#.#...#.....#.#.#...#.#...#.......#...........###...#.#.#.#.# +#.###############.#.#############.#.###############.#.###.#.#.#.#.#####.#####.#.#.#.#.#.#####.#.###.#.#.#.#######.###################.#.#.#.# +#.........#.....#...#...#.....#...#...#...#.....#...#...#...#.#.#.....#...#...#.#...#.#...#...#...#.#.#.#...#...#...................#...#...# +#########.#.###.#####.#.#.###.#.#####.#.#.#.###.#.#####.#####.#.#####.###.#.###.#####.###.#.#####.#.#.#.###.#.#.###################.######### +#...#...#...###.....#.#...#...#.....#.#.#.#.#...#.#####...#...#.#...#.#...#.###.#.....###.#.#.....#.#...###.#.#.#...#.....#.........###...### +#.#.#.#.###########.#.#####.#######.#.#.#.#.#.###.#######.#.###.#.#.#.#.###.###.#.#######.#.#.#####.#######.#.#.#.#.#.###.#.###########.#.### +#.#...#.............#.#...#.....#...#.#.#.#.#...#...#.....#.#...#.#.#.#...#.#...#.....#...#.#.#...#...###...#.#.#.#...###.#.......#.....#...# +#.###################.#.#.#####.#.###.#.#.#.###.###.#.#####.#.###.#.#.###.#.#.#######.#.###.#.#.#.###.###.###.#.#.#######.#######.#.#######.# +#...........#...#...#...#...#...#...#.#.#...#...#...#.#...#.#.#...#.#.###...#.#.......#.#...#...#...#...#...#.#.#.......#.#...#...#.#.......# +###########.#.#.#.#.#######.#.#####.#.#.#####.###.###.#.#.#.#.#.###.#.#######.#.#######.#.#########.###.###.#.#.#######.#.#.#.#.###.#.####### +#...........#.#...#.#...#...#...#...#.#...#...#...#...#.#.#.#.#...#.#.#.......#.....#...#.........#...#...#.#.#.#...#...#...#.#.....#.....### +#.###########.#####.#.#.#.#####.#.###.###.#.###.###.###.#.#.#.###.#.#.#.###########.#.###########.###.###.#.#.#.#.#.#.#######.###########.### +#.#.....#...#.#.....#.#.#.#...#.#...#...#.#...#.###.....#.#.#.....#...#.....#...#...#.#...#.......###...#.#.#.#...#.#.......#...#...#...#...# +#.#.###.#.#.#.#.#####.#.#.#.#.#.###.###.#.###.#.#########.#.###############.#.#.#.###.#.#.#.###########.#.#.#.#####.#######.###.#.#.#.#.###.# +#...###...#...#.#...#.#.#.#.#...#...###...#...#...###...#.#...#...###.......#.#...###...#...#...###...#.#.#.#.....#.........###.#.#.#.#...#.# +###############.#.#.#.#.#.#.#####.#########.#####.###.#.#.###.#.#.###.#######.###############.#.###.#.#.#.#.#####.#############.#.#.#.###.#.# +#.....#.........#.#.#.#...#.....#.....###...#...#.....#.#.#...#.#.....#.....#.................#...#.#...#.#.#.....#...........#.#.#...###...# +#.###.#.#########.#.#.#########.#####.###.###.#.#######.#.#.###.#######.###.#####################.#.#####.#.#.#####.#########.#.#.########### +#...#.#.........#.#.#.....#.....#...#.#...#...#...#.....#.#...#.#.....#.#...#.....#...#...#.......#.....#.#.#.#.....#.....#...#.#...........# +###.#.#########.#.#.#####.#.#####.#.#.#.###.#####.#.#####.###.#.#.###.#.#.###.###.#.#.#.#.#.###########.#.#.#.#.#####.###.#.###.###########.# +#...#.........#.#.#...#...#.....#.#...#.#...#.....#.....#.....#...#...#.#...#...#.#.#.#.#.#.....#.......#.#.#...#.....###...#...#...#...#...# +#.###########.#.#.###.#.#######.#.#####.#.###.#########.###########.###.###.###.#.#.#.#.#.#####.#.#######.#.#####.###########.###.#.#.#.#.### +#.#.....#...#...#.#...#.#.......#...#...#...#...#.....#...#.....#...#...###...#.#...#.#.#...#...#.....#...#.....#...........#.#...#...#...### +#.#.###.#.#.#####.#.###.#.#########.#.#####.###.#.###.###.#.###.#.###.#######.#.#####.#.###.#.#######.#.#######.###########.#.#.############# +#.#.#...#.#...#...#.#...#.......#...#.#.....###...#...#...#...#...#...#...#...#...#...#.###.#.......#.#.......#.#...........#.#...........### +#.#.#.###.###.#.###.#.#########.#.###.#.###########.###.#####.#####.###.#.#.#####.#.###.###.#######.#.#######.#.#.###########.###########.### +#.#.#...#...#.#...#.#.....#.....#.#...#...#.........#...#.....#...#.....#.#...#...#...#.#...#...#...#.#...#...#.#...........#...#...#...#...# +#.#.###.###.#.###.#.#####.#.#####.#.#####.#.#########.###.#####.#.#######.###.#.#####.#.#.###.#.#.###.#.#.#.###.###########.###.#.#.#.#.###.# +#...###.....#.....#.......#.......#.......#...........###.......#.........###...#####...#.....#...###...#...###.............###...#...#.....# +############################################################################################################################################# \ No newline at end of file diff --git a/rust/y2024/src/bin/solution_2024_20.rs b/rust/y2024/src/bin/solution_2024_20.rs new file mode 100644 index 00000000..76e90d8c --- /dev/null +++ b/rust/y2024/src/bin/solution_2024_20.rs @@ -0,0 +1,157 @@ +use std::collections::{HashMap, HashSet}; + +use advent_of_code_common::grid2d::{Coords, Grid2D, MatrixGrid2D}; +use advent_of_code_common::parsing::Error; +use pathfinding::prelude::dijkstra_all; + +const DATA: &str = include_str!("../../resources/20.txt"); + +type N = i32; +type R = usize; +type Input = (Coords, MatrixGrid2D, Coords); + +#[derive(Eq, PartialEq, Hash, Debug)] +struct Cheat { + from: Coords, + to: Coords, + distance: N, +} + +fn parse(input: &str) -> Result { + let char_field = MatrixGrid2D::parse_char_field(input); + let start = char_field + .find_coords_by_value(&'S') + .ok_or("Start not found")?; + let end = char_field + .find_coords_by_value(&'E') + .ok_or("End not found")?; + let field = char_field.map_by_values(|c| { + match c { + '#' => true, + 'S' | 'E' | '.' => false, + _ => panic!("Unknown character {c} in field"), + } + }); + Ok((start, field, end)) +} + +fn solve(data: &Input, save_at_least: N, max_cheat: N) -> R { + let (start, field, end) = data; + + let successors = |position: &Coords| -> Vec<(Coords, N)> { + field + .neighbours_for(*position, false) + .into_iter() + .filter(|n| field.get(*n).is_some_and(|b| !*b)) + .map(|n| (n, 1)) + .collect() + }; + + let from_start: HashMap = dijkstra_all(start, successors); + let from_end: HashMap = dijkstra_all(end, successors); + + let (_, cost) = from_start.get(end).expect("No path from start to end"); + let goal_cost_threshold = cost - save_at_least; + + println!("Without cheats = {cost}, goal cost threshold = {goal_cost_threshold}"); + + let valid_cheat = |cheat: &Cheat| -> bool { + let start_cost = from_start + .get(&cheat.from) + .map(|(_, c)| *c) + .unwrap_or_default(); + let end_cost = from_end.get(&cheat.to).map(|(_, c)| *c).unwrap_or_default(); + start_cost + end_cost + cheat.distance <= goal_cost_threshold + }; + + let empties: Vec<_> = field + .coords() + .filter(|c| field.get(*c).is_some_and(|b| !*b)) + .collect(); + + let mut valid_cheats = HashSet::new(); + + // Could be optimised by avoiding processing all O(N^2), as if we know one coordinate, we can generate all others within maxCheat distance more efficiently + for from in &empties { + for to in &empties { + let from = *from; + let to = *to; + let distance = from.manhattan_distance(to); + if (1 ..= max_cheat).contains(&distance) { + let cheat = Cheat { from, to, distance }; + if valid_cheat(&cheat) { + valid_cheats.insert(cheat); + } + } + } + } + + valid_cheats.len() +} + +fn solve_1(data: &Input, save_at_least: N) -> R { + solve(data, save_at_least, 2) +} + +fn solve_2(data: &Input, save_at_least: N) -> R { + solve(data, save_at_least, 20) +} + +fn main() -> Result<(), Error> { + let data = parse(DATA)?; + + let result_1 = solve_1(&data, 100); + println!("Part 1: {result_1}"); + + let result_2 = solve_2(&data, 100); + println!("Part 2: {result_2}"); + + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + + const TEST_DATA: &str = include_str!("../../resources/20-test-00.txt"); + + fn test_data() -> Input { + parse(TEST_DATA).unwrap() + } + + fn real_data() -> Input { + parse(DATA).unwrap() + } + + #[test] + fn test_solve_1_test() { + assert_eq!(solve_1(&test_data(), 64), 1); + assert_eq!(solve_1(&test_data(), 40), 2); + assert_eq!(solve_1(&test_data(), 38), 3); + assert_eq!(solve_1(&test_data(), 36), 4); + assert_eq!(solve_1(&test_data(), 20), 5); + assert_eq!(solve_1(&test_data(), 12), 5 + 3); + assert_eq!(solve_1(&test_data(), 10), 5 + 3 + 2); + assert_eq!(solve_1(&test_data(), 8), 5 + 3 + 2 + 4); + assert_eq!(solve_1(&test_data(), 6), 5 + 3 + 2 + 4 + 2); + assert_eq!(solve_1(&test_data(), 4), 5 + 3 + 2 + 4 + 2 + 14); + assert_eq!(solve_1(&test_data(), 2), 5 + 3 + 2 + 4 + 2 + 14 + 14); + } + + #[test] + #[ignore] + fn test_solve_1_real() { + assert_eq!(solve_1(&real_data(), 100), 1293); + } + + #[test] + fn test_solve_2_test() { + assert_eq!(solve_2(&test_data(), 76), 3); + } + + #[test] + #[ignore] + fn test_solve_2_real() { + assert_eq!(solve_2(&real_data(), 100), 977_747); + } +} diff --git a/scala2/src/main/resources/2024/20-test-00.txt b/scala2/src/main/resources/2024/20-test-00.txt index a8b6c947..f107d405 100644 --- a/scala2/src/main/resources/2024/20-test-00.txt +++ b/scala2/src/main/resources/2024/20-test-00.txt @@ -1 +1,15 @@ -noop \ No newline at end of file +############### +#...#...#.....# +#.#.#.#.#.###.# +#S#...#.#.#...# +#######.#.#.### +#######.#.#...# +#######.#.###.# +###..E#...#...# +###.#######.### +#...###...#...# +#.#####.#.###.# +#.#...#.#.#...# +#.#.#.#.#.#.### +#...#...#...### +############### \ No newline at end of file diff --git a/scala2/src/main/resources/2024/20.txt b/scala2/src/main/resources/2024/20.txt index a8b6c947..4d4826d5 100644 --- a/scala2/src/main/resources/2024/20.txt +++ b/scala2/src/main/resources/2024/20.txt @@ -1 +1,141 @@ -noop \ No newline at end of file +############################################################################################################################################# +###...#.......#.....#...#...#...#.......#.......#.......###...#...###...#...#...#...#.......#...###...#...#...#.....#...#.............#...### +###.#.#.#####.#.###.#.#.#.#.#.#.#.#####.#.#####.#.#####.###.#.#.#.###.#.#.#.#.#.#.#.#.#####.#.#.###.#.#.#.#.#.#.###.#.#.#.###########.#.#.### +#...#.#.....#.#...#...#...#...#.#...#...#.....#.#.#.....#...#...#.#...#...#...#.#.#.#.....#.#.#.....#.#.#.#.#.#.#...#.#...#...#.....#...#...# +#.###.#####.#.###.#############.###.#.#######.#.#.#.#####.#######.#.###########.#.#.#####.#.#.#######.#.#.#.#.#.#.###.#####.#.#.###.#######.# +#...#.###...#.#...#...#...#...#...#.#.#...###.#.#.#.....#...#.....#...#.....#...#.#.....#.#...#.......#.#.#.#.#.#...#...#...#...###.........# +###.#.###.###.#.###.#.#.#.#.#.###.#.#.#.#.###.#.#.#####.###.#.#######.#.###.#.###.#####.#.#####.#######.#.#.#.#.###.###.#.################### +#...#...#...#.#.....#...#...#...#...#...#.#...#.#.#...#.#...#...#...#...###.#...#...#...#.#.....#...#...#.#.#...#...#...#...................# +#.#####.###.#.#################.#########.#.###.#.#.#.#.#.#####.#.#.#######.###.###.#.###.#.#####.#.#.###.#.#####.###.#####################.# +#.....#.#...#...#.........#...#.....#.....#...#.#.#.#...#...#...#.#...###...#...#...#...#.#.#...#.#.#...#...#...#.#...#.....#...#...........# +#####.#.#.#####.#.#######.#.#.#####.#.#######.#.#.#.#######.#.###.###.###.###.###.#####.#.#.#.#.#.#.###.#####.#.#.#.###.###.#.#.#.########### +#...#.#.#.#.....#.......#.#.#.......#...#...#.#...#...#...#.#...#...#...#...#...#...#...#.#.#.#...#...#.#.....#...#...#.###...#...#.........# +#.#.#.#.#.#.###########.#.#.###########.#.#.#.#######.#.#.#.###.###.###.###.###.###.#.###.#.#.#######.#.#.###########.#.###########.#######.# +#.#.#.#...#.#...#.....#.#.#.......#.....#.#.#...#.....#.#...#...###...#.....#...#...#...#.#.#.#.......#.#.#...#...#...#.......#...#.#.....#.# +#.#.#.#####.#.#.#.###.#.#.#######.#.#####.#.###.#.#####.#####.#######.#######.###.#####.#.#.#.#.#######.#.#.#.#.#.#.#########.#.#.#.#.###.#.# +#.#.#.....#.#.#.#...#.#.#.#.....#.#.###...#.....#.#.....#.....#...###.......#...#...#...#.#.#.#.#.....#.#.#.#.#.#.#.#.......#.#.#...#.###...# +#.#.#####.#.#.#.###.#.#.#.#.###.#.#.###.#########.#.#####.#####.#.#########.###.###.#.###.#.#.#.#.###.#.#.#.#.#.#.#.#.#####.#.#.#####.####### +#.#.......#...#.....#...#.#...#.#.#...#.........#.#.#.....###...#...#...#...#...#...#.....#...#...#...#.#.#.#...#...#.....#...#.#.....#.....# +#.#######################.###.#.#.###.#########.#.#.#.#######.#####.#.#.#.###.###.#################.###.#.#.#############.#####.#.#####.###.# +#.#...#...#...#.........#...#.#.#...#.#...#.....#...#...#...#.#.....#.#.#...#.###.......#...........#...#.#...#...........###...#.....#.#...# +#.#.#.#.#.#.#.#.#######.###.#.#.###.#.#.#.#.###########.#.#.#.#.#####.#.###.#.#########.#.###########.###.###.#.#############.#######.#.#.### +#...#...#...#...#.......#...#.#...#.#.#.#.#.....#.......#.#.#.#.#...#.#.#...#...#.......#.....#...###...#.###.#.#...#.......#...#.....#.#...# +#################.#######.###.###.#.#.#.#.#####.#.#######.#.#.#.#.#.#.#.#.#####.#.###########.#.#.#####.#.###.#.#.#.#.#####.###.#.#####.###.# +#.....#...#...###.......#...#...#.#.#.#.#.#...#.#.#.....#.#...#...#.#.#.#...#...#...#.........#.#.....#.#.#...#...#.#.#.....#...#.#...#.#...# +#.###.#.#.#.#.#########.###.###.#.#.#.#.#.#.#.#.#.#.###.#.#########.#.#.###.#.#####.#.#########.#####.#.#.#.#######.#.#.#####.###.#.#.#.#.### +#...#...#.#.#.#...#...#.#...#...#.#.#.#.#.#.#...#.#.#...#...#.....#.#.#.#...#.#...#.#...#...###.#.....#.#.#...#.....#.#.#...#.#...#.#.#.#...# +###.#####.#.#.#.#.#.#.#.#.###.###.#.#.#.#.#.#####.#.#.#####.#.###.#.#.#.#.###.#.#.#.###.#.#.###.#.#####.#.###.#.#####.#.#.#.#.#.###.#.#.###.# +###.#...#...#...#...#...#.###...#.#.#.#.#.#...#...#.#.#.....#...#...#.#.#...#.#.#...#...#.#...#.#...#...#.#...#.#...#.#.#.#...#.#...#...#...# +###.#.#.#################.#####.#.#.#.#.#.###.#.###.#.#.#######.#####.#.###.#.#.#####.###.###.#.###.#.###.#.###.#.#.#.#.#.#####.#.#######.### +#...#.#.............#...#.....#.#.#.#.#.#.###.#.###.#.#...#.....#...#.#.#...#.#...#...###.#...#.#...#.#...#.#...#.#...#.#.#.....#.#.......### +#.###.#############.#.#.#####.#.#.#.#.#.#.###.#.###.#.###.#.#####.#.#.#.#.###.###.#.#####.#.###.#.###.#.###.#.###.#####.#.#.#####.#.######### +#...#.#...........#...#.....#.#.#.#.#.#.#...#.#...#.#...#.#...#...#.#.#...#...###.#.#...#.#...#.#...#.#...#.#.###.#.....#.#.#...#.#.#.......# +###.#.#.#########.#########.#.#.#.#.#.#.###.#.###.#.###.#.###.#.###.#.#####.#####.#.#.#.#.###.#.###.#.###.#.#.###.#.#####.#.#.#.#.#.#.#####.# +###...#.........#.###.......#...#...#.#...#.#.#...#...#.#.#...#.#...#.....#.#...#.#.#.#.#...#.#.#...#.#...#.#.#...#...###.#.#.#.#.#.#.#.....# +###############.#.###.###############.###.#.#.#.#####.#.#.#.###.#.#######.#.#.#.#.#.#.#.###.#.#.#.###.#.###.#.#.#####.###.#.#.#.#.#.#.#.##### +#...#...#.......#.....#.............#.....#.#.#.#...#.#.#.#...#.#.....#...#...#.#.#...#.....#.#.#...#.#...#.#...#...#.....#...#...#...#.#...# +#.#.#.#.#.#############.###########.#######.#.#.#.#.#.#.#.###.#.#####.#.#######.#.###########.#.###.#.###.#.#####.#.###################.#.#.# +#.#...#...#...#...#.....###...#...#.#.....#.#.#.#.#.#.#.#.###.#.....#...#.......#...........#...#...#.#...#.#.....#.........#.........#...#.# +#.#########.#.#.#.#.#######.#.#.#.#.#.###.#.#.#.#.#.#.#.#.###.#####.#####.#################.#####.###.#.###.#.#############.#.#######.#####.# +#.....#...#.#.#.#.#.#.......#...#...#.#...#...#.#.#.#.#.#.#...#...#...###.#.....#.....#...#...###.....#.....#...#.......#...#.......#.#...#.# +#####.#.#.#.#.#.#.#.#.###############.#.#######.#.#.#.#.#.#.###.#.###.###.#.###.#.###.#.#.###.#################.#.#####.#.#########.#.#.#.#.# +#...#...#.#.#...#...#.................#.#...###.#.#.#.#...#...#.#.#...#...#.#...#...#.#.#.#...#...#...........#...#...#.#.#.......#.#...#...# +#.#.#####.#.###########################.#.#.###.#.#.#.#######.#.#.#.###.###.#.#####.#.#.#.#.###.#.#.#########.#####.#.#.#.#.#####.#.######### +#.#.#.....#.#.........................#...#...#.#.#.#.###.....#.#.#.###...#.#.#...#.#...#...#...#...#.......#.......#...#...#.....#...#...### +#.#.#.#####.#.#######################.#######.#.#.#.#.###.#####.#.#.#####.#.#.#.#.#.#########.#######.#####.#################.#######.#.#.### +#.#...#.....#.......................#.#.....#.#.#.#.#.#...#...#.#.#...###...#.#.#.#...#...###.#.......###...###...#...#...###...#...#...#...# +#.#####.###########################.#.#.###.#.#.#.#.#.#.###.#.#.#.###.#######.#.#.###.#.#.###.#.#########.#####.#.#.#.#.#.#####.#.#.#######.# +#.#.....#.....#...........#...#.....#.#...#.#.#.#.#...#.....#.#.#...#...#.....#.#...#...#...#...#...#...#.......#...#...#.....#.#.#...#...#.# +#.#.#####.###.#.#########.#.#.#.#####.###.#.#.#.#.###########.#.###.###.#.#####.###.#######.#####.#.#.#.#####################.#.#.###.#.#.#.# +#...###...#...#.........#...#.#.....#.....#...#.#...###.......#.###.#...#...#...#...#.....#.#.....#...#.................#.....#...#...#.#.#.# +#######.###.###########.#####.#####.###########.###.###.#######.###.#.#####.#.###.###.###.#.#.#########################.#.#########.###.#.#.# +###...#...#.#...#...###.....#.....#.........###...#...#.#.....#.#...#...###.#.###...#...#...#...............#.........#...#.......#.#...#...# +###.#.###.#.#.#.#.#.#######.#####.#########.#####.###.#.#.###.#.#.#####.###.#.#####.###.###################.#.#######.#####.#####.#.#.####### +#...#.....#...#.#.#.#...#...#...#...........#...#.#...#...###...#.#...#...#.#.....#...#.....#.....#.........#.#.....#.#.....#.....#...###...# +#.#############.#.#.#.#.#.###.#.#############.#.#.#.#############.#.#.###.#.#####.###.#####.#.###.#.#########.#.###.#.#.#####.###########.#.# +#.............#...#...#.#.....#...........#...#.#...###..E#.......#.#...#.#...#...###...#...#...#.#...........#...#...#.....#.#...#.....#.#.# +#############.#########.#################.#.###.#######.###.#######.###.#.###.#.#######.#.#####.#.###############.#########.#.#.#.#.###.#.#.# +#...........#.........#...................#.#...#.......###.....#...#...#.###.#.#.....#...#...#.#.......#.......#...###...#.#...#...#...#.#.# +#.#########.#########.#####################.#.###.#############.#.###.###.###.#.#.###.#####.#.#.#######.#.#####.###.###.#.#.#########.###.#.# +#.........#...........#.................###.#.###.###########...#...#...#...#.#.#...#.......#...#.....#...#...#...#...#.#.#.#...#.....###.#.# +#########.#############.###############.###.#.###.###########.#####.###.###.#.#.###.#############.###.#####.#.###.###.#.#.#.#.#.#.#######.#.# +#.........#.....#.......#.........#...#.....#.....###########...#...#...#...#...#...#...#.....#...###.#.....#...#.....#.#.#.#.#...###.....#.# +#.#########.###.#.#######.#######.#.#.#########################.#.###.###.#######.###.#.#.###.#.#####.#.#######.#######.#.#.#.#######.#####.# +#.........#...#.#...#.....#.....#...#S#########################...###...#.....###.....#...###...#...#...#.......###.....#...#.......#.#.....# +#########.###.#.###.#.#####.###.#######################################.#####.###################.#.#####.#########.###############.#.#.##### +#.........#...#.....#.....#.###.............###########################...#...#...#...###.........#.....#...........#.........#.....#.#.#...# +#.#########.#############.#.###############.#############################.#.###.#.#.#.###.#############.#############.#######.#.#####.#.#.#.# +#...#...#...###...#...###...#...............#############################.#...#.#.#.#...#.............#.....#.......#.......#.#...#...#...#.# +###.#.#.#.#####.#.#.#.#######.###########################################.###.#.#.#.###.#############.#####.#.#####.#######.#.###.#.#######.# +###...#...#.....#...#.........#...........###############################.....#.#...#...###...#.....#.....#...#...#.....#...#.....#.#.....#.# +###########.###################.#########.#####################################.#####.#####.#.#.###.#####.#####.#.#####.#.#########.#.###.#.# +#.........#.#...................#.........#...###.......#######################.#...#.#...#.#.#...#.#...#.......#.....#...#####...#.#...#.#.# +#.#######.#.#.###################.#########.#.###.#####.#######################.#.#.#.#.#.#.#.###.#.#.#.#############.#########.#.#.###.#.#.# +#.......#.#...#...#...#...#...###...........#.....#...#.....#################...#.#.#...#...#.....#...#.....#...#...#.#.....#...#...#...#...# +#######.#.#####.#.#.#.#.#.#.#.#####################.#.#####.#################.###.#.#######################.#.#.#.#.#.#.###.#.#######.####### +#.....#.#...#...#...#...#...#...........#...#...#...#.#.....#.......###...###.....#.....#...#...#.........#...#...#...#...#.#...#.....#...### +#.###.#.###.#.#########################.#.#.#.#.#.###.#.#####.#####.###.#.#############.#.#.#.#.#.#######.###############.#.###.#.#####.#.### +#...#.#...#.#.........#.....#...#...###...#...#...###...#...#.#.....#...#.#.............#.#...#...###...#...........###...#.....#.......#...# +###.#.###.#.#########.#.###.#.#.#.#.#####################.#.#.#.#####.###.#.#############.###########.#.###########.###.###################.# +#...#.....#...........#.###.#.#...#...............#...#...#...#...#...#...#...............#...........#.............#...#...#.........#...#.# +#.#####################.###.#.###################.#.#.#.#########.#.###.###################.#########################.###.#.#.#######.#.#.#.# +#.#.....#...........#...#...#.#.......#...........#.#.#...#.......#...#.#.....#.....#...###...#.....#...............#...#.#.#.......#.#.#.#.# +#.#.###.#.#########.#.###.###.#.#####.#.###########.#.###.#.#########.#.#.###.#.###.#.#.#####.#.###.#.#############.###.#.#.#######.#.#.#.#.# +#...###.#.#.........#...#...#.#.#...#...#.......#...#.#...#...#...#...#.#.#...#...#...#.......#.###.#.#.....#.......###.#.#.........#.#.#.#.# +#######.#.#.###########.###.#.#.#.#.#####.#####.#.###.#.#####.#.#.#.###.#.#.#####.#############.###.#.#.###.#.#########.#.###########.#.#.#.# +#.....#.#.#.........#...###...#...#.......#.....#.#...#.....#...#.#...#.#.#.#...#.........#...#.#...#.#...#...#...#.....#...#.......#...#...# +#.###.#.#.#########.#.#####################.#####.#.#######.#####.###.#.#.#.#.#.#########.#.#.#.#.###.###.#####.#.#.#######.#.#####.######### +#.#...#...#.........#.#.....#.............#.#.....#...#...#.#.....#...#.#.#.#.#...#.....#...#.#.#.....###.......#...#.....#...#...#.........# +#.#.#######.#########.#.###.#.###########.#.#.#######.#.#.#.#.#####.###.#.#.#.###.#.###.#####.#.#####################.###.#####.#.#########.# +#.#...#...#.........#.#.#...#...........#.#...#.......#.#...#.#...#...#.#.#...#...#...#...###...#.............#...#...###.#...#.#...........# +#.###.#.#.#########.#.#.#.#############.#.#####.#######.#####.#.#.###.#.#.#####.#####.###.#######.###########.#.#.#.#####.#.#.#.############# +#...#...#.###...###...#.#.............#.#...#...#.....#.....#...#...#.#.#.#.....#...#...#.#.....#...........#...#.#.....#.#.#...###...#...### +###.#####.###.#.#######.#############.#.###.#.###.###.#####.#######.#.#.#.#.#####.#.###.#.#.###.###########.#####.#####.#.#.#######.#.#.#.### +###.....#.....#.........#...........#.#.###...###...#.#...#.#.....#...#...#.......#.#...#.#.#...#.......#...#...#.....#.#...#.......#...#...# +#######.#################.#########.#.#.###########.#.#.#.#.#.###.#################.#.###.#.#.###.#####.#.###.#.#####.#.#####.#############.# +#.......#...#.....#.......#.........#.#.#.......#...#.#.#.#...###.....#.........#...#...#...#.....#...#.#.....#.....#...#...#.#...........#.# +#.#######.#.#.###.#.#######.#########.#.#.#####.#.###.#.#.###########.#.#######.#.#####.###########.#.#.###########.#####.#.#.#.#########.#.# +#.......#.#.#.###...#.....#.........#...#.#.....#...#.#.#.###.....#...#.....###...#...#.............#.#.....#.....#...#...#...#.....#...#...# +#######.#.#.#.#######.###.#########.#####.#.#######.#.#.#.###.###.#.#######.#######.#.###############.#####.#.###.###.#.###########.#.#.##### +#...###...#...#...###...#.#...#.....###...#.....###.#.#.#.#...#...#...#.....#...###.#.###.....#.....#.....#.#...#...#...#...#.....#...#.....# +#.#.###########.#.#####.#.#.#.#.#######.#######.###.#.#.#.#.###.#####.#.#####.#.###.#.###.###.#.###.#####.#.###.###.#####.#.#.###.#########.# +#.#.............#.#...#.#.#.#.#.......#.#.......#...#...#.#.#...#...#.#.....#.#...#.#.#...#...#...#...#...#.....###.......#...###.#...#...#.# +#.###############.#.#.#.#.#.#.#######.#.#.#######.#######.#.#.###.#.#.#####.#.###.#.#.#.###.#####.###.#.#########################.#.#.#.#.#.# +#.#...#.....#...#...#...#...#.........#.#.###...#.......#.#.#.###.#.#.#.....#.#...#.#.#...#.#...#.#...#...........#.........#.....#.#...#.#.# +#.#.#.#.###.#.#.#######################.#.###.#.#######.#.#.#.###.#.#.#.#####.#.###.#.###.#.#.#.#.#.#############.#.#######.#.#####.#####.#.# +#.#.#...###...#...#.............#.....#.#...#.#.#...#...#.#.#...#.#.#.#.....#.#.#...#...#.#.#.#.#.#.....#...#...#...#...#...#.....#.....#.#.# +#.#.#############.#.###########.#.###.#.###.#.#.#.#.#.###.#.###.#.#.#.#####.#.#.#.#####.#.#.#.#.#.#####.#.#.#.#.#####.#.#.#######.#####.#.#.# +#.#.#.............#.#...#.......#...#.#.#...#.#.#.#.#.#...#.#...#.#.#.#.....#.#.#...#...#.#.#.#.#...###.#.#...#.#...#.#...#.....#.#...#.#.#.# +#.#.#.#############.#.#.#.#########.#.#.#.###.#.#.#.#.#.###.#.###.#.#.#.#####.#.###.#.###.#.#.#.###.###.#.#####.#.#.#.#####.###.#.#.#.#.#.#.# +#...#...............#.#.#.......#...#...#.....#.#.#...#.#...#...#.#.#.#...#...#.#...#.....#.#.#.#...#...#...###...#.#.......#...#.#.#.#.#.#.# +#####################.#.#######.#.#############.#.#####.#.#####.#.#.#.###.#.###.#.#########.#.#.#.###.#####.#######.#########.###.#.#.#.#.#.# +#.................#...#.........#.#.............#...#...#.#...#.#.#...#...#...#.#.#...#.....#.#.#...#.#...#.......#...........###...#.#.#.#.# +#.###############.#.#############.#.###############.#.###.#.#.#.#.#####.#####.#.#.#.#.#.#####.#.###.#.#.#.#######.###################.#.#.#.# +#.........#.....#...#...#.....#...#...#...#.....#...#...#...#.#.#.....#...#...#.#...#.#...#...#...#.#.#.#...#...#...................#...#...# +#########.#.###.#####.#.#.###.#.#####.#.#.#.###.#.#####.#####.#.#####.###.#.###.#####.###.#.#####.#.#.#.###.#.#.###################.######### +#...#...#...###.....#.#...#...#.....#.#.#.#.#...#.#####...#...#.#...#.#...#.###.#.....###.#.#.....#.#...###.#.#.#...#.....#.........###...### +#.#.#.#.###########.#.#####.#######.#.#.#.#.#.###.#######.#.###.#.#.#.#.###.###.#.#######.#.#.#####.#######.#.#.#.#.#.###.#.###########.#.### +#.#...#.............#.#...#.....#...#.#.#.#.#...#...#.....#.#...#.#.#.#...#.#...#.....#...#.#.#...#...###...#.#.#.#...###.#.......#.....#...# +#.###################.#.#.#####.#.###.#.#.#.###.###.#.#####.#.###.#.#.###.#.#.#######.#.###.#.#.#.###.###.###.#.#.#######.#######.#.#######.# +#...........#...#...#...#...#...#...#.#.#...#...#...#.#...#.#.#...#.#.###...#.#.......#.#...#...#...#...#...#.#.#.......#.#...#...#.#.......# +###########.#.#.#.#.#######.#.#####.#.#.#####.###.###.#.#.#.#.#.###.#.#######.#.#######.#.#########.###.###.#.#.#######.#.#.#.#.###.#.####### +#...........#.#...#.#...#...#...#...#.#...#...#...#...#.#.#.#.#...#.#.#.......#.....#...#.........#...#...#.#.#.#...#...#...#.#.....#.....### +#.###########.#####.#.#.#.#####.#.###.###.#.###.###.###.#.#.#.###.#.#.#.###########.#.###########.###.###.#.#.#.#.#.#.#######.###########.### +#.#.....#...#.#.....#.#.#.#...#.#...#...#.#...#.###.....#.#.#.....#...#.....#...#...#.#...#.......###...#.#.#.#...#.#.......#...#...#...#...# +#.#.###.#.#.#.#.#####.#.#.#.#.#.###.###.#.###.#.#########.#.###############.#.#.#.###.#.#.#.###########.#.#.#.#####.#######.###.#.#.#.#.###.# +#...###...#...#.#...#.#.#.#.#...#...###...#...#...###...#.#...#...###.......#.#...###...#...#...###...#.#.#.#.....#.........###.#.#.#.#...#.# +###############.#.#.#.#.#.#.#####.#########.#####.###.#.#.###.#.#.###.#######.###############.#.###.#.#.#.#.#####.#############.#.#.#.###.#.# +#.....#.........#.#.#.#...#.....#.....###...#...#.....#.#.#...#.#.....#.....#.................#...#.#...#.#.#.....#...........#.#.#...###...# +#.###.#.#########.#.#.#########.#####.###.###.#.#######.#.#.###.#######.###.#####################.#.#####.#.#.#####.#########.#.#.########### +#...#.#.........#.#.#.....#.....#...#.#...#...#...#.....#.#...#.#.....#.#...#.....#...#...#.......#.....#.#.#.#.....#.....#...#.#...........# +###.#.#########.#.#.#####.#.#####.#.#.#.###.#####.#.#####.###.#.#.###.#.#.###.###.#.#.#.#.#.###########.#.#.#.#.#####.###.#.###.###########.# +#...#.........#.#.#...#...#.....#.#...#.#...#.....#.....#.....#...#...#.#...#...#.#.#.#.#.#.....#.......#.#.#...#.....###...#...#...#...#...# +#.###########.#.#.###.#.#######.#.#####.#.###.#########.###########.###.###.###.#.#.#.#.#.#####.#.#######.#.#####.###########.###.#.#.#.#.### +#.#.....#...#...#.#...#.#.......#...#...#...#...#.....#...#.....#...#...###...#.#...#.#.#...#...#.....#...#.....#...........#.#...#...#...### +#.#.###.#.#.#####.#.###.#.#########.#.#####.###.#.###.###.#.###.#.###.#######.#.#####.#.###.#.#######.#.#######.###########.#.#.############# +#.#.#...#.#...#...#.#...#.......#...#.#.....###...#...#...#...#...#...#...#...#...#...#.###.#.......#.#.......#.#...........#.#...........### +#.#.#.###.###.#.###.#.#########.#.###.#.###########.###.#####.#####.###.#.#.#####.#.###.###.#######.#.#######.#.#.###########.###########.### +#.#.#...#...#.#...#.#.....#.....#.#...#...#.........#...#.....#...#.....#.#...#...#...#.#...#...#...#.#...#...#.#...........#...#...#...#...# +#.#.###.###.#.###.#.#####.#.#####.#.#####.#.#########.###.#####.#.#######.###.#.#####.#.#.###.#.#.###.#.#.#.###.###########.###.#.#.#.#.###.# +#...###.....#.....#.......#.......#.......#...........###.......#.........###...#####...#.....#...###...#...###.............###...#...#.....# +############################################################################################################################################# \ No newline at end of file diff --git a/scala2/src/main/resources/2024/21-test-00.txt b/scala2/src/main/resources/2024/21-test-00.txt new file mode 100644 index 00000000..a8b6c947 --- /dev/null +++ b/scala2/src/main/resources/2024/21-test-00.txt @@ -0,0 +1 @@ +noop \ No newline at end of file diff --git a/scala2/src/main/resources/2024/21.txt b/scala2/src/main/resources/2024/21.txt new file mode 100644 index 00000000..a8b6c947 --- /dev/null +++ b/scala2/src/main/resources/2024/21.txt @@ -0,0 +1 @@ +noop \ No newline at end of file diff --git a/scala2/src/main/scala/jurisk/adventofcode/y2024/Advent16.scala b/scala2/src/main/scala/jurisk/adventofcode/y2024/Advent16.scala index 4f66befd..0092ad25 100644 --- a/scala2/src/main/scala/jurisk/adventofcode/y2024/Advent16.scala +++ b/scala2/src/main/scala/jurisk/adventofcode/y2024/Advent16.scala @@ -35,8 +35,9 @@ object Advent16 { def parse(input: String): Input = { val charField = Field2D.parseCharField(input) - val start = charField.findCoordsByValue('S').get - val end = charField.findCoordsByValue('E').get + val start = + charField.findCoordsByValue('S').getOrElse("Start not found".fail) + val end = charField.findCoordsByValue('E').getOrElse("End not found".fail) val field = charField.mapByCoordsWithValues { case (_, c) => c match { case 'S' => false diff --git a/scala2/src/main/scala/jurisk/adventofcode/y2024/Advent20.scala b/scala2/src/main/scala/jurisk/adventofcode/y2024/Advent20.scala index 6d3bb1eb..a617aa10 100644 --- a/scala2/src/main/scala/jurisk/adventofcode/y2024/Advent20.scala +++ b/scala2/src/main/scala/jurisk/adventofcode/y2024/Advent20.scala @@ -1,37 +1,99 @@ package jurisk.adventofcode.y2024 +import jurisk.algorithms.pathfinding.Dijkstra +import jurisk.geometry.Coords2D +import jurisk.geometry.Field2D import jurisk.utils.FileInput._ import jurisk.utils.Parsing.StringOps object Advent20 { - type Input = List[Command] + type Input = (Coords2D, Field2D[Boolean], Coords2D) type N = Long - sealed trait Command extends Product with Serializable - object Command { - case object Noop extends Command - final case class Something( - values: List[N] - ) extends Command - final case class Other(value: String) extends Command - - def parse(s: String): Command = - s match { - case "noop" => Noop - case s"something $rem" => Something(rem.extractLongList) - case s if s.nonEmpty => Other(s) - case _ => s.failedToParse + final case class Cheat(from: Coords2D, to: Coords2D) { + def distance: Int = from manhattanDistance to + } + + def parse(input: String): Input = { + val charField = Field2D.parseCharField(input) + val start = + charField.findCoordsByValue('S').getOrElse("Start not found".fail) + val end = charField.findCoordsByValue('E').getOrElse("End not found".fail) + val field = charField.mapByCoordsWithValues { case (_, c) => + c match { + case 'S' => false + case 'E' => false + case '#' => true + case '.' => false + case _ => s"Unknown character $c in field".fail } + } + (start, field, end) } - def parse(input: String): Input = - input.parseLines(Command.parse) + def solve(data: Input, saveAtLeast: Int, maxCheat: Int): N = { + val (start, field, end) = data + + def successors(c: Coords2D): List[(Coords2D, Int)] = + field + .neighboursFor(c, includeDiagonal = false) + .filter(field.at(_).contains(false)) + .map { n => + (n, 1) + } + + val fromStart = Dijkstra.dijkstraAll[Coords2D, Int]( + start, + successors, + ) + + val fromEnd = Dijkstra.dijkstraAll[Coords2D, Int]( + end, + successors, + ) + + val (_, cost) = fromStart.getOrElse(end, "No path from start to end".fail) + val goalCostThreshold = cost - saveAtLeast + + println(s"Without cheats = $cost, goal cost threshold = $goalCostThreshold") + + def validCheat(cheat: Cheat): Boolean = + (fromStart.get(cheat.from), fromEnd.get(cheat.to)) match { + case (Some((_, startCost)), Some((_, endCost))) => + startCost + endCost + cheat.distance <= goalCostThreshold + case _ => + false + } + + val empties = field.allCoords + .filter(field.at(_).contains(false)) + val cheats = + for { + // Could be optimised by avoiding processing all O(N^2), as if we know one coordinate, we can generate all others within maxCheat distance more efficiently + c1 <- empties + c2 <- empties + if c1.manhattanDistance(c2) <= maxCheat + if c1 != c2 + } yield Cheat(c1, c2) + + println(s"Cheats: ${cheats.size}") + + val selectedCheats = + cheats + .filter(validCheat) + .toSet + + println(s"Selected cheats: ${selectedCheats.size}") + selectedCheats.foreach(println) + + selectedCheats.size + } - def part1(data: Input): N = - 0 + def part1(data: Input, saveAtLeast: Int): N = + solve(data, saveAtLeast, 2) - def part2(data: Input): N = - 0 + def part2(data: Input, saveAtLeast: Int): N = + solve(data, saveAtLeast, 20) def parseFile(fileName: String): Input = parse(readFileText(fileName)) @@ -42,7 +104,7 @@ object Advent20 { def main(args: Array[String]): Unit = { val realData: Input = parseFile(fileName("")) - println(s"Part 1: ${part1(realData)}") - println(s"Part 2: ${part2(realData)}") + println(s"Part 1: ${part1(realData, 100)}") + println(s"Part 2: ${part2(realData, 100)}") } } diff --git a/scala2/src/main/scala/jurisk/adventofcode/y2024/Advent21.scala b/scala2/src/main/scala/jurisk/adventofcode/y2024/Advent21.scala new file mode 100644 index 00000000..75a527ff --- /dev/null +++ b/scala2/src/main/scala/jurisk/adventofcode/y2024/Advent21.scala @@ -0,0 +1,48 @@ +package jurisk.adventofcode.y2024 + +import jurisk.utils.FileInput._ +import jurisk.utils.Parsing.StringOps + +object Advent21 { + type Input = List[Command] + type N = Long + + sealed trait Command extends Product with Serializable + object Command { + case object Noop extends Command + final case class Something( + values: List[N] + ) extends Command + final case class Other(value: String) extends Command + + def parse(s: String): Command = + s match { + case "noop" => Noop + case s"something $rem" => Something(rem.extractLongList) + case s if s.nonEmpty => Other(s) + case _ => s.failedToParse + } + } + + def parse(input: String): Input = + input.parseLines(Command.parse) + + def part1(data: Input): N = + 0 + + def part2(data: Input): N = + 0 + + def parseFile(fileName: String): Input = + parse(readFileText(fileName)) + + def fileName(suffix: String): String = + s"2024/00$suffix.txt" + + def main(args: Array[String]): Unit = { + val realData: Input = parseFile(fileName("")) + + println(s"Part 1: ${part1(realData)}") + println(s"Part 2: ${part2(realData)}") + } +} diff --git a/scala2/src/test/scala/jurisk/adventofcode/y2024/Advent20Spec.scala b/scala2/src/test/scala/jurisk/adventofcode/y2024/Advent20Spec.scala index 3d63a8cf..03ded45a 100644 --- a/scala2/src/test/scala/jurisk/adventofcode/y2024/Advent20Spec.scala +++ b/scala2/src/test/scala/jurisk/adventofcode/y2024/Advent20Spec.scala @@ -9,22 +9,38 @@ class Advent20Spec extends AnyFreeSpec { private def realData = parseFile(fileName("")) "part 1" - { - "test" in { - part1(testData) shouldEqual 0 + "test 64" in { + part1(testData, 64) shouldEqual 1 + } + + "test 40" in { + part1(testData, 40) shouldEqual 1 + 1 + } + + "test misc" in { + part1(testData, 38) shouldEqual 1 + 1 + 1 + part1(testData, 36) shouldEqual 1 + 1 + 1 + 1 + part1(testData, 20) shouldEqual 1 + 1 + 1 + 1 + 1 + part1(testData, 12) shouldEqual 1 + 1 + 1 + 1 + 1 + 3 + part1(testData, 10) shouldEqual 1 + 1 + 1 + 1 + 1 + 3 + 2 + part1(testData, 8) shouldEqual 1 + 1 + 1 + 1 + 1 + 3 + 2 + 4 + part1(testData, 6) shouldEqual 1 + 1 + 1 + 1 + 1 + 3 + 2 + 4 + 2 + part1(testData, 4) shouldEqual 1 + 1 + 1 + 1 + 1 + 3 + 2 + 4 + 2 + 14 + part1(testData, 2) shouldEqual 1 + 1 + 1 + 1 + 1 + 3 + 2 + 4 + 2 + 14 + 14 } - "real" in { - part1(realData) shouldEqual 0 + "real" ignore { + part1(realData, 100) shouldEqual 1293 } } "part 2" - { "test" in { - part2(testData) shouldEqual 0 + part2(testData, 76) shouldEqual 3 } - "real" in { - part2(realData) shouldEqual 0 + "real" ignore { + part2(realData, 100) shouldEqual 977747 } } } diff --git a/scala2/src/test/scala/jurisk/adventofcode/y2024/Advent21Spec.scala b/scala2/src/test/scala/jurisk/adventofcode/y2024/Advent21Spec.scala new file mode 100644 index 00000000..4dce4b7f --- /dev/null +++ b/scala2/src/test/scala/jurisk/adventofcode/y2024/Advent21Spec.scala @@ -0,0 +1,30 @@ +package jurisk.adventofcode.y2024 + +import Advent21._ +import org.scalatest.freespec.AnyFreeSpec +import org.scalatest.matchers.should.Matchers._ + +class Advent21Spec extends AnyFreeSpec { + private def testData = parseFile(fileName("-test-00")) + private def realData = parseFile(fileName("")) + + "part 1" - { + "test" in { + part1(testData) shouldEqual 0 + } + + "real" in { + part1(realData) shouldEqual 0 + } + } + + "part 2" - { + "test" in { + part2(testData) shouldEqual 0 + } + + "real" in { + part2(realData) shouldEqual 0 + } + } +}