Skip to content

Instantly share code, notes, and snippets.

@Ramasubramanian
Last active September 11, 2016 05:03
Show Gist options
  • Save Ramasubramanian/49f7197c13b3a74d81ea26ee37f11237 to your computer and use it in GitHub Desktop.
Save Ramasubramanian/49f7197c13b3a74d81ea26ee37f11237 to your computer and use it in GitHub Desktop.
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