Created
September 13, 2016 14:46
-
-
Save rbobillot/33706819a6120a4795db99e3503f11ba to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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