Last active
September 11, 2016 05:03
-
-
Save Ramasubramanian/49f7197c13b3a74d81ea26ee37f11237 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
module LangtonsAnt | |
type Direction = Up | Down | Left | Right | |
type CellColor = Black | White | |
type Cell = {Row: int; Column: int; Color: CellColor; Ant: Ant option} | |
and Ant = {Cell: Cell; Direction: Direction} | |
type Plane = {Cells: Cell[][]} | |
let getColor color = | |
match color with | |
| CellColor.Black -> CellColor.White | |
| CellColor.White -> CellColor.Black | |
let flipColor cell: Cell = | |
{cell with Color = getColor cell.Color} | |
let removeAnt cell = | |
{cell with Ant = None} | |
let removeAntAndFlipColor = removeAnt >> flipColor | |
let getClockwiseDirection direction = | |
match direction with | |
| Up -> Right | |
| Right -> Down | |
| Down -> Left | |
| Left -> Up | |
let getAntiClockwiseDirection direction = | |
match direction with | |
| Up -> Left | |
| Left -> Down | |
| Down -> Right | |
| Right -> Up | |
let turn ant = | |
let newDirection = | |
match ant.Cell.Color with | |
| CellColor.Black -> getAntiClockwiseDirection ant.Direction | |
| CellColor.White -> getClockwiseDirection ant.Direction | |
{ant with Direction = newDirection} | |
let incrIndex index plane = | |
let output = if index >= (Array.length plane.Cells - 1) then 0 else index + 1 | |
output | |
let decrIndex index plane = | |
let output = if index = 0 then (Array.length plane.Cells - 1) else index - 1 | |
output | |
let getNextCell direction currentCell plane = | |
match direction with | |
| Up -> plane.Cells.[decrIndex currentCell.Row plane].[currentCell.Column] | |
| Left -> plane.Cells.[currentCell.Row].[decrIndex currentCell.Column plane] | |
| Down -> plane.Cells.[incrIndex currentCell.Row plane].[currentCell.Column] | |
| Right -> plane.Cells.[currentCell.Row].[incrIndex currentCell.Column plane] | |
let moveForward plane ant = | |
let nextCell = getNextCell ant.Direction ant.Cell plane | |
let newAnt = {ant with Cell = {nextCell with Ant = None}} | |
{newAnt with Cell = {newAnt.Cell with Ant = Some newAnt}} | |
let cellToString cell = | |
match cell.Ant with | |
| Some(_) -> printf " ✖" | |
| None -> match cell.Color with | |
| Black -> printf " ▢" | |
| White -> printf " ◼" | |
let printRow row = | |
Array.iter cellToString row | |
printfn "" | |
let printPlane plane = | |
Array.iter printRow plane.Cells | |
printfn("--------xxx-------") | |
let createPlane planeSize = | |
let cells = seq {for x in 0 .. planeSize - 1 do | |
for y in 0 .. planeSize - 1 -> | |
{Row = x; Column = y; Color = White; Ant = None}} | |
{Cells = Seq.groupBy (fun e -> e.Row) cells | |
|> Seq.map (fun e -> Seq.toArray (snd e)) | |
|> Seq.toArray} | |
let step (ant,plane, printSteps) = | |
let oldCell = ant.Cell | |
let ant = turn ant |> moveForward plane | |
Array.set plane.Cells.[oldCell.Row] oldCell.Column (removeAntAndFlipColor oldCell) | |
Array.set plane.Cells.[ant.Cell.Row] ant.Cell.Column ant.Cell | |
if printSteps then | |
System.Console.Clear() | |
printPlane plane | |
(ant, plane, printSteps) | |
let execute planeSize steps printSteps = | |
let plane = createPlane planeSize | |
let antCell = {Row= planeSize/2; Column= planeSize/2; Color = White; Ant = None} | |
let ant = {Cell = antCell; Direction = Up} | |
let cell = {antCell with Ant = Some ant} | |
let ant = {ant with Cell = cell} | |
Array.set plane.Cells.[ant.Cell.Row] ant.Cell.Column ant.Cell | |
let ant,plane,_ = Seq.fold (fun acc i -> step acc) (ant, plane, printSteps) (seq {1.. steps}) | |
printPlane plane | |
() | |
[<EntryPoint>] | |
let main argv = | |
let res = execute (System.Int32.Parse argv.[0]) (System.Int32.Parse argv.[1]) | |
0 // return an integer exit code |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment