Skip to content

Instantly share code, notes, and snippets.

@sungkmi
Last active April 1, 2022 13:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sungkmi/48dac71d3bbae833ec99b5af814ecb36 to your computer and use it in GitHub Desktop.
Save sungkmi/48dac71d3bbae833ec99b5af814ecb36 to your computer and use it in GitHub Desktop.
package lascala.aoc2021.day11_20.day17
case class TargetArea(x0: Int, x1: Int, y0: Int, y1: Int)
object TargetArea:
def parse(s: String): TargetArea =
val prefix = "target area: "
val Array(xRange, yRange) = s.drop(prefix.size).split(", ").map(_.drop(2))
def parseRange(s: String): (Int, Int) =
val Array(x0, x1) = s.split("\\.\\.")
(x0.toInt, x1.toInt)
val (x0, x1) = parseRange(xRange)
val (y0, y1) = parseRange(yRange)
TargetArea(x0, x1, y0, y1)
extension (t: TargetArea)
def highestY(vx: Int, vy: Int): Option[Int] =
@annotation.tailrec
def loop(x: Int, y: Int, vx: Int, vy: Int, yMax: Int): Option[Int] =
if t.x0 <= x && x <= t.x1 && t.y0 <= y && y <= t.y1 then Some(yMax)
else if y < t.y0 then None
else loop(x + vx, y + vy, vx - vx.sign, vy - 1, yMax max y)
loop(0, 0, vx, vy, 0)
def solve(s: String): Seq[Int] =
val targetArea = TargetArea.parse(s)
for
vx <- 1 to targetArea.x1
vy <- targetArea.y0 to targetArea.y0.abs
yMax <- targetArea.highestY(vx, vy)
yield yMax
def solve1(s: String): BigInt =
solve(s).max
end solve1
def solve2(s: String): BigInt =
solve(s).size
end solve2
@main def part1: Unit =
val ans = solve1(input)
println(ans)
@main def part2: Unit =
val ans = solve2(input)
println(ans)
val input = """target area: x=282..314, y=-80..-45"""
package lascala.aoc2021.day11_20.day17
import minitest.SimpleTestSuite
import hedgehog.minitest.HedgehogSupport
import hedgehog.*
object Day17Test extends SimpleTestSuite with HedgehogSupport:
val testInput = """target area: x=20..30, y=-10..-5"""
example("day17 - TargetArea#parse") {
TargetArea.parse(testInput) ==== TargetArea(20, 30, -10, -5)
}
example("day17 - TargetArea#highestY case #1") {
val targetArea = TargetArea.parse(testInput)
targetArea.highestY(7, 2) ==== Some(3)
}
example("day17 - TargetArea#highestY case #2") {
val targetArea = TargetArea.parse(testInput)
targetArea.highestY(6, 3) ==== Some(6)
}
example("day17 - TargetArea#highestY case #3") {
val targetArea = TargetArea.parse(testInput)
targetArea.highestY(9, 0) ==== Some(0)
}
example("day17 - TargetArea#highestY case #4") {
val targetArea = TargetArea.parse(testInput)
targetArea.highestY(17, -4) ==== None
}
example("day17 - TargetArea#highestY case #5") {
val targetArea = TargetArea.parse(testInput)
targetArea.highestY(6, 9) ==== Some(45)
}
example("day17 - solve 1") {
solve1(testInput) ==== 45
}
example("day17 - solve 2") {
solve2(testInput) ==== 112
}
example("day17 - solve 1 with real input") {
solve1(input) ==== 3160
}
example("day17 - solve2 with real input") {
solve2(input) ==== 1928
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment