Advertisement
lluque

AoC day 13

Dec 14th, 2016
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 1.53 KB | None | 0 0
  1. import scala.collection.mutable
  2.  
  3. object day13 {
  4.  
  5.   case class Delta(x: Int, y: Int)
  6.   case class Point(x: Int, y: Int) {
  7.     def withinBoundaries: Boolean = x > -1 && y > -1
  8.     def +(delta: Delta): Point = Point(x + delta.x, y + delta.y)
  9.     def isWall: Boolean = {
  10.       val bin = (x * x + 3 * x + 2 * x * y + y + y * y + 1362).toBinaryString
  11.       bin.count(_ == '1') % 2 == 1
  12.     }
  13.   }
  14.  
  15.   def aStar(start: Point, goal: Point)(costFn: (Point, Point) => Int): Map[Point, Int] = {
  16.     val frontier = mutable.ListBuffer[(Point, Int)]((start, 0))
  17.     val costs = mutable.Map[Point, Int](start -> 0)
  18.     while (frontier.nonEmpty) {
  19.       val current = frontier.minBy(_._2)
  20.       frontier -= current
  21.       if (current._1 == goal) frontier.clear
  22.       else {
  23.         val newCost = costs(current._1) + 1
  24.         val neighbors = List(Delta(0, -1), Delta(0, 1), Delta(1, 0), Delta(-1, 0))
  25.           .map(current._1 + _).filter(p => p.withinBoundaries && !p.isWall)
  26.         for (next <- neighbors) {
  27.           if (!costs.contains(next) || newCost < costs(next)) {
  28.             costs(next) = newCost
  29.             val priority = newCost + costFn(goal, next)
  30.             frontier += ((next, priority))
  31.           }
  32.         }
  33.       }
  34.     }
  35.     costs.toMap
  36.   }
  37.  
  38.   val (start, end) = (Point(1, 1), Point(31, 39))
  39.   // Part 1
  40.   val results = aStar(start, end)((a, b) => math.abs(a.x - b.x) + math.abs(a.y - b.y))
  41.   println(results(end))
  42.   // Part 2
  43.   val results2 = aStar(start, end)((_,_) => 0)
  44.   println(results2.values.count(_ <= 50))
  45.  
  46. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement