-
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.
* 2023-17 * 2023-17 * 2023-17 * 2023-17 * 2023-17 --------- Co-authored-by: Juris <[email protected]>
- Loading branch information
Showing
11 changed files
with
329 additions
and
13 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 @@ | ||
111111111111 | ||
999999999991 | ||
999999999991 | ||
999999999991 | ||
999999999991 |
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,13 @@ | ||
2413432311323 | ||
3215453535623 | ||
3255245654254 | ||
3446585845452 | ||
4546657867536 | ||
1438598798454 | ||
4457876987766 | ||
3637877979653 | ||
4654967986887 | ||
4564679986453 | ||
1224686865563 | ||
2546548887735 | ||
4322674655533 |
Large diffs are not rendered by default.
Oops, something went wrong.
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
107 changes: 107 additions & 0 deletions
107
scala2/src/main/scala/jurisk/adventofcode/y2023/Advent17.scala
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,107 @@ | ||
package jurisk.adventofcode.y2023 | ||
|
||
import cats.implicits.{catsSyntaxOptionId, none} | ||
import jurisk.algorithms.pathfinding.Dijkstra | ||
import jurisk.geometry.Direction2D.{CardinalDirection2D, E, S} | ||
import jurisk.geometry.Rotation.{Left90, NoRotation, Right90} | ||
import jurisk.geometry.{Coords2D, Field2D} | ||
import jurisk.utils.FileInput._ | ||
import jurisk.utils.Parsing.StringOps | ||
|
||
object Advent17 { | ||
type Input = Field2D[Int] | ||
|
||
def parse(input: String): Input = | ||
Field2D.parseDigitField(input) | ||
|
||
final case class State( | ||
coords: Coords2D, | ||
direction: Option[CardinalDirection2D], | ||
singleDirectionCounter: Int, | ||
) | ||
|
||
private def successors( | ||
data: Input, | ||
atMostInSingleDirection: Int, | ||
minimumBeforeTurning: Int, | ||
)(state: State): List[(State, Int)] = { | ||
val candidateDirections = state.direction match { | ||
case Some(lastDirection) => | ||
val turns = | ||
if (state.singleDirectionCounter >= minimumBeforeTurning) { | ||
// Allowed to turn | ||
List(Left90, Right90) | ||
} else Nil | ||
val straights = | ||
if (state.singleDirectionCounter < atMostInSingleDirection) { | ||
// Allowed to go straight | ||
List(NoRotation) | ||
} else Nil | ||
|
||
(turns ::: straights) map lastDirection.rotate | ||
|
||
case None => | ||
// Start | ||
E :: S :: Nil | ||
} | ||
|
||
candidateDirections flatMap { direction => | ||
val nextCoords = state.coords + direction | ||
data.at(nextCoords) map { heatLoss => | ||
val newState = State( | ||
nextCoords, | ||
direction.some, | ||
if (direction.some == state.direction) { | ||
state.singleDirectionCounter + 1 | ||
} else { | ||
1 | ||
}, | ||
) | ||
newState -> heatLoss | ||
} | ||
} | ||
} | ||
|
||
private def solve( | ||
data: Input, | ||
atMostInSingleDirection: Int, | ||
minimumBeforeStoppingOrTurning: Int, | ||
): Int = { | ||
val calculateSuccessors = successors( | ||
data, | ||
atMostInSingleDirection, | ||
minimumBeforeStoppingOrTurning, | ||
) _ | ||
|
||
val result = Dijkstra.dijkstra[State, Int]( | ||
State(coords = data.topLeft, none, singleDirectionCounter = 0), | ||
calculateSuccessors, | ||
s => | ||
s.coords == data.bottomRight && s.singleDirectionCounter >= minimumBeforeStoppingOrTurning, | ||
) | ||
|
||
result match { | ||
case Some((_, result)) => result | ||
case None => "Failed to solve".fail | ||
} | ||
} | ||
|
||
def part1(data: Input): Int = | ||
solve(data, 3, 0) | ||
|
||
def part2(data: Input): Int = | ||
solve(data, 10, 4) | ||
|
||
def parseFile(fileName: String): Input = | ||
parse(readFileText(fileName)) | ||
|
||
def fileName(suffix: String): String = | ||
s"2023/17$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)}") | ||
} | ||
} |
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
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
35 changes: 35 additions & 0 deletions
35
scala2/src/test/scala/jurisk/adventofcode/y2023/Advent17Spec.scala
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,35 @@ | ||
package jurisk.adventofcode.y2023 | ||
|
||
import org.scalatest.freespec.AnyFreeSpec | ||
import Advent17._ | ||
import org.scalatest.matchers.should.Matchers._ | ||
|
||
class Advent17Spec extends AnyFreeSpec { | ||
private def testData = parseFile(fileName("-test")) | ||
private def testData2 = parseFile(fileName("-test-2")) | ||
private def realData = parseFile(fileName("")) | ||
|
||
"part 1" - { | ||
"test" in { | ||
part1(testData) shouldEqual 102 | ||
} | ||
|
||
"real" in { | ||
part1(realData) shouldEqual 686 | ||
} | ||
} | ||
|
||
"part 2" - { | ||
"test" in { | ||
part2(testData) shouldEqual 94 | ||
} | ||
|
||
"test 2" in { | ||
part2(testData2) shouldEqual 71 | ||
} | ||
|
||
"real" in { | ||
part2(realData) shouldEqual 801 | ||
} | ||
} | ||
} |