Skip to content

Instantly share code, notes, and snippets.

@waynejo
Last active April 1, 2022 12:09
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 waynejo/a641bcd94537a395fcbe46f3a9a010c7 to your computer and use it in GitHub Desktop.
Save waynejo/a641bcd94537a395fcbe46f3a9a010c7 to your computer and use it in GitHub Desktop.
import java.io.FileInputStream
import scala.annotation.tailrec
import scala.io.StdIn
case class Range(min: Int, max: Int)
case class Area(x: Range, y: Range) {
def isInArea(point: Point): Boolean = x.min <= point.x && point.x <= x.max && y.min <= point.y && point.y <= y.max
}
case class Point(x: Int, y: Int) {
def + (another: Point): Point = Point(x + another.x, y + another.y)
}
@tailrec
def maxYPos(yVelocity: Int, yPos: Int = 0): Int =
if 0 >= yVelocity then
yPos
else
maxYPos(yVelocity - 1, yPos + yVelocity)
def solve17_1(area: Area): Int =
maxYPos(-area.y.min - 1)
@tailrec
def isInArea(pos: Point, velocity: Point, area: Area): Boolean =
if pos.x > area.x.max || pos.y < area.y.min then
false
else if area.isInArea(pos) then
true
else
isInArea(pos + velocity, Point(velocity.x - 1 max 0, velocity.y - 1), area)
def solve17_2(area: Area): Int =
val minY = area.y.min
val maxY = -area.y.min - 1
val maxX = area.x.max
val count = (1 to maxX).flatMap(x => (minY to maxY).map(y => Point(x, y))).count(isInArea(Point(0, 0), _, area))
count
def parse(line: String): Area =
val Array(_, values) = line.split(":")
val Array(xs, ys) = values.trim.split(",")
val Array(xStart, xEnd) = xs.trim.drop(2).split("\\.\\.")
val Array(yStart, yEnd) = ys.trim.drop(2).split("\\.\\.")
Area(Range(xStart.toInt, xEnd.toInt), Range(yStart.toInt, yEnd.toInt))
@main def solve17(): Unit =
val in = new FileInputStream("example17-2.in")
System.setIn(in)
val inputs = StdIn.readLine()
println(solve17_1(parse(inputs)))
println(solve17_2(parse(inputs)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment