Skip to content

Instantly share code, notes, and snippets.

@guillaumebort
Created June 15, 2011 15:49
Show Gist options
  • Save guillaumebort/1027392 to your computer and use it in GitHub Desktop.
Save guillaumebort/1027392 to your computer and use it in GitHub Desktop.
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)
}
}
Simulator(5,5).execute((Orientations.N,(1,2)),List('G','A','G','A','G','A','G','A','A'))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment