Skip to content

Instantly share code, notes, and snippets.

@waynejo
Last active March 11, 2022 12:21
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/3a1c41029f02a2ea458a7b7efe2fc9d3 to your computer and use it in GitHub Desktop.
Save waynejo/3a1c41029f02a2ea458a7b7efe2fc9d3 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):
def add(dx: Int, dy: Int): Point =
Point(x + dx, y + dy)
case class Link(point: Point, cost: Int)
@tailrec
def _findMinimumPath(riskMap: Vector[Vector[Int]], visited: Set[Point], nexts: Vector[Link], dest: Point): Int =
val current = nexts.head
val point = current.point
if point == dest then
val cost = current.cost + riskMap(point.y)(point.x)
cost
else if visited.contains(point) then
_findMinimumPath(riskMap, visited, nexts.tail, dest)
else if 0 > point.x || 0 > point.y || riskMap.size <= point.y || riskMap(0).size <= point.x then
_findMinimumPath(riskMap, visited, nexts.tail, dest)
else
val cost = current.cost + riskMap(point.y)(point.x)
val nextVisited = visited + point
val availables = Vector(
Link(point.add(1, 0), cost),
Link(point.add(0, 1), cost),
Link(point.add(-1, 0), cost),
Link(point.add(0, -1), cost)
)
_findMinimumPath(riskMap, nextVisited, (nexts.tail ++ availables).sortBy(_.cost), dest)
val nexts = Vector(
Link(Point(1, 0), 0),
Link(Point(0, 1), 0),
)
def solve15_1(inputs: Vector[Vector[Int]]): Int =
_findMinimumPath(inputs, Set(Point(0, 0)), nexts, Point(inputs(0).size - 1, inputs.size - 1))
def solve15_2(inputs: Vector[Vector[Int]]): Int =
val width = inputs(0).size
val height = inputs.size
val riskMap: Vector[Vector[Int]] =
(0 until height * 5).map { y =>
(0 until width * 5).map { x =>
val risk = inputs(y % height)(x % width) + (y / height) + (x / width)
(risk - 1) % 9 + 1
}.toVector
}.toVector
_findMinimumPath(riskMap, Set(Point(0, 0)), nexts, Point(riskMap(0).size - 1, riskMap.size - 1))
@main def solve15(): Unit =
val in = new FileInputStream("example15-2.in")
System.setIn(in)
val inputs = Iterator.continually(StdIn.readLine())
.takeWhile(line => null != line && line.trim.nonEmpty)
.map(line => line.map(_.toInt - '0').toVector)
.toVector
println(solve15_1(inputs))
println(solve15_2(inputs))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment