Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 06921c8

Browse files
Further tidy
1 parent 2e6e79c commit 06921c8

File tree

1 file changed

+26
-27
lines changed

1 file changed

+26
-27
lines changed

‎src/main/scala/AdventOfCode2022/Day17.scala

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package AdventOfCode2022
22

3-
import scala.annotation.tailrec
4-
53
object Day17:
64
val shapes = Seq(
75
Set(Point(0, 0), Point(1, 0), Point(2, 0), Point(3, 0)),
@@ -10,44 +8,45 @@ object Day17:
108
Set(Point(0, 0), Point(0, 1), Point(0, 2), Point(0, 3)),
119
Set(Point(0, 0), Point(1, 0), Point(0, 1), Point(1, 1)))
1210

11+
case class Point(x: Int, y: Int)
12+
1313
extension (shape: Set[Point])
1414
def move(dx: Int, dy: Int): Set[Point] = shape.map(p => Point(p.x + dx, p.y + dy))
1515
def canMove(grid: Set[Point]): Boolean = shape.forall(p => p.x > 0 && p.x < 8 && !grid.contains(p))
1616

17-
case class Point(x: Int, y: Int)
18-
case class State(grid: Set[Point], shapeIndex: Int, jetIndex: Int, height: Int)
19-
20-
@tailrec
21-
def fall(grid: Set[Point], shape: Set[Point], jets: String, jetIndex: Int): (Set[Point], Int) =
22-
val jet = jets(jetIndex % jets.length)
23-
val first = if jet == '>' then shape.move(1, 0) else shape.move(-1, 0)
24-
val second = if first.canMove(grid) then first else shape
25-
val third = second.move(0, -1)
26-
if third.canMove(grid) then fall(grid, third, jets, jetIndex + 1) else (second, jetIndex + 1)
27-
28-
def step(jets: String)(state: State): State =
29-
val State(grid, shapeIndex, jetIndex, height) = state
30-
val initialShape = shapes(shapeIndex % shapes.size).move(3, height + 4)
31-
val (nextShape, nextJetIndex) = fall(grid, initialShape, jets, jetIndex)
32-
State(grid ++ nextShape, shapeIndex + 1, nextJetIndex, height.max(nextShape.map(_.y).max))
17+
case class State(jets: String, grid: Set[Point], shapeIndex: Int, jetIndex: Int, height: Int):
18+
def step: State =
19+
val initialShape = shapes(shapeIndex % shapes.size).move(3, height + 4)
20+
val (nextShape, nextJetIndex) = fall(initialShape, jetIndex)
21+
val nextHeight = height.max(nextShape.map(_.y).max)
22+
State(jets, grid ++ nextShape, shapeIndex + 1, nextJetIndex, nextHeight)
23+
24+
def fall(shape: Set[Point], jetIndex: Int): (Set[Point], Int) =
25+
val jet = jets(jetIndex % jets.length)
26+
val first = if jet == '>' then shape.move(1, 0) else shape.move(-1, 0)
27+
val second = if first.canMove(grid) then first else shape
28+
val third = second.move(0, -1)
29+
if third.canMove(grid) then fall(third, jetIndex + 1) else (second, jetIndex + 1)
30+
end State
3331

3432
def simulate(jets: String): Iterator[Int] =
35-
val initial = State(Set.tabulate(8)(Point(_, 0)), 0, 0, 0)
36-
Iterator.iterate(initial)(step(jets)).map(_.height)
33+
val initial = State(jets, Set.tabulate(8)(Point(_, 0)), 0, 0, 0)
34+
Iterator.iterate(initial)(_.step).map(_.height)
3735

3836
def part1(input: String): Int = simulate(input).drop(2022).next()
3937

4038
def part2(input: String): Long =
4139
val guess = 1000
42-
val height = simulate(input).slice(1, 10 * guess).toSeq
43-
val delta = height.sliding(2).map { case Seq(a, b) => b - a }.toSeq
44-
val index = delta.lastIndexOfSlice(delta.takeRight(guess), delta.size - guess - 1)
45-
val cycleHeight = height(delta.size - guess) - height(index)
46-
val cycleWidth = delta.size - guess - index
47-
val offset = 1000000000000L - 1 - index
40+
val height = simulate(input).slice(1, 5 * guess).toSeq
41+
val delta = height.sliding(2).map(s => s.last - s.head).toSeq
42+
val end = delta.size - guess
43+
val start = delta.lastIndexOfSlice(delta.takeRight(guess), end - 1)
44+
val cycleHeight = height(end) - height(start)
45+
val cycleWidth = end - start
46+
val offset = 1000000000000L - 1 - start
4847
val quotient = offset / cycleWidth
4948
val remainder = offset % cycleWidth
50-
(quotient * cycleHeight) + height(index + remainder.toInt)
49+
(quotient * cycleHeight) + height(start + remainder.toInt)
5150

5251
def main(args: Array[String]): Unit =
5352
val data = io.Source.fromResource("AdventOfCode2022/Day17.txt").mkString.trim

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /