Skip to content

Instantly share code, notes, and snippets.

@rbobillot
Created September 13, 2016 14:46
Show Gist options
  • Save rbobillot/33706819a6120a4795db99e3503f11ba to your computer and use it in GitHub Desktop.
Save rbobillot/33706819a6120a4795db99e3503f11ba to your computer and use it in GitHub Desktop.
trait Infos {
val validActions = 'r' :: 'l' :: 'a' :: Nil
val dirs = Map(0 -> "North", 1 -> "East", 2 -> "South", 3 -> "West")
def isAction: Char => Boolean = validActions contains _
implicit class StringCheck(str: String) {
def isActionString: Boolean = str forall isAction
def isNaAS: Boolean = !isActionString
def isNumber: Boolean = str forall (x => ('0' to '9') :+ '-' contains x)
def isNaN: Boolean = !isNumber
}
}
case class Coord(x:Int, y:Int, dir:String = "North")
object Walker extends Infos {
def usage: Unit = println("usage: walker.jar <X_POS_ON_GRID> <Y_POS_ON_GRID> <DIRECTIONS_STRING>")
def move(action:List[Char], dir:Int = 0)(x:Int, y:Int): List[Coord] =
action match {
case h :: t => h match {
case 'r' | 'l' => move(t, (4 + dir + (if ('r' == h) 1 else -1)) % 4)(x,y)
case 'a' => dir match {
case 0 | 2 => Coord(x,y,dirs(dir)) :: move(t, dir)(x, y + (if (dir == 0) 1 else -1))
case 1 | 3 => Coord(x,y,dirs(dir)) :: move(t, dir)(x + (if (dir == 1) 1 else -1), y)
}
}
case Nil => Coord(x,y,dirs(dir)) :: Nil
}
def putOnGrid(actions:String, x:String, y:String): Unit =
if (x.isNaN || y.isNaN || actions.isNaAS) usage else {
val coords: List[Coord] = move(actions.toList)(x.toInt, y.toInt)
val init: Coord = coords.head
val last: Coord = coords.last
val max:Coord = Coord(coords.map(_.x).max + 2, coords.map(_.y).max + 2)
val min:Coord = Coord(coords.map(_.x).min - 2, coords.map(_.y).min - 2)
println(
s"Initial position: \u001b[92m[${init.x},${init.y}]\u001b[0m facing ${init.dir}\n" +
(max.y to min.y by -1).map { y =>
(min.x to max.x).map { x =>
if (Coord(x,y,init.dir) == init) "\u001b[92mD\u001b[0m"
else if (Coord(x,y,last.dir) == last) "\u001b[91mA\u001b[0m"
else if (coords.map(e => (e.x,e.y)).contains((x,y))) "o"
else "."
}.mkString(" ")
}.mkString("\n") +
s"\nCurrent position: \u001b[91m[${last.x},${last.y}]\u001b[0m facing ${last.dir}"
)
}
//usage example: scala walker.jar -3 -6 "RAALAAAARARLLAAAAAAAALRAALRRARRAAAALLLAR"
def main(av:Array[String]): Unit = av.toList match {
case x :: y :: actions :: Nil => putOnGrid(actions.toLowerCase, x, y)
case actions :: Nil => putOnGrid(actions.toLowerCase, "0", "0")
case _ => usage
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment