diff --git a/README.md b/README.md
index c4f4cda..db0ba0a 100644
--- a/README.md
+++ b/README.md
@@ -38,7 +38,7 @@ To run all solutions, simply run `./gradlew run`. If you want to run the solutio
| 14 | ⭐ | ⭐ |
| 15 | ⭐ | ⭐ |
| 16 | ⭐ | ⭐
|
-| 17 | ⭐ | ⭐ |
+| 17 | ⭐ | ⭐
|
| 18 | ⭐ | ⭐ |
| 19 | ⭐ | ⭐ |
| 20 | ⭐ | ⭐ |
diff --git a/aoc16/build.gradle b/aoc16/build.gradle
index afbc2f5..fd2cf8d 100644
--- a/aoc16/build.gradle
+++ b/aoc16/build.gradle
@@ -12,7 +12,7 @@ dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
implementation 'org.scala-lang:scala3-library_3:3.3.1'
- testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1'
+ testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1'
testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'
testImplementation 'org.scalatest:scalatest_3:3.2.17'
testImplementation 'org.scalatestplus:junit-5-10_3:3.2.17.0'
diff --git a/aoc17/build.gradle b/aoc17/build.gradle
index a74f563..a7e7e2a 100644
--- a/aoc17/build.gradle
+++ b/aoc17/build.gradle
@@ -4,14 +4,18 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id 'application'
id 'org.jetbrains.kotlin.jvm' version '1.7.22'
+ id 'scala'
}
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-reflect'
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
+ implementation 'org.scala-lang:scala3-library_3:3.3.1'
- testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1'
+ testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1'
testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'
+ testImplementation 'org.scalatest:scalatest_3:3.2.17'
+ testImplementation 'org.scalatestplus:junit-5-10_3:3.2.17.0'
}
tasks.withType(KotlinCompile).configureEach {
@@ -22,7 +26,9 @@ tasks.withType(KotlinCompile).configureEach {
}
tasks.withType(Test).configureEach {
- useJUnitPlatform()
+ useJUnitPlatform {
+ includeEngines("junit-jupiter", "scalatest")
+ }
testLogging {
exceptionFormat = TestExceptionFormat.FULL
diff --git a/aoc17/src/main/scala/de/havox_design/aoc2022/day17/Day17.scala b/aoc17/src/main/scala/de/havox_design/aoc2022/day17/Day17.scala
new file mode 100644
index 0000000..7c824c4
--- /dev/null
+++ b/aoc17/src/main/scala/de/havox_design/aoc2022/day17/Day17.scala
@@ -0,0 +1,38 @@
+package de.havox_design.aoc2022.day17
+
+object Day17 {
+ def solvePart2(filename: String, runs: Int = 10000): Long = {
+ val guess = 1000
+ val height = simulate(readData(filename).next())
+ .slice(1, 5 * guess)
+ .toSeq
+ val delta = height.sliding(2).map(s => s.last - s.head).toSeq
+ val end = delta.size - guess
+ val start = delta.lastIndexOfSlice(delta.takeRight(guess), end - 1)
+ val cycleHeight = height(end) - height(start)
+ val cycleWidth = end - start
+ val offset = 1000000000000L - 1 - start
+ val quotient = offset / cycleWidth
+ val remainder = offset % cycleWidth
+
+ (quotient * cycleHeight) + height(start + remainder.toInt)
+ }
+
+ def main(args: Array[String]): Unit = {
+ println("Solution for part2: " + solvePart2("input.txt"))
+ }
+
+ private def simulate(jets: String): Iterator[Int] =
+ val initial = State(jets, Set.tabulate(8)(Point(_, 0)), 0, 0, 0)
+
+ Iterator
+ .iterate(initial)(_.step)
+ .map(_.height)
+
+ private def readData(filename: String): Iterator[String] =
+ scala
+ .io
+ .Source
+ .fromResource(filename)
+ .getLines()
+}
diff --git a/aoc17/src/main/scala/de/havox_design/aoc2022/day17/Point.scala b/aoc17/src/main/scala/de/havox_design/aoc2022/day17/Point.scala
new file mode 100644
index 0000000..c875e8f
--- /dev/null
+++ b/aoc17/src/main/scala/de/havox_design/aoc2022/day17/Point.scala
@@ -0,0 +1,7 @@
+package de.havox_design.aoc2022.day17
+
+case class Point(x: Int, y: Int)
+
+extension (shape: Set[Point])
+ def move(dx: Int, dy: Int): Set[Point] = shape.map(p => Point(p.x + dx, p.y + dy))
+ def canMove(grid: Set[Point]): Boolean = shape.forall(p => p.x > 0 && p.x < 8 && !grid.contains(p))
diff --git a/aoc17/src/main/scala/de/havox_design/aoc2022/day17/State.scala b/aoc17/src/main/scala/de/havox_design/aoc2022/day17/State.scala
new file mode 100644
index 0000000..5913c07
--- /dev/null
+++ b/aoc17/src/main/scala/de/havox_design/aoc2022/day17/State.scala
@@ -0,0 +1,37 @@
+package de.havox_design.aoc2022.day17
+
+val shapes = Seq(
+ Set(Point(0, 0), Point(1, 0), Point(2, 0), Point(3, 0)),
+ Set(Point(1, 0), Point(0, 1), Point(1, 1), Point(2, 1), Point(1, 2)),
+ Set(Point(0, 0), Point(1, 0), Point(2, 0), Point(2, 1), Point(2, 2)),
+ Set(Point(0, 0), Point(0, 1), Point(0, 2), Point(0, 3)),
+ Set(Point(0, 0), Point(1, 0), Point(0, 1), Point(1, 1)))
+
+case class State(jets: String, grid: Set[Point], shapeIndex: Int, jetIndex: Int, height: Int):
+ def step: State =
+ val initialShape = shapes(shapeIndex % shapes.size)
+ .move(3, height + 4)
+ val (nextShape, nextJetIndex) = fall(initialShape, jetIndex)
+ val nextHeight = height
+ .max(nextShape.map(_.y).max)
+
+ State(jets, grid ++ nextShape, shapeIndex + 1, nextJetIndex, nextHeight)
+
+ private def fall(shape: Set[Point], jetIndex: Int): (Set[Point], Int) =
+ val jet = jets(jetIndex % jets.length)
+ val first = if jet != '>' then
+ shape.move(-1, 0)
+ else
+ shape.move(1, 0)
+ val second = if !first.canMove(grid) then
+ shape
+ else
+ first
+ val third = second
+ .move(0, -1)
+
+ if !third.canMove(grid) then
+ (second, jetIndex + 1)
+ else
+ fall(third, jetIndex + 1)
+end State
diff --git a/aoc17/src/test/scala/de/havox_design/aoc2022/day17/Day17ScalaTest.scala b/aoc17/src/test/scala/de/havox_design/aoc2022/day17/Day17ScalaTest.scala
new file mode 100644
index 0000000..ba66c21
--- /dev/null
+++ b/aoc17/src/test/scala/de/havox_design/aoc2022/day17/Day17ScalaTest.scala
@@ -0,0 +1,14 @@
+package de.havox_design.aoc2022.day17
+
+import Day17._
+import org.scalatest.funsuite.AnyFunSuite
+
+class Day17ScalaTest extends AnyFunSuite {
+ test("Day 17 - Part 2") {
+ println("Solution for part2: " + solvePart2("input.txt"))
+ }
+
+ test("Day 17 - Part 2 - Sample") {
+ assert(solvePart2("sample.txt") == 1514285714288L)
+ }
+}
diff --git a/build.gradle b/build.gradle
index 62e8d5a..c0ab6d3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -4,7 +4,7 @@ plugins {
// project meta data
group 'de.havox_design.aoc2022'
-version '1.0.4'
+version '1.0.5'
// Switch to gradle "all" distribution.
wrapper {