Skip to content

Instantly share code, notes, and snippets.

@sadache
Created January 18, 2010 00:43
Show Gist options
  • Save sadache/279700 to your computer and use it in GitHub Desktop.
Save sadache/279700 to your computer and use it in GitHub Desktop.
object Application {
def main(args :Array[String]){
println(Simulator(5,5).execute((Orientations.N,(1,2)),List('G','A','G','A','G','A','G','A','A')))
println(Simulator(5,5).execute((Orientations.E,(3,3)),List('A','A','D','A','A','D','A','D','D','A')))
}
object Orientations {
type Orientation=Char
val N='N'
val E='E'
val W='W'
val S='S'
val clockWise=List(N,E,S,W)
def next[A](elements:List[A],e:A):Option[A]= elements.drop(elements.indexOf(e)+1).firstOption
def previous[A](elements:List[A],e:A):Option[A]= elements.take(elements.indexOf(e)).lastOption
def right(o:Orientation)= next(clockWise,o).getOrElse(clockWise.first)
def left(o:Orientation)= previous(clockWise,o).getOrElse(clockWise.last)
}
case class Simulator(bounds:(Int,Int)) {
import Orientations._
type Coordination=(Int,Int)
type State= (Orientation,Coordination)
def commandMap(c:Char,s:State):State= {
val (o,cord)=s
c match{
case 'G' => (left(o),cord)
case 'D'=>(right(o),cord)
case 'A'=>(o,advance(o,cord))
}
}
def advance(o:Orientation,cord:(Int,Int)):(Int,Int)={
val (x,y)=cord
o match {
case N=> (x,y+1)
case S=> (x,y-1)
case W=> (x-1,y)
case E=> (x+1,y)
}
}
def execute(initial:State,commands:List[Char])=
commands.foldLeft(initial)((state,c)=> notOutOfBound(commandMap(c,state)).getOrElse(state))
def notOutOfBound(s:State):Option[State]={
val (_,(x,y))=s
val (maxX,maxY)=bounds
if (x>maxX||y>maxY) None else Some(s)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment