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 | ⭐ | ⭐ Scala | -| 17 | ⭐ | ⭐ | +| 17 | ⭐ | ⭐ Scala | | 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 {