Skip to content

Instantly share code, notes, and snippets.

@waynejo
Created January 14, 2022 11: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 waynejo/e6d8da750a350bf1cb9d0d8b868def18 to your computer and use it in GitHub Desktop.
Save waynejo/e6d8da750a350bf1cb9d0d8b868def18 to your computer and use it in GitHub Desktop.
import java.io.FileInputStream
import scala.annotation.tailrec
import scala.io.StdIn
case class Point(x: Int, y: Int)
case class Vent(p0: Point, p1: Point)
implicit class MapAdder(map: Map[Point, Int]) {
def addValueOrInsert(key: Point, v: Int): Map[Point, Int] = {
map.updated(key, map.getOrElse(key, 0) + 1)
}
}
def solve5(inputs: Vector[Vent], updater: (Map[Point, Int], Point, Point) => Map[Point, Int]): Int = {
val maps = inputs.foldLeft(Map[Point, Int]()) { (acc, vent) =>
updater(acc, vent.p0, vent.p1)
}
maps.count(2 <= _._2)
}
def solve5_1Updater(acc: Map[Point, Int], p0: Point, p1: Point): Map[Point, Int] = {
if p0.x == p1.x then
val y0 = p0.y min p1.y
val y1 = p0.y max p1.y
(y0 to y1).foldLeft(acc) { (map, y) => map.addValueOrInsert(Point(p0.x, y), 1) }
else if p0.y == p1.y then
val x0 = p0.x min p1.x
val x1 = p0.x max p1.x
(x0 to x1).foldLeft(acc) { (map, x) => map.addValueOrInsert(Point(x, p0.y), 1) }
else
acc
}
def solve5_1(inputs: Vector[Vent]): Int = {
solve5(inputs, solve5_1Updater)
}
def solve5_2Updater(acc: Map[Point, Int], p0: Point, p1: Point): Map[Point, Int] = {
if p1.y - p0.y == p1.x - p0.x then
val deltaMin = 0 min (p1.x - p0.x)
val deltaMax = 0 max (p1.x - p0.x)
(deltaMin to deltaMax).foldLeft(acc) { (map, delta) => map.addValueOrInsert(Point(p0.x + delta, p0.y + delta), 1) }
else if -(p1.y - p0.y) == p1.x - p0.x then
val deltaMin = 0 min (p1.x - p0.x)
val deltaMax = 0 max (p1.x - p0.x)
(deltaMin to deltaMax).foldLeft(acc) { (map, delta) => map.addValueOrInsert(Point(p0.x + delta, p0.y - delta), 1) }
else
solve5_1Updater(acc, p0, p1)
}
def solve5_2(inputs: Vector[Vent]): Int = {
solve5(inputs, solve5_2Updater)
}
@main def solve5(): Unit =
val in = new FileInputStream("example5-2.in")
System.setIn(in)
val inputs = Iterator.continually(StdIn.readLine())
.takeWhile(line => null != line && line.trim.nonEmpty)
.map(line => {
val Array(x0, y0, _, x1, y1) = line.split("[, ]")
Vent(Point(x0.toInt, y0.toInt), Point(x1.toInt, y1.toInt))
})
.toVector
println(solve5_1(inputs)) // 5 8350
println(solve5_2(inputs)) // 12 19374
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment