I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

# Langton's ant

Langton's ant
You are encouraged to solve this task according to the task description, using any language you may know.

Langton's ant is a cellular automaton that models an ant sitting on a plane of cells, all of which are white initially, the ant facing in one of four directions.

Each cell can either be black or white.

The ant moves according to the color of the cell it is currently sitting in, with the following rules:

1.   If the cell is black, it changes to white and the ant turns left;
2.   If the cell is white, it changes to black and the ant turns right;
3.   The ant then moves forward to the next cell, and repeat from step 1.

This rather simple ruleset leads to an initially chaotic movement pattern, and after about 10000 steps, a cycle appears where the ant moves steadily away from the starting location in a diagonal corridor about 10 cells wide. Conceptually the ant can then walk infinitely far away.

Start the ant near the center of a 100x100 field of cells, which is about big enough to contain the initial chaotic part of the movement.

Follow the movement rules for the ant, terminate when it moves out of the region, and show the cell colors it leaves behind.

The problem has received some analysis; for more details, please take a look at the Wikipedia article   (a link is below)..

## 11l

Translation of: Python
T.enum Dir   UP   RIGHT   DOWN   LEFT -V color_WHITE = Char(‘ ’)-V color_BLACK = Char(‘#’) F invert_color(&grid, x, y)   ‘Invert the color of grid at x, y coordinate.’   I grid[y][x] == :color_BLACK      grid[y][x] = :color_WHITE   E      grid[y][x] = :color_BLACK F next_direction(grid, x, y, =direction)   ‘Compute next direction according to current position and direction.’   V turn_right = grid[y][x] != :color_BLACK   V direction_index = Int(direction)   I turn_right      direction_index = (direction_index + 1) % 4   E      direction_index = (direction_index + 4 - 1) % 4   V directions = [Dir.UP, Dir.RIGHT, Dir.DOWN, Dir.LEFT]   direction = directions[direction_index]   R direction F next_position(=x, =y, direction)   ‘Compute next position according to direction.’   I direction == UP      y--   E I direction == RIGHT      x--   E I direction == DOWN      y++   E I direction == LEFT      x++   R (x, y) F print_grid(grid)   ‘Display grid.’   print(80 * ‘#’)   print(grid.map(row -> row.join(‘’)).join("\n")) F ant(width, height, max_nb_steps)   ‘Langton's ant.’   V grid = [[:color_WHITE] * width] * height   V x = width I/ 2   V y = height I/ 2   V direction = Dir.UP    V i = 0   L i < max_nb_steps & x C 0 .< width & y C 0 .< height      invert_color(&grid, x, y)      direction = next_direction(grid, x, y, direction)      (x, y) = next_position(x, y, direction)      i++    print_grid(grid) ant(width' 75, height' 52, max_nb_steps' 12000)
Output:
################################################################################

##  ############  ##
#  ####          #  ##
###   ##            ## #
# #  #         #  #    #
##  ## # #         ###       #
### #  #   #     #     ## ##  ###
# #  ###  ## #### ##   # #  # ##  ##
# ### ##  # ##  ### # #     ###   ###
#     #   ##### # #  ####  #   ### # # #
### ##   # ####  ## ## ###### # ### #   #
# ### # ## # # ## ## ## #   ##### ### ##
# #   # ## ###   #   # #  ####    # ##
#  #         ## ##   #  ##     ## #     ##
###   # # ## ###  #  ##     #   ### ##  ## #
#  ###  ##   ## ##   ###  #    #  ## ####   #
###   #   # #  # # #### ##  # ## ###  #     #
#  ###  # ##    #  # ###  #      ### ## #  #  ##
###   #     # ## # ##  ##  ##### ####  #### ##   #
#  ###  # # #  # ### # # ##      ##   # # #    #   #
###   #  ## ###  ## #   ##       #### ####   #      #
#  ###  # #  #   ##  ########### #  ####  #    #    #
###   #  ##      # ####  ##  #########  #  ##    #  ##
#  ###  # #   ##  # ##   ## ## ### ###   #  # ##  #### #
###   #  ##   #  # ###### ## # ## # #    ### ###   ##   #
#  ###  # #   #     ##### # #####     # #  ## #    ##   #
###   #  ##    #     # ## ##### ##  # #   #  #  ## #  #  #
#  ###  # #     #    #   #### #  ##### ##   ##########   ##
###   #  ##      # ##   ##   #  #   ####  #   ## #### ##
#  ###  # #        ##### #  ##   ## #   #    # #  #  #  # #
###   #  ##          ##  ## # # #    ## ## # # ##  #  ##  ##
#  ###  # #                 #  #    # ######## # # ##  #### #
###   #  ##                  #  #   #       ## ##   #  #  ## #
##  # #                    #  #  #      #  ##  ##   ## ####
##  #  ##                      ##   #       ##  ##    #   # ###
# # # #                            # ##  ####    #### ### ####
#### ##                              ##  ####    ##  # ## # #  #
# ## #                                ##    ##    ## ### ## #####
####                                                # ## #  ####
##                                                     ## ## ##
##
# ##  #### #
#  # ###  ###
# ## #  #  #
##      ##
##


## ALGOL 68

BEGIN    # size of board for Langton's ant #    INT max board = 100;    [ 1 : max board, 1 : max board ]CHAR board;    # start with the board all white #    CHAR white = " ", black = "#";    FOR r TO 1 UPB board DO FOR c TO 2 UPB board DO board[ r, c ] := white OD OD;    # possible ant directions #    INT head left = 0, head up = 1, head right = 2, head down = 3;    # returns the new direction if we turn left from curr direction #    OP LEFT = ( INT curr direction )INT:       IF   curr direction = head left  THEN head down       ELIF curr direction = head down  THEN head right       ELIF curr direction = head right THEN head up       ELSE                                  head left       FI ; # LEFT #    # returns the new direction if we turn right from curr direction #    OP RIGHT = ( INT curr direction )INT:       IF   curr direction = head left  THEN head up       ELIF curr direction = head up    THEN head right       ELIF curr direction = head right THEN head down       ELSE                                  head left       FI ; # RIGHT #    # move the ant until it leaves the board #    INT ant row := max board OVER 2;    INT ant col := max board OVER 2;    INT ant direction := head up;    INT max row := 1;    INT max col := 1;    INT min row := max board;    INT min col := max board;    INT moves := 0;    WHILE ant row >= 1 LWB board AND ant row <= 1 UPB board      AND ant col >= 2 LWB board AND ant col <= 2 UPB board    DO        moves +:= 1;        IF ant row > max row THEN max row := ant row FI;        IF ant col > max col THEN max col := ant col FI;        IF ant row < min row THEN min row := ant row FI;        IF ant col < min col THEN min col := ant col FI;        IF board[ ant row, ant col ] = white THEN            # ant turns right on a white square #            ant direction := RIGHT ant direction;            board[ ant row, ant col ] := black        ELSE            # ant turns left on a black square #            ant direction :=  LEFT ant direction;            board[ ant row, ant col ] := white        FI;        # move the ant #        IF     ant direction = head up    THEN ant row -:= 1        ELIF   ant direction = head down  THEN ant row +:= 1        ELIF   ant direction = head left  THEN ant col -:= 1        ELSE # ant direction = head right #    ant col +:= 1        FI    OD;    # show resultant position #    print( ( "After ", whole( moves, 0 ), " moves."           , " Showing rows ", whole( min row,0 ), " to ", whole( max row, 0 )           , " columns ", whole( min col,0 ), " to ", whole( max col, 0 )           , newline           )         );    FOR r FROM min row TO max row DO        print( ( board[ r, min col : max col ], newline ) )    ODEND
Output:
After 11655 moves. Showing rows 28 to 78 columns 1 to 79
##  ############  ##
#  ####          #  ##
###   ##            ## #
# #  #         #  #    #
##  ## # #         ###       #
### #  #   #     #     ## ##  ###
# #  ###  ## #### ##   # #  # ##  ##
# ### ##  # ##  ### # #     ###   ###
#     #   ##### # #  ####  #   ### # # #
### ##   # ####  ## ## ###### # ### #   #
# ### # ## # # ## ## ## #   ##### ### ##
# #   # ## ###   #   # #  ####    # ##
#  #         ## ##   #  ##     ## #     ##
###   # # ## ###  #  ##     #   ### ##  ## #
#  ###  ##   ## ##   ###  #    #  ## ####   #
###   #   # #  # # #### ##  # ## ###  #     #
#  ###  # ##    #  # ###  #      ### ## #  #  ##
###   #     # ## # ##  ##  ##### ####  #### ##   #
#  ###  # # #  # ### # # ##      ##   # # #    #   #
###   #  ## ###  ## #   ##       #### ####   #      #
#  ###  # #  #   ##  ########### #  ####  #    #    #
###   #  ##      # ####  ##  #########  #  ##    #  ##
#  ###  # #   ##  # ##   ## ## ### ###   #  # ##  #### #
###   #  ##   #  # ###### ## # ## # #    ### ###   ##   #
#  ###  # #   #     ##### # #####     # #  ## #    ##   #
###   #  ##    #     # ## ##### ##  # #   #  #  ## #  #  #
#  ###  # #     #    #   #### #  ##### ##   ##########   ##
###   #  ##      # ##   ##   #  #   ####  #   ## #### ##
#  ###  # #        ##### #  ##   ## #   #    # #  #  #  # #
###   #  ##          ##  ## # # #    ## ## # # ##  #  ##  ##
#  ###  # #                 #  #    # ######## # # ##  #### #
###   #  ##                  #  #   #       ## ##   #  #  ## #
#  ###  # #                    #  #  #      #  ##  ##   ## ####
###   #  ##                      ##   #       ##  ##    #   # ###
#  ###  # #                            # ##  ####    #### ### ####
###   #  ##                              ##  ####    ##  # ## # #  #
#  ###  # #                                ##    ##    ## ### ## #####
###   #  ##                                                # ## #  ####
#  ###  # #                                                     ## ## ##
###   #  ##                                                      ##
#  ###  # #                                                     # ##  #### #
###   #  ##                                                     #  # ###  ###
#  ###  # #                                                      # ## #  #  #
###   #  ##                                                        ##      ##
##  # #                                                          ##
##  #  ##
# # # #
#### ##
# ## #
####
##


## AutoHotkey

ahk forum: discussion

Works with: AutoHotkey 1.1
(Fixed by just me)
#NoEnvSetBatchLines, -1; DirectionsDirections := {0: "North", 1: "East", 2: "South", 3: "West"}; Initialize the plane (set all cells to white)White := 0xFFFFFFPlane := []PW := PH := 100loop, % PH {    I := A_Index    loop, % PW        Plane[I, A_Index] := White}; Let it runDI := D := 0 ; initial directionX := Y := 50 ; initial coordinateswhile (X > 0) && (X <= PW) && (Y > 0) && (Y <= PH) {    D := (D + ((Plane[X, Y] ^= White) ? 1 : 3)) & 3    if (D & 1)        X += -(D = 3) + (D = 1)    else        Y += -(D = 0) + (D = 2)}; Show the resultHBM := CreateDIB(Plane, PW, PH, 400, 400, 0)Gui, Margin, 0, 0Gui, Add, Text, x0 y0 w20 h440 Center 0x200, WGui, Add, Text, x20 y0 w400 h20 Center 0x200, NGui, Add, Picture, x20 y20 w400 h400 0x4E hwndHPIC ; SS_REALSIZECONTROL = 0x40 | SS_BITMAP = 0xEDllCall("User32.dll\SendMessage", "Ptr", HPIC, "UInt", 0x172, "Ptr", 0, "Ptr", HBM) ; STM_SETIMAGE = 0x172Gui, Add, Text, xp+5 yp h20 0x200 BackgroundTrans, % "Initial direction: " . Directions[DI]Gui, Add, Text, x20 y420 w400 h20 Center 0x200, SGui, Add, Text, x420 y0 w20 h440 Center 0x200, EGui, Show, , Langton's ant (%PW%x%PH%)Return GuiClose:ExitApp CreateDIB(PixelArray, PAW, PAH, BMW := 0, BMH := 0, Gradient := 1) { ; SKAN, 01-Apr-2014 / array version by just me    SLL := (PAW * 3) + (PAW & 1)    VarSetCapacity(BMBITS, SLL * PAH, 0)    P := &BMBITS    loop, % PAH {        R := A_Index        loop, % PAW            P := Numput(PixelArray[R, A_Index], P + 0, "UInt") - 1        P += (PAW & 1)    }    HBM := DllCall("Gdi32.dll\CreateBitmap", "Int", PAW, "Int", PAH, "UInt", 1, "UInt", 24, "Ptr", 0, "UPtr")    HBM := DllCall("User32.dll\CopyImage", "Ptr", HBM, "UInt", 0, "Int", 0, "Int", 0, "UInt", 0x2008, "UPtr")    DllCall( "Gdi32.dll\SetBitmapBits", "Ptr", HBM, "UInt", SLL * PAH, "Ptr", &BMBITS)    if (!Gradient)        HBM := DllCall("User32.dll\CopyImage", "Ptr", HBM, "UInt", 0, "Int", 0, "Int", 0, "Int", 8, "UPtr")    return DllCall("User32.dll\CopyImage", "Ptr", HBM, "UInt", 0, "Int", BMW, "Int", BMH, "UInt", 0x200C, "UPtr")} ; http://ahkscript.org/boards/viewtopic.php?f=6&t=3203

 Global $iCountMax = 100000Global$aFields[100][100][2]Global $iDelayStep = 10 ; stop between steps in msec Global$aDirection[4][4] = [ _ ; [ direction 0-3 ][ left change x, y, right change x, y ][-1,  0, +1,  0], _   ; == direction 0[ 0, -1,  0, +1], _   ; == direction 1[+1,  0, -1,  0], _   ; == direction 2[ 0, +1,  0, -1]]     ; == direction 3 Global $hGui = GUICreate("Langton's ant", 100*8, 100*8)GUISetBkColor(0xFFFFFF) For$i = 0 To 99	For $j = 0 To 99$aFields[$i][$j][0] = GUICtrlCreateLabel('', $j*8,$i*8)		GUICtrlSetColor(-1, 0xFF0000)		$aFields[$i][$j][1] = 0 NextNext GUISetState() GUICtrlSetData($aFields[49][49][0], '#') Do	Sleep($iDelayStep)Until Not _SetAnt() DoUntil GUIGetMsg() = -3 Func _SetAnt() Local Static$iRowLast = 49, $iColLast = 49,$iCount = 0	Local Static $aCol[2] = [0xFFFFFF,0x000000],$iDirection = 0	Local $iRow,$iCol, $fRight = False If$iCount = $iCountMax Then Return 0 ; == get current color Local$iLastColor = $aFields[$iRowLast][$iColLast][1] ; == go to left/right If$iLastColor = 0 Then $fRight = True ; == set the ant to the next field Local$indexX = 0, $indexY = 1 If$fRight Then		$indexX = 2$indexY = 3	EndIf	$iRow =$iRowLast + ($aDirection[$iDirection][$indexX])$iCol = $iColLast + ($aDirection[$iDirection][$indexY])	If $iRow < 0 Or$iRow > 99 Or $iCol < 0 Or$iCol > 99 Then Return 0	GUICtrlSetData($aFields[$iRowLast][$iColLast][0], '') GUICtrlSetData($aFields[$iRow][$iCol][0], '#') 	; == direction for next step	If $fRight Then$iDirection += 1		If $iDirection = 4 Then$iDirection = 0	Else		$iDirection -= 1 If$iDirection = -1 Then $iDirection = 3 EndIf ; == change the color of the current field GUICtrlSetBkColor($aFields[$iRowLast][$iColLast][0], $aCol[(Not$iLastColor)*1])	$aFields[$iRowLast][$iColLast][1] = (Not$iLastColor)*1 	$iRowLast =$iRow	$iColLast =$iCol	$iCount += 1 WinSetTitle($hGui, '', "Langton's ant      [ step: " & StringFormat('%06d', $iCount) & " ]") Return 1EndFunc ;==>_SetAnt  To see the GUI output, click here. --BugFix (talk) 14:48, 16 November 2013 (UTC) ## AWK  # usage: awk -v debug=0 -f langton.awk # Simulates the cellular automaton "Langton's ant",# see http://en.wikipedia.org/wiki/Langton%27s_ant function turnRight() { dir++ if( dir>4 ) { dir=1 }}function turnLeft() { dir-- if( dir<1 ) { dir=4 }}function move() { if (dir==1) { y--; z="^" } if (dir==3) { y++; z="v" } if (dir==2) { x++; z=">" } if (dir==4) { x--; z="<" }} function ant() { if( debug ) AntStat() ## if( grid[x,y]==0 ) { turnLeft() } else { turnRight() } if( grid[x,y]==0 ) { color=1 } else { color=0 } if( debug ) print( "# action", color, dir, z ) ## grid[x,y] = color move()} ### function AntStat() { printf( "Move# %d : Ant @ x=%d y=%d dir=%d %s color=%d\n", moveNr, x,y, dir,z, grid[x,y] )}function dumpGrid() { AntStat() printf( "Grid:" ) for(xx=1; xx<=limit/10; xx++) { printf( "....+....%s", xx ) } printf "\n" cSum=0 for(yy=1; yy <= limit; yy++) { printf( "%4d:",yy ) for(xx=1; xx <= limit; xx++) { c = grid[xx,yy] if( c ) cSum++ c1++ c2+=grid[xx,yy] if( (xx==x)&&(yy==y) ) { c=z } # Ant printf( c ) } printf( "\n" ) } printf( "Cells: %d 'black' cells: %d Moves: %d\n\n", limit*limit, cSum, moveNr )} BEGIN { print( "Langton's ant\n" ) limit = 72 for(x=1; x <= limit; x++) { for(y=1; y <= limit; y++) { grid[x,y] = 0 } } moveNr = 0 x = 36 y = 28 dir = 1 # 1=up/north 2=right/east 3=down/south 4=left/west z = "!" while( moveNr < 11200 ) { moveNr++ ant() if(x<0 || x>limit) break if(y<0 || y>limit) break # Snapshots: if (moveNr==163 || moveNr==1297 || moveNr==10095 ) dumpGrid() if (y<=5 ) break } dumpGrid()}END { print("END.") }  ## BBC BASIC  REM Implementation of Langton's ant for Rosetta Code fieldsize%=100 REM Being pedantic, this will actually result in a field of 101 square, REM since arrays start at 0, and my implementation allows them to use it DIM field&(fieldsize%,fieldsize%) : REM variables with an & suffix are byte variables x%=fieldsize%/2 y%=fieldsize%/2 d%=0 REPEAT IF field&(x%,y%)=0 THEN field&(x%,y%)=1:d%-=1 ELSE field&(x%,y%)=0:d%+=1 GCOL 15*field&(x%,y%) PLOT 69,x%*2,y%*2 :REM for historical reasons there are two "plot points" per pixel d%=(d%+4) MOD 4 :REM ensure direction is always between 0 and 3 CASE d% OF WHEN 0:y%+=1 WHEN 1:x%+=1 WHEN 2:y%-=1 WHEN 3:x%-=1 ENDCASE UNTIL x%>fieldsize% OR x%<0 OR y%>fieldsize% OR y%<0 END  ## bc The output function o prints the resulting image (as a PBM image) to stdout. One can either store it into a file or pipe it through an image viewer (e.g. bc langton.bc | display). define o() { auto i, j "P1 " w h for (j = 0; j < h; j++) { for (i = 0; i < w; i++) { a[j * w + i] } }} define l(w, h, x, y) { auto a[], d, i, x[], y[] /* d represents one of the four possible directions: * 0 * ⇑ * 3⇐ ⇒1 * ⇓ * 2 * The arrays x[] and y[] contain the changes to the x and y direction for * each value of d. */ x[1] = 1 x[3] = -1 y[0] = -1 y[2] = 1 while (1) { i = y * w + x if (a[i] == 0) d += 1 /* turn right if white */ if (a[i] == 1) d -= 1 /* turn left if black */ if (d < 0) d = 3 if (d > 3) d = 0 x += x[d] y += y[d] a[i] = 1 - a[i] /* toggle cell colour */ if (x < 0) break if (x == w) break if (y < 0) break if (y == h) break } o()} l(100, 100, 50, 50)quit ## Befunge "22222 -"*>>>1-:0\:"P"%\v>\7%1g48*-/2%3*48*+,1+:20g!v1g01+55p03:_$>@!"$([email protected]vp00_^#!:p+7/"P"<<^g+7/*5"p"\%"P"/7::+g03*"d":_$,1+>:40g!^1g03<_::10g\v>00g+4%:00p::3\\1-*50g+50p:2\-\0*+::0\\"c"+50g:0\\"c"++#^-*84g1<v^+1*2g09pg08g07-*g06-1*2p09:%2/g06:gp08:+7/*5"p"\p07:%"P"/7:p060p+:7%^>>-:0!*+10p::20g\-:0*+20p:"d"*50g::30g\-:0!*+30p::40g\-:0*+4
Output:
                                          ##  ############  ##
#  ####          #  ##
###   ##            ## #
# #  #         #  #    #
##  ## # #         ###       #
### #  #   #     #     ## ##  ###
# #  ###  ## #### ##   # #  # ##  ##
# ### ##  # ##  ### # #     ###   ###
#     #   ##### # #  ####  #   ### # # #
### ##   # ####  ## ## ###### # ### #   #
# ### # ## # # ## ## ## #   ##### ### ##
# #   # ## ###   #   # #  ####    # ##
#  #         ## ##   #  ##     ## #     ##
###   # # ## ###  #  ##     #   ### ##  ## #
#  ###  ##   ## ##   ###  #    #  ## ####   #
###   #   # #  # # #### ##  # ## ###  #     #
#  ###  # ##    #  # ###  #      ### ## #  #  ##
###   #     # ## # ##  ##  ##### ####  #### ##   #
#  ###  # # #  # ### # # ##      ##   # # #    #   #
###   #  ## ###  ## #   ##       #### ####   #      #
#  ###  # #  #   ##  ########### #  ####  #    #    #
###   #  ##      # ####  ##  #########  #  ##    #  ##
#  ###  # #   ##  # ##   ## ## ### ###   #  # ##  #### #
###   #  ##   #  # ###### ## # ## # #    ### ###   ##   #
#  ###  # #   #     ##### # #####     # #  ## #    ##   #
###   #  ##    #     # ## ##### ##  # #   #  #  ## #  #  #
#  ###  # #     #    #   #### #  ##### ##   ##########   ##
###   #  ##      # ##   ##   #  #   ####  #   ## #### ##
#  ###  # #        ##### #  ##   ## #   #    # #  #  #  # #
###   #  ##          ##  ## # # #    ## ## # # ##  #  ##  ##
#  ###  # #                 #  #    # ######## # # ##  #### #
###   #  ##                  #  #   #       ## ##   #  #  ## #
#  ###  # #                    #  #  #      #  ##  ##   ## ####
###   #  ##                      ##   #       ##  ##    #   # ###
#  ###  # #                            # ##  ####    #### ### ####
###   #  ##                              ##  ####    ##  # ## # #  #
#  ###  # #                                ##    ##    ## ### ## #####
###   #  ##                                                # ## #  ####
#  ###  # #                                                     ## ## ##
###   #  ##                                                      ##
#  ###  # #                                                     # ##  #### #
###   #  ##                                                     #  # ###  ###
#  ###  # #                                                      # ## #  #  #
###   #  ##                                                        ##      ##
#  ###  # #                                                          ##
### #  ##
# # # # #
#### ##
# ## #
####
##

## BQN

Ant is the main function, which runs the ant simulation given a starting point, direction and grid of zeros.

Fmt then formats into hashes and spaces.

_while_ is an idiom from BQNcrate which helps with conditional looping.

Rot ← ¬⊸{-⌾(𝕨⊸⊑)⌽𝕩}Fmt ← ⊏⟜" #"_while_ ← {𝔽⍟𝔾∘𝔽_𝕣_𝔾∘𝔽⍟𝔾𝕩} Ant ← 2⊑{ # Generator Block  p‿d‿g:  r ← d Rot˜ p⊑g  ⟨    p + r    r    ¬⌾(p⊸⊑)g  ⟩} _while_ {   # Condition Block  p‿d‿g:  ∧´(p≥0‿0)∧p<≢g} •Show Fmt Ant ⟨50‿50, 0‿1, 100‿100⥊0⟩

Try It! (Running will take some time due to JS, ≈40 secs on my machine)

## C

Requires ANSI terminal.

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h> int w = 0, h = 0;unsigned char *pix; void refresh(int x, int y){	int i, j, k;	printf("\033[H");	for (i = k = 0; i < h; putchar('\n'), i++)		for (j = 0; j < w; j++, k++)			putchar(pix[k] ? '#' : ' ');} void walk(){	int dx = 0, dy = 1, i, k;	int x = w / 2, y = h / 2; 	pix = calloc(1, w * h);	printf("\033[H\033[J"); 	while (1) {		i = (y * w + x);		if (pix[i]) k = dx, dx = -dy, dy = k;		else	    k = dy, dy = -dx, dx = k; 		pix[i] = !pix[i];		printf("\033[%d;%dH%c", y + 1, x + 1, pix[i] ? '#' : ' '); 		x += dx, y += dy; 		k = 0;		if (x < 0) {			memmove(pix + 1, pix, w * h - 1);			for (i = 0; i < w * h; i += w) pix[i] = 0;			x++, k = 1;		}		else if (x >= w) {			memmove(pix, pix + 1, w * h - 1);			for (i = w-1; i < w * h; i += w) pix[i] = 0;			x--, k = 1;		} 		if (y >= h) {			memmove(pix, pix + w, w * (h - 1));			memset(pix + w * (h - 1), 0, w);			y--, k = 1;		}		else if (y < 0) {			memmove(pix + w, pix, w * (h - 1));			memset(pix, 0, w);			y++, k = 1;		}		if (k) refresh(x, y);		printf("\033[%d;%dH\033[[email protected]\033[m", y + 1, x + 1); 		fflush(stdout);		usleep(10000);	}} int main(int c, char **v){	if (c > 1) w = atoi(v[1]);	if (c > 2) h = atoi(v[2]);	if (w < 40) w = 40;	if (h < 25) h = 25; 	walk();	return 0;}

## C#

using System; namespace LangtonAnt{    public struct Point    {        public int X;        public int Y;         public Point(int x, int y)        {            X = x;            Y = y;        }    }     enum Direction    {        North, East, West, South    }     public class Langton    {        public readonly bool [,] IsBlack;        private Point _origin;        private Point _antPosition = new Point(0, 0);        public bool OutOfBounds { get; set;}         // I don't see any mention of what direction the ant is supposed to start out in        private Direction _antDirection = Direction.East;         private readonly Direction[] _leftTurn = new[] { Direction.West, Direction.North, Direction.South, Direction.East };        private readonly Direction[] _rightTurn = new[] { Direction.East, Direction.South, Direction.North, Direction.West };        private readonly int[] _xInc = new[] { 0, 1,-1, 0};        private readonly int[] _yInc = new[] {-1, 0, 0, 1};         public Langton(int width, int height, Point origin)        {            _origin = origin;            IsBlack = new bool[width, height];            OutOfBounds = false;        }         public Langton(int width, int height) : this(width, height, new Point(width / 2, height / 2)) {}         private void MoveAnt()        {            _antPosition.X += _xInc[(int)_antDirection];            _antPosition.Y += _yInc[(int)_antDirection];        }         public Point Step()        {            if (OutOfBounds)            {                throw new InvalidOperationException("Trying to step after ant is out of bounds");            }            Point ptCur = new Point(_antPosition.X + _origin.X, _antPosition.Y + _origin.Y);            bool leftTurn = IsBlack[ptCur.X, ptCur.Y];            int iDirection = (int) _antDirection;            _antDirection = leftTurn ? _leftTurn[iDirection] : _rightTurn[iDirection];            IsBlack[ptCur.X, ptCur.Y] = !IsBlack[ptCur.X, ptCur.Y];            MoveAnt();            ptCur = new Point(_antPosition.X + _origin.X, _antPosition.Y + _origin.Y);            OutOfBounds =                 ptCur.X < 0 ||                ptCur.X >= IsBlack.GetUpperBound(0) ||                ptCur.Y < 0 ||                ptCur.Y >= IsBlack.GetUpperBound(1);            return _antPosition;        }    }    class Program    {        static void Main()        {            Langton ant = new Langton(100, 100);             while (!ant.OutOfBounds) ant.Step();             for (int iRow = 0; iRow < 100; iRow++)            {                for (int iCol = 0; iCol < 100; iCol++)                {                    Console.Write(ant.IsBlack[iCol, iRow] ? "#" : " ");                }                Console.WriteLine();            }             Console.ReadKey();        }    }} 

Output:

<Blank lines eliminated for efficiency>                          # #
## # #
# ### ##
#### ### #
##### #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #  ##
###   #  ##  ##
#   ## ##  ##   #
####   ###   #   #  ###
#    #   #   ## ####   #
###    #   # #      # ## #
###    # ##     # ##  # ##
#    #   ## # #     ##
# #      # #####  #   #
#   #####          ## ######
###  ##  # ## # # #   ## # ##
##  # ####### #   #  ###    ## #
#  #  ###### ##   #  # ##   #   #
#    # # ## #  ###### #######   #
# #### ## # ####    ##  ## # ## #
#    ####   #  # ###### ##    ###
#   # ## # ### #  ##  ##   ###
#######    #  ## ## #     #
####  ## ##  #### ## ## ##  #     #
#    # #   ### ## ###    # ####    #
###       ### # # #####    # #      #
# #   ### #### ## #   ## ### ##     #
## ##  ####    #### # # #     #
#    #  ##   ###  ###     ###      #
##   ## ### ####  #      ###   ##  #
## # ####     #   #  # ## ### ##   #
#### ##   ## ####  # #  #  #  ###   #
# ## ###  # # ## # #     # #     # #
# #  #    ## ##  # #  ### ##
## #    #  ##### #    #    #  # #
# ## #  #    ## ## #  ###      ###
# #   #  #  #  #  ###   ##  ##    #
### # ##### ###### ### ####### # ##
# # #    #####   ##  ##### #####
#  ##   #      #  # ##  ### ###
####   ##### #########   # #
##    #  #     ### # #   # ###  ###
#  #  #### ##   ### ##   ### ##     ##
###    # ## # #####   #    #  #  ## ###
# ##### # #   ##  ##     #    #   #  #
###### ####  ## #   #  ##  # # ##
##      # ### ##  ####   #   ###
#  # #####  #   # ##   #  #  #
## ### #######     #     # ##
# #  ## ##      #   ##    #
#  # ####        ###  ##  #
# ## ###            ##  ##
##
##


## C++

If you want to see it running infinitely, set the const bool INFINIT_RUN = true

 #include <windows.h>#include <string> //--------------------------------------------------------------------------------------------------using namespace std; //--------------------------------------------------------------------------------------------------const int BMP_SIZE = 600, CELL_SIZE = 4, GRID_SIZE = BMP_SIZE / CELL_SIZE;const bool INFINIT_RUN = false; enum cellState { WHITE, BLACK, ANT };enum facing { NOR, EAS, SOU, WES };enum state { RUNNING, RESTING }; //--------------------------------------------------------------------------------------------------class myBitmap{public:    myBitmap() : pen( NULL ) {}    ~myBitmap()    {	DeleteObject( pen );	DeleteDC( hdc );	DeleteObject( bmp );    }     bool create( int w, int h )    {	BITMAPINFO	bi;	ZeroMemory( &bi, sizeof( bi ) ); 	bi.bmiHeader.biSize	   = sizeof( bi.bmiHeader );	bi.bmiHeader.biBitCount	   = sizeof( DWORD ) * 8;	bi.bmiHeader.biCompression = BI_RGB;	bi.bmiHeader.biPlanes	   = 1;	bi.bmiHeader.biWidth	   =  w;	bi.bmiHeader.biHeight	   = -h; 	HDC dc = GetDC( GetConsoleWindow() );	bmp = CreateDIBSection( dc, &bi, DIB_RGB_COLORS, &pBits, NULL, 0 );	if( !bmp ) return false; 	hdc = CreateCompatibleDC( dc );	SelectObject( hdc, bmp );	ReleaseDC( GetConsoleWindow(), dc );  	width = w; height = h; 	return true;    }     void clear()    {	ZeroMemory( pBits, width * height * sizeof( DWORD ) );    }     void setPenColor( DWORD clr )    {	if( pen ) DeleteObject( pen );	pen = CreatePen( PS_SOLID, 1, clr );	SelectObject( hdc, pen );    }     void saveBitmap( string path )    {	BITMAPFILEHEADER fileheader;	BITMAPINFO	 infoheader;	BITMAP		 bitmap;	DWORD		 wb; 	GetObject( bmp, sizeof( bitmap ), &bitmap ); 	DWORD* dwpBits = new DWORD[bitmap.bmWidth * bitmap.bmHeight];	ZeroMemory( dwpBits, bitmap.bmWidth * bitmap.bmHeight * sizeof( DWORD ) );	ZeroMemory( &infoheader, sizeof( BITMAPINFO ) );	ZeroMemory( &fileheader, sizeof( BITMAPFILEHEADER ) ); 	infoheader.bmiHeader.biBitCount = sizeof( DWORD ) * 8;	infoheader.bmiHeader.biCompression = BI_RGB;	infoheader.bmiHeader.biPlanes = 1;	infoheader.bmiHeader.biSize = sizeof( infoheader.bmiHeader );	infoheader.bmiHeader.biHeight = bitmap.bmHeight;	infoheader.bmiHeader.biWidth = bitmap.bmWidth;	infoheader.bmiHeader.biSizeImage = bitmap.bmWidth * bitmap.bmHeight * sizeof( DWORD ); 	fileheader.bfType    = 0x4D42;	fileheader.bfOffBits = sizeof( infoheader.bmiHeader ) + sizeof( BITMAPFILEHEADER );	fileheader.bfSize    = fileheader.bfOffBits + infoheader.bmiHeader.biSizeImage; 	GetDIBits( hdc, bmp, 0, height, ( LPVOID )dwpBits, &infoheader, DIB_RGB_COLORS ); 	HANDLE file = CreateFile( path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );	WriteFile( file, &fileheader, sizeof( BITMAPFILEHEADER ), &wb, NULL );	WriteFile( file, &infoheader.bmiHeader, sizeof( infoheader.bmiHeader ), &wb, NULL );	WriteFile( file, dwpBits, bitmap.bmWidth * bitmap.bmHeight * 4, &wb, NULL );	CloseHandle( file ); 	delete [] dwpBits;    }     HDC getDC() const     { return hdc; }    int getWidth() const  { return width; }    int getHeight() const { return height; } private:    HBITMAP bmp;    HDC	    hdc;    HPEN    pen;    void   *pBits;    int	    width, height;};//--------------------------------------------------------------------------------------------------class Ant{public:    Ant()     {	_bmp.create( BMP_SIZE, BMP_SIZE );	ZeroMemory( _grid, sizeof( _grid ) );	RED_BRUSH = CreateSolidBrush( 255 );	_antState = RUNNING;    }     ~Ant()    {	DeleteObject( RED_BRUSH );    }     void setPosition( int x, int y )    {	_sx = x; _sy = y;	_facing = WES;    }     void mainLoop()    {	switch( _antState )	{	    case RUNNING:	        simulate();		// fall thru	    case RESTING:		display();	}    }     void setHWND( HWND hwnd ) { _hwnd = hwnd; } private:    void simulate()    {	switch( _grid[_sx][_sy] )	{	    case BLACK:		_grid[_sx][_sy] = WHITE;		if( --_facing < NOR ) _facing = WES;	    break;	    case WHITE:		_grid[_sx][_sy] = BLACK;		if( ++_facing > WES ) _facing = NOR;	}	switch( _facing )	{	    case NOR: 		if( --_sy < 0 )		{		    if( INFINIT_RUN ) _sy = GRID_SIZE - 1;		    else _antState = RESTING;		}	    break;	    case EAS:		if( ++_sx >= GRID_SIZE )		{		    if( INFINIT_RUN ) _sx = 0;		    else _antState = RESTING;		}	    break;	    case SOU:		if( ++_sy >= GRID_SIZE )		{		    if( INFINIT_RUN ) _sy = 0;		    else _antState = RESTING;		}	    break;	    case WES:	        if( --_sx < 0 )		{		    if( INFINIT_RUN ) _sx = GRID_SIZE - 1;		    else _antState = RESTING;		}	}    }     void display()    {        _bmp.clear();         HBRUSH br; RECT rc;        int xx, yy; HDC dc = _bmp.getDC();         for( int y = 0; y < GRID_SIZE; y++ )	    for( int x = 0; x < GRID_SIZE; x++ )	    {	        switch( _grid[x][y] )	        {		    case BLACK: br = static_cast<HBRUSH>( GetStockObject( BLACK_BRUSH ) ); break;		    case WHITE: br = static_cast<HBRUSH>( GetStockObject( WHITE_BRUSH ) );	        }	        if( x == _sx && y == _sy ) br = RED_BRUSH; 	        xx = x * CELL_SIZE; yy = y * CELL_SIZE;	        SetRect( &rc, xx, yy, xx + CELL_SIZE, yy + CELL_SIZE );	        FillRect( dc, &rc, br );	    }         HDC wdc = GetDC( _hwnd );        BitBlt( wdc, 0, 0, BMP_SIZE, BMP_SIZE, dc, 0, 0, SRCCOPY );        ReleaseDC( _hwnd, wdc );    }     myBitmap _bmp;    HWND     _hwnd;    HBRUSH   RED_BRUSH;    BYTE     _grid[GRID_SIZE][GRID_SIZE];    int      _sx, _sy, _facing;    state    _antState;};//--------------------------------------------------------------------------------------------------class wnd{public:    int wnd::Run( HINSTANCE hInst )    {	_hInst = hInst;	_hwnd = InitAll(); 	_ant.setHWND( _hwnd );	_ant.setPosition( GRID_SIZE / 2, GRID_SIZE / 2 ); 	ShowWindow( _hwnd, SW_SHOW );	UpdateWindow( _hwnd ); 	MSG msg;	ZeroMemory( &msg, sizeof( msg ) );	while( msg.message != WM_QUIT )	{	    if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) != 0 )	    {		TranslateMessage( &msg );		DispatchMessage( &msg );	    }	    else	    {		_ant.mainLoop();	    }	}	return UnregisterClass( "_LANGTONS_ANT_", _hInst );    }private:    static int WINAPI wnd::WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )    {	switch( msg )	{	    case WM_DESTROY: PostQuitMessage( 0 ); break;	    default:		return DefWindowProc( hWnd, msg, wParam, lParam );	}	return 0;    }     HWND InitAll()    {	WNDCLASSEX wcex;	ZeroMemory( &wcex, sizeof( wcex ) );	wcex.cbSize	       = sizeof( WNDCLASSEX );	wcex.style	       = CS_HREDRAW | CS_VREDRAW;	wcex.lpfnWndProc   = ( WNDPROC )WndProc;	wcex.hInstance     = _hInst;	wcex.hCursor       = LoadCursor( NULL, IDC_ARROW );	wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );	wcex.lpszClassName = "_LANGTONS_ANT_"; 	RegisterClassEx( &wcex ); 	return CreateWindow( "_LANGTONS_ANT_", ".: Langton's Ant -- PJorente :.", WS_SYSMENU, CW_USEDEFAULT, 0, BMP_SIZE, BMP_SIZE, NULL, NULL, _hInst, NULL );    }     HINSTANCE _hInst;    HWND      _hwnd;    Ant       _ant;};//--------------------------------------------------------------------------------------------------int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ){    wnd myWnd;    return myWnd.Run( hInstance );}//-------------------------------------------------------------------------------------------------- 

## Chapel

 config const gridHeight: int = 100;config const gridWidth: int = 100; class PBMWriter {  var imgDomain: domain(2);  var imgData: [imgDomain] int;   proc PBMWriter( height: int, width: int ){    imgDomain = { 1..#height, 1..#width };  }   proc this( i : int, j : int) ref : int{    return this.imgData[ i, j ];  }   proc writeImage( fileName: string ){    var file = open(fileName, iomode.cw);    var writingChannel = file.writer();    writingChannel.write("P1\n", imgDomain.dim(1).size, " " ,imgDomain.dim(2).size,"\n");     for px in imgData {      writingChannel.write( px, " " );    }     writingChannel.write( "\n" );    writingChannel.flush();    writingChannel.close();  } } enum Color { white, black }; inline proc nextDirection( position: 2*int, turnLeft: bool ): 2*int {  return ( (if turnLeft then 1 else -1 ) * position[2], (if turnLeft then -1 else 1 ) * position[1] );} proc <( left: 2*int, right: 2*int ){  return left[1] < right[1] && left[2] < right[2];} proc <=( left: 2*int, right: 2*int ){  return left[1] <= right[1] && left[2] <= right[2];} proc main{  const gridDomain: domain(2) = {1..#gridHeight, 1..#gridWidth};  var grid: [gridDomain] Color;   var antPos = ( gridHeight / 2, gridWidth / 2 );  var antDir = (1,0); // start up;   while (0,0) < antPos && antPos <= (gridHeight, gridWidth ) {    var currColor = grid[ antPos ];    grid[antPos] = if currColor == Color.white then Color.black else Color.white ;     antDir = nextDirection( antDir, currColor == Color.black );    antPos = antPos + antDir;  }   var image = new PBMWriter( height = gridHeight, width = gridWidth );   for (i, j) in gridDomain {    image[i,j] = if grid[gridHeight-j+1,gridHeight-i+1] == Color.black then 0 else 1;  }   image.writeImage( "output.png" );} 

## Clojure

In keeping with the spirit of Clojure, this program eschews mutable state entirely. Instead, all computation occurs within a single recursive loop whose "variables" are "adjusted" at each iteration, a natural fit for this particular execution model.

(let [bounds (set (range 100))      xs [1 0 -1 0] ys [0 -1 0 1]]  (loop [dir 0 x 50 y 50         grid {[x y] false}]    (if (and (bounds x) (bounds y))      (let [cur (not (grid [x y]))            dir (mod (+ dir (if cur -1 1)) 4)]        (recur dir (+ x (xs dir)) (+ y (ys dir))               (merge grid {[x y] cur})))      (doseq [col (range 100)]        (println          (apply str                 (map #(if (grid [% col]) \# \.)                      (range 100))))))))

## COBOL

The following program displays the simulation in the console, and a very small font size (~4pt) will be needed to fit it into the window.

Works with: OpenCOBOL
       IDENTIFICATION DIVISION.       PROGRAM-ID. langtons-ant.        DATA DIVISION.       WORKING-STORAGE SECTION.       78  Grid-Size               VALUE 100.       01  grid-area.           03  grid-x              OCCURS Grid-Size TIMES.               05  grid-y          OCCURS Grid-Size TIMES.                   07  cell-colour PIC X VALUE "W".                       88  black   VALUE "B".                       88  white   VALUE "W".        01  ant-x                   PIC 999.       01  ant-y                   PIC 999.        01  ant-direction           PIC 9.           88  upward              VALUE 0.           88  rightward           VALUE 1.           88  downward            VALUE 2.           88  leftward            VALUE 3.        78  Pause-Time-Ns           VALUE 10000000.        01  display-y               PIC 999.        78  Black-Background        VALUE 0.       78  White-Background        VALUE 7.        01  i                       PIC 999.       01  j                       PIC 999.        01  pause                   PIC X.        PROCEDURE DIVISION.       main-line.           DIVIDE Grid-Size BY 2 GIVING ant-x, ant-y            PERFORM display-initial-grid           PERFORM UNTIL (ant-x = Grid-Size OR 0)                   OR (ant-y = Grid-Size OR 0)               PERFORM step-simulation               CALL "CBL_OC_NANOSLEEP" USING Pause-Time-Ns           END-PERFORM            DISPLAY "Press enter to quit." AT LINE 1 COLUMN 1           ACCEPT pause            GOBACK           .       step-simulation.           IF black (ant-x, ant-y)               SET white (ant-x, ant-y) TO TRUE               PERFORM display-ant-cell               COMPUTE ant-direction =                   FUNCTION MOD(ant-direction + 1, 4)           ELSE               SET black (ant-x, ant-y) TO TRUE               PERFORM display-ant-cell               COMPUTE ant-direction =                   FUNCTION MOD(ant-direction - 1, 4)           END-IF            EVALUATE TRUE               WHEN upward                   ADD 1 TO ant-y               WHEN rightward                   ADD 1 TO ant-x               WHEN downward                   SUBTRACT 1 FROM ant-y               WHEN leftward                   SUBTRACT 1 FROM ant-x           END-EVALUATE           .       display-ant-cell.               SUBTRACT ant-y FROM Grid-Size GIVING display-y               IF black (ant-x, ant-y)                   DISPLAY SPACE AT LINE display-y COLUMN ant-x                       WITH BACKGROUND-COLOR Black-Background               ELSE                   DISPLAY SPACE AT LINE display-y COLUMN ant-x                      WITH BACKGROUND-COLOR White-Background               END-IF               .       display-initial-grid.           PERFORM VARYING i FROM 1 BY 1 UNTIL i > Grid-Size                   AFTER j FROM 1 BY 1 UNTIL j > Grid-Size               DISPLAY SPACE AT LINE i COLUMN j                   WITH BACKGROUND-COLOR White-Background           END-PERFORM           .

## CoffeeScript

 class Ant  constructor: (@world) ->    @location = [0, 0]    @direction = 'E'   move: =>    [x, y] = @location    if @world.is_set x, y      @world.unset x, y      @direction = Directions.left @direction    else      @world.set x, y      @direction = Directions.right @direction    @location = Directions.forward(x, y, @direction) # Model a theoretically infinite 2D world with a hash, allowing squares# to be black or white (independent of any ants.)class BlackWhiteWorld  constructor: ->    @bits = {}   set: (x, y) ->    @bits["#{x},#{y}"] = true   unset: (x, y) ->    delete @bits["#{x},#{y}"]   is_set: (x, y) ->    @bits["#{x},#{y}"]   draw: ->    # Most of this code just involves finding the extent of the world.    # Always include the origin, even if it's not set.    @min_x = @max_x = @min_y = @max_y = 0    for key of @bits      [xx, yy] = (coord for coord in key.split ',')      x = parseInt xx      y = parseInt yy      @min_x = x if x < @min_x      @max_x = x if x > @max_x      @min_y = y if y < @min_y      @max_y = y if y > @max_y    console.log "top left: #{@min_x}, #{@max_y}, bottom right: #{@max_x}, #{@min_y}"    for y in [@max_y..@min_y] by -1      s = ''      for x in [@min_x..@max_x]        if @bits["#{x},#{y}"]          s += '#'        else          s += '_'      console.log s # Simple code for directions, independent of ants.Directions =  left: (dir) ->    return 'W' if dir == 'N'    return 'S' if dir == 'W'    return 'E' if dir == 'S'    'N'   right: (dir) ->    return 'E' if dir == 'N'    return 'S' if dir == 'E'    return 'W' if dir == 'S'    'N'   forward: (x, y, dir) ->    return [x, y+1] if dir == 'N'    return [x, y-1] if dir == 'S'    return [x+1, y] if dir == 'E'    return [x-1, y] if dir == 'W'  world = new BlackWhiteWorld()ant = new Ant(world)for i in [1..11500]  ant.move()console.log "Ant is at #{ant.location}, direction #{ant.direction}"world.draw() 

output

 > coffee langstons_ant.coffee Ant is at -24,46, direction Wtop left: -25, 47, bottom right: 22, -29_##__##_________________________________________##_#####________________________________________#____##_#___________________________________________#_#_##_______________________________________####_###_#______________________________________#####_#__##______________________________________#___##_##_#______________________________________###___#__##______________________________________#___##_##_#______________________________________###___#__##______________________________________#___##_##_#______________________________________###___#__##______________________________________#___##_##_#______________________________________###___#__##______________________________________#___##_##_#______________________________________###___#__##______________________________________#___##_##_#______________________________________###___#__##______________________________________#___##_##_#______________________________________###___#__##______________________________________#___##_##_#______________________________________###___#__##______________________________________#___##_##_#______________________________________###___#__##______________________________________#___##_##_#______________________________________###___#__##______________________________________#___##_##_#______________________________________###___#__##______________________________________#___##_##_#__##__________________________________###___#__##__##__________________________________#___##_##__##___#_________________________####___###___#___#__###________________________#____#___#___##_####___#_______________________###____#___#_#______#_##_#______________________###____#_##_____#_##__#_##_______________________#____#___##_#_#_____##__________________________#_#______#_#####__#___#________________________#___#####__________##_######____________________###__##__#_##_#_#_#___##_#_##_________________##__#_#######_#___#__###____##_#_______________#__#__######_##___#__#_##___#___#______________#____#_#_##_#__######_#######___#_______________#_####_##_#_####____##__##_#_##_#________________#____####___#__#_######_##____###__________________#___#_##_#_###_#__##__##___###_____________________#######____#__##_##_#_____#_____________####__##_##__####_##_##_##__#_____#____________#____#_#___###_##_###____#_####____#___________###_______###_#_#_#####____#_#______#___________#_#___###_####_##_#___##_###_##_____#_________________##_##__####____####_#_#_#_____#____________#____#__##___###__###_____###______#____________##___##_###_####__#______###___##__#____________##_#_####_____#___#__#_##_###_##___#___________####_##___##_####__#_#__#__#__###___#___________#_##_###__#_#_##_#_#_____#_#_____#_#________________#_#__#____##_##__#_#__###_##____________________##_#____#__#####_#____#____#__#_#______________#_##_#__#____##_##_#__###______###____________#_#___#__#__#__#__###___##__##____#____________###_#_#####_######_###_#######_#_##_____________#_#_#____#####___##__#####_#####__________________#__##___#______#__#_##__###_###______________####___#####_#########___#_#_______________##____#__#_____###_#_#___#_###__###____________#__#__####_##___###_##___###_##_____##_________###____#_##_#_#####___#____#__#__##_###_________#_#####_#_#___##__##_____#____#___#__#______________######_####__##_#___#__##__#_#_##_____________##______#_###_##__####___#___###_________________#__#_#####__#___#_##___#__#__#__________________##_###_#######_____#_____#_##__________________#_#__##_##______#___##____#____________________#__#_####________###__##__#_____________________#_##_###____________##__##_______________________##_______________________________________________##________________________________________ 

## Common Lisp

(defmacro toggle (gv) (setf  ,gv (not ,gv))) (defun langtons-ant (width height start-x start-y start-dir)   (let ( (grid (make-array (list width height)))         (x start-x)         (y start-y)         (dir start-dir) )    (loop while (and (< -1 x width) (< -1 y height)) do      (if (toggle (aref grid x y))        (setq dir (mod (1+ dir) 4))        (setq dir (mod (1- dir) 4)))      (case dir        (0 (decf y))        (1 (incf x))        (2 (incf y))        (3 (decf x)))    )    grid  )) (defun show-grid (grid)   (destructuring-bind (width height) (array-dimensions grid)     (dotimes (y height)      (dotimes (x width)        (princ (if (aref grid x y) "#" ".")))      (princ #\Newline))  )) (setf *random-state* (make-random-state t))(show-grid (langtons-ant 100 100 (+ 45 (random 10)) (+ 45 (random 10)) (random 4)))

## D

### Textual Version

void main() @safe {    import std.stdio, std.traits;     enum width = 75, height = 52;    enum maxSteps = 12_000;    enum Direction { up, right, down, left }    enum Color : char { white = '.', black = '#' }    uint x = width / 2, y = height / 2;    Color[width][height] M;    auto dir = Direction.up;     with (Color)        for (int i = 0; i < maxSteps && x < width && y < height; i++) {            immutable turn = M[y][x] == black;            dir = [EnumMembers!Direction][(dir + (turn ? 1 : -1)) & 3];            M[y][x] = (M[y][x] == black) ? white : black;            final switch(dir) with (Direction) {                case up:    y--; break;                case right: x--; break;                case down:  y++; break;                case left:  x++; break;            }        }     writefln("%(%-(%c%)\n%)", M);}
Output:
...........................................................................
...........................................................................
...........................................................................
...........................................................................
.............................##..############..##..........................
............................#..####..........#..##.........................
...........................###...##............##.#........................
...........................#.#..#.........#..#....#........................
.......................##..##.#.#.........###.......#......................
....................###.#..#...#.....#.....##.##..###......................
.....................#.#..###..##.####.##...#.#..#.##..##..................
.....................#.###.##..#.##..###.#.#.....###...###.................
...................#.....#...#####.#.#..####..#...###.#.#.#................
..................###.##...#.####..##.##.######.#.###.#...#................
..................#.###.#.##.#.#.##.##.##.#...#####.###.##.................
......................#.#...#.##.###...#...#.#..####....#.##...............
...................#..#.........##.##...#..##.....##.#.....##..............
..................###...#.#.##.###..#..##.....#...###.##..##.#.............
.................#..###..##...##.##...###..#....#..##.####...#.............
................###...#...#.#..#.#.####.##..#.##.###..#.....#..............
...............#..###..#.##....#..#.###..#......###.##.#..#..##............
..............###...#.....#.##.#.##..##..#####.####..####.##...#...........
.............#..###..#.#.#..#.###.#.#.##......##...#.#.#....#...#..........
............###...#..##.###..##.#...##.......####.####...#......#..........
...........#..###..#.#..#...##..###########.#..####..#....#....#...........
..........###...#..##......#.####..##..#########..#..##....#..##...........
.........#..###..#.#...##..#.##...##.##.###.###...#..#.##..####.#..........
........###...#..##...#..#.######.##.#.##.#.#....###.###...##...#..........
.......#..###..#.#...#.....#####.#.#####.....#.#..##.#....##...#...........
......###...#..##....#.....#.##.#####.##..#.#...#..#..##.#..#..#...........
.....#..###..#.#.....#....#...####.#..#####.##...##########...##...........
....###...#..##......#.##...##...#..#...####..#...##.####.##...............
...#..###..#.#........#####.#..##...##.#...#....#.#..#..#..#.#.............
..###...#..##..........##..##.#.#.#....##.##.#.#.##..#..##..##.............
.#..###..#.#.................#..#....#.########.#.#.##..####.#.............
###...#..##..................#..#...#.......##.##...#..#..##.#.............
...##..#.#....................#..#..#......#..##..##...##.####.............
##..#..##......................##...#.......##..##....#...#.###............
.#.#.#.#............................#.##..####....####.###.####............
####.##..............................##..####....##..#.##.#.#..#...........
#.##.#................................##....##....##.###.##.#####..........
.####................................................#.##.#..####..........
..##.....................................................##.##.##..........
.........................................................##................
.......................................................#.##..####.#........
......................................................#..#.###..###........
......................................................#.##.#..#..#.........
.......................................................##......##..........
........................................................##.................
...........................................................................
...........................................................................
...........................................................................

### Image Version

This similar version requires the module from the Grayscale Image Task to generate and save a PGM image.

import std.stdio, std.algorithm, std.traits, grayscale_image; void main() {    enum width = 100, height = 100;    enum nSteps = 12_000;    enum Direction { up, right, down, left }    auto M = new Image!Gray(width, height);    M.clear(Gray.white);    uint x = width / 2, y = height / 2;    auto dir = Direction.up;     for (int i = 0; i < nSteps && x < width && y < height; i++) {        immutable turn = M[x, y] == Gray.black;        dir = [EnumMembers!Direction][(dir + (turn ? 1 : -1)) & 3];        M[x, y] = (M[x, y] == Gray.black) ? Gray.white : Gray.black;        final switch(dir) with (Direction) {            case up:    y--; break;            case right: x--; break;            case down:  y++; break;            case left:  x++; break;        }    }     M.savePGM("langton_ant.pgm");}

## Dyalect

let xInc = [0, 1, -1, 0]let yInc = [-1, 0, 0, 1]let north = 0let east = 1let west = 2let south = 3 let leftTurns  = [ west, north, south, east ]let rightTurns = [ east, south, north, west ] func move(ant) {    ant::position::x += xInc[ant::direction]    ant::position::y += yInc[ant::direction]} func Array.step(ant) {    var ptCur = (var x: ant::position::x + ant::origin::x, var y: ant::position::y + ant::origin::y)    var leftTurn = this[ptCur::x][ptCur::y]    ant::direction =        if leftTurn  {            leftTurns[ant::direction]         } else {            rightTurns[ant::direction]        }    this[ptCur::x][ptCur::y] = !this[ptCur::x][ptCur::y]    move(ant)    ptCur = (x: ant::position::x + ant::origin::x, y: ant::position::y + ant::origin::y)    ant::outOfBounds =         ptCur::x < 0 ||        ptCur::x >= ant::width ||        ptCur::y < 0 ||        ptCur::y >= ant::height    ant::position} func newAnt(width, height) {    (        var position: (var x: 0, var y: 0),        var origin: (x: width / 2, y: height / 2),        var outOfBounds: false,        var isBlack: [],        var direction: east,        var width: width,        var height: height    )} func run() {    let w = 100    let h = 100    let blacks = Array.empty(w, () => Array.empty(h, false))    let ant = newAnt(w, h)     while !ant::outOfBounds {        blacks.step(ant)    }     var iRow = 0;     while iRow < w {        var iCol = 0;        var ln = ""        while iCol < h {            ln += if blacks[iCol][iRow] {                "#"            } else {                " "            }            iCol += 1        }        print(ln)        iRow += 1    }} run()
Output:

Empty lines are omitted.

                          # #
## # #
# ### ##
#### ### #
##### #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #  ##
###   #  ##  ##
#   ## ##  ##   #
####   ###   #   #  ###
#    #   #   ## ####   #
###    #   # #      # ## #
###    # ##     # ##  # ##
#    #   ## # #     ##
# #      # #####  #   #
#   #####          ## ######
###  ##  # ## # # #   ## # ##
##  # ####### #   #  ###    ## #
#  #  ###### ##   #  # ##   #   #
#    # # ## #  ###### #######   #
# #### ## # ####    ##  ## # ## #
#    ####   #  # ###### ##    ###
#   # ## # ### #  ##  ##   ###
#######    #  ## ## #     #
####  ## ##  #### ## ## ##  #     #
#    # #   ### ## ###    # ####    #
###       ### # # #####    # #      #
# #   ### #### ## #   ## ### ##     #
## ##  ####    #### # # #     #
#    #  ##   ###  ###     ###      #
##   ## ### ####  #      ###   ##  #
## # ####     #   #  # ## ### ##   #
#### ##   ## ####  # #  #  #  ###   #
# ## ###  # # ## # #     # #     # #
# #  #    ## ##  # #  ### ##
## #    #  ##### #    #    #  # #
# ## #  #    ## ## #  ###      ###
# #   #  #  #  #  ###   ##  ##    #
### # ##### ###### ### ####### # ##
# # #    #####   ##  ##### #####
#  ##   #      #  # ##  ### ###
####   ##### #########   # #
##    #  #     ### # #   # ###  ###
#  #  #### ##   ### ##   ### ##     ##
###    # ## # #####   #    #  #  ## ###
# ##### # #   ##  ##     #    #   #  #
###### ####  ## #   #  ##  # # ##
##      # ### ##  ####   #   ###
#  # #####  #   # ##   #  #  #
## ### #######     #     # ##
# #  ## ##      #   ##    #
#  # ####        ###  ##  #
# ## ###            ##  ##
##
##

## EasyLang

len f[] 100 * 100func show . .  for y range 100    for x range 100      if f[y * 100 + x] = 1        move_pen x y        draw_rect 1 1      .    .  ..func run x y dir . .  dx[] = [ 0 1 0 -1 ]  dy[] = [ -1 0 1 0 ]  while x >= 0 and x < 100 and y >= 0 and y < 100    v = f[y * 100 + x]    f[y * 100 + x] = 1 - v    dir = (dir + 1 + 2 * v) mod 4    x += dx[dir]    y += dy[dir]  ..call run 70 40 0call show

## EchoLisp

We implement multi-colored ants, as depicted in the article. An ant is described using L(eft)R(ight) patterns. LR is the basic black and white ant, other are RRLLLRRL or RRLLLRLLLRRR. See results for s black-and-white or colored ants.

 (lib 'plot)(lib 'types) (define (move iter x dir constant: plane turns cmax  width  xmax (cidx 0))	(while (> iter 0)	;; get color index of current square	(set! cidx (vector-ref plane x))  	;; turn		(if (vector-ref turns cidx)  		(set! dir (if (= dir 3) 0 (1+ dir))) ;; right is #t		(set! dir (if (= dir 0) 3 (1- dir))))  	;; rotate colors	(set! cidx (if (= cidx cmax) 0 (1+ cidx)))	(vector-set! plane x cidx) 	;; move	;; x = v + h*width for a pixel at (h,v)	(set! x 		(cond			((= dir 0) (1+ x))			((= dir 1) (+ x width))			((= dir 2) (1- x))			((= dir 3) (- x width))))  	(when (or (< x 0) (>= x xmax)) (set! iter -666)) ;; out of bounds	(set! iter (1- iter)))	iter) ;; a color table of 16 colors(define colors    (list 0 (rgb 1 1 1) (rgb 1 0 0) (rgb 0 1 0) (rgb 0 0 1) (rgb 1 1 0) (rgb 1 0 1) (rgb 0 1 1)))(define colors (list->vector (append colors colors))) ;; transform color index into rgb color, using colors table.(define (colorize plane xmax)	(for ((x xmax)) 		(vector-set! plane x (vector-ref colors (vector-ref plane x))))	(vector->pixels plane)	xmax ) ;; ant's patterns(define turns #(#t #t #f #f #f #t #f #f #f #t #t #t))   ;; RRLLLRLLLRRR;;(define turns #(#t #t #f #f #f #t #t #f)) ; RRLLLRRL;;(define turns #(#t #f)) ; RL : basic ant (define  (ant (iter 100000))	(plot-clear)	(define width (first (pixels-dim))) ;; plane dimensions	(define height (rest (pixels-dim)))	(define plane (pixels->uint32-vector))	(define x (+ (quotient width 2) (* width (quotient height 2)))) ;; middle of plane	(define xmax (* width height)) 	(move iter  x 0 plane turns (1- (vector-length turns)) width xmax)	(colorize plane xmax)) (ant) ;; run

## Ela

open list core generic type Field = Field atype Color = White | Blacktype Direction = Lft | Fwd | Rgt | Bwdfield s = Field [[White \\ _ <- [1..s]] \\ _ <- [1..s]] isBlack Black = trueisBlack _ = false newfield xc yc (Field xs) = Field (newfield' 0 xs)  where newfield' _ [] = []        newfield' n (x::xs)           | n == yc = row 0 x :: xs          | else   = x :: newfield' (n+1) xs          where row _ [] = []                row n (x::xs)                   | n == xc = toggle x :: xs                  | else    = x :: row (n+1) xs                  where toggle White = Black                        toggle Black = White showPath (Field xs) = toString <| show' "" xs  where show' sb [] = sb +> ""        show' sb (x::xs) = show' (showRow sb x +> "\r\n") xs          where showRow sb [] = sb +> ""                showRow sb (x::xs) = showRow (sb +> s) xs                  where s | isBlack x = "#"                          | else = "_" move s xc yc = move' (Fwd,xc,yc) (field s)  where move' (pos,xc,yc)@coor fld           | xc >= s || yc >= s || xc < 0 || yc < 0 = fld          | else = fld |> newfield xc yc |> move' (matrix (dir fld) coor)          where dir (Field xs)                   | isBlack (xs:yc):xc = Lft                  | else = Rgt                matrix Lft (pos,x,y) = go (left pos,x,y)                matrix Rgt (pos,x,y) = go (right pos,x,y)                go (Lft,x,y) = (Lft,x - 1,y)                go (Rgt,x,y) = (Rgt,x+1,y)                go (Fwd,x,y) = (Fwd,x,y - 1)                go (Bwd,x,y) = (Bwd,x,y+1)                right Lft = Fwd                right Fwd = Rgt                right Rgt = Bwd                right Bwd = Lft                left Lft = Bwd                left Bwd = Rgt                left Rgt = Fwd                left Fwd = Lft

This implementation is pure (doesn't produce side effects).

Testing:

showPath <| move 100 50 50

Output (empty lines are skipped to save space):

__________________________________________##__############__##______________________________________
_________________________________________#__####__________#__##_____________________________________
________________________________________###___##____________##_#____________________________________
________________________________________#_#__#_________#__#____#____________________________________
____________________________________##__##_#_#_________###_______#__________________________________
_________________________________###_#__#___#_____#_____##_##__###__________________________________
__________________________________#_#__###__##_####_##___#_#__#_##__##______________________________
__________________________________#_###_##__#_##__###_#_#_____###___###_____________________________
________________________________#_____#___#####_#_#__####__#___###_#_#_#____________________________
_______________________________###_##___#_####__##_##_######_#_###_#___#____________________________
_______________________________#_###_#_##_#_#_##_##_##_#___#####_###_##_____________________________
___________________________________#_#___#_##_###___#___#_#__####____#_##___________________________
________________________________#__#_________##_##___#__##_____##_#_____##__________________________
_______________________________###___#_#_##_###__#__##_____#___###_##__##_#_________________________
______________________________#__###__##___##_##___###__#____#__##_####___#_________________________
_____________________________###___#___#_#__#_#_####_##__#_##_###__#_____#__________________________
____________________________#__###__#_##____#__#_###__#______###_##_#__#__##________________________
___________________________###___#_____#_##_#_##__##__#####_####__####_##___#_______________________
__________________________#__###__#_#_#__#_###_#_#_##______##___#_#_#____#___#______________________
_________________________###___#__##_###__##_#___##_______####_####___#______#______________________
________________________#__###__#_#__#___##__###########_#__####__#____#____#_______________________
_______________________###___#__##______#_####__##__#########__#__##____#__##_______________________
______________________#__###__#_#___##__#_##___##_##_###_###___#__#_##__####_#______________________
_____________________###___#__##___#__#_######_##_#_##_#_#____###_###___##___#______________________
____________________#__###__#_#___#_____#####_#_#####_____#_#__##_#____##___#_______________________
___________________###___#__##____#_____#_##_#####_##__#_#___#__#__##_#__#__#_______________________
__________________#__###__#_#_____#____#___####_#__#####_##___##########___##_______________________
_________________###___#__##______#_##___##___#__#___####__#___##_####_##___________________________
________________#__###__#_#________#####_#__##___##_#___#____#_#__#__#__#_#_________________________
_______________###___#__##__________##__##_#_#_#____##_##_#_#_##__#__##__##_________________________
______________#__###__#_#_________________#__#____#_########_#_#_##__####_#_________________________
_____________###___#__##__________________#__#___#_______##_##___#__#__##_#_________________________
____________#__###__#_#____________________#__#__#______#__##__##___##_####_________________________
___________###___#__##______________________##___#_______##__##____#___#_###________________________
__________#__###__#_#____________________________#_##__####____####_###_####________________________
_________###___#__##______________________________##__####____##__#_##_#_#__#_______________________
________#__###__#_#________________________________##____##____##_###_##_#####______________________
_______###___#__##________________________________________________#_##_#__####______________________
______#__###__#_#_____________________________________________________##_##_##______________________
_____###___#__##______________________________________________________##____________________________
____#__###__#_#_____________________________________________________#_##__####_#____________________
___###___#__##_____________________________________________________#__#_###__###____________________
__#__###__#_#______________________________________________________#_##_#__#__#_____________________
_###___#__##________________________________________________________##______##______________________
#__###__#_#__________________________________________________________##_____________________________
_###_#__##__________________________________________________________________________________________
#_#_#_#_#___________________________________________________________________________________________
_####_##____________________________________________________________________________________________
_#_##_#_____________________________________________________________________________________________
__####______________________________________________________________________________________________
___##_______________________________________________________________________________________________


## Elixir

Works with: Elixir version 1.1+
Translation of: Ruby
defmodule Langtons do  def ant(sizex, sizey) do    {px, py} = {div(sizex,2), div(sizey,2)}     # start position    move(MapSet.new, sizex, sizey, px, py, {1,0}, 0)  end   defp move(plane, sx, sy, px, py, _, step) when px<0 or sx<px or py<0 or sy<py, do:    print(plane, sx, sy, px, py, step)  defp move(plane, sx, sy, px, py, dir, step) do    {plane2, {dx,dy}} = if {px,py} in plane,                          do:   {MapSet.delete(plane, {px,py}), turn_right(dir)},                          else: {MapSet.put(plane, {px,py}), turn_left(dir)}    move(plane2, sx, sy, px+dx, py+dy, {dx,dy}, step+1)  end   defp turn_right({dx, dy}), do: {dy, -dx}  defp turn_left({dx, dy}), do: {-dy, dx}   defp print(plane, sx, sy, px, py, step) do    IO.puts "out of bounds after #{step} moves: (#{px}, #{py})"    Enum.each(0..sy, fn j ->      IO.puts Enum.map(0..sx, fn i -> if {i,j} in plane, do: "#", else: "." end)    end)  endend Langtons.ant(100, 100)
Output:
out of bounds after 11669 moves: (26, -1)
..........................#.#........................................................................
........................##.#.#.......................................................................
.......................#.###.##......................................................................
......................####.###.#.....................................................................
......................#####.#..##....................................................................
.......................#...##.##.#...................................................................
........................###...#..##..................................................................
.........................#...##.##.#.................................................................
..........................###...#..##................................................................
...........................#...##.##.#...............................................................
............................###...#..##..............................................................
.............................#...##.##.#.............................................................
..............................###...#..##............................................................
...............................#...##.##.#...........................................................
................................###...#..##..........................................................
.................................#...##.##.#.........................................................
..................................###...#..##........................................................
...................................#...##.##.#.......................................................
....................................###...#..##......................................................
.....................................#...##.##.#.....................................................
......................................###...#..##....................................................
.......................................#...##.##.#...................................................
........................................###...#..##..................................................
.........................................#...##.##.#.................................................
..........................................###...#..##................................................
...........................................#...##.##.#...............................................
............................................###...#..##..............................................
.............................................#...##.##.#.............................................
..............................................###...#..##............................................
...............................................#...##.##.#...........................................
................................................###...#..##..........................................
.................................................#...##.##.#..##.....................................
..................................................###...#..##..##....................................
...................................................#...##.##..##...#.................................
.............................................####...###...#...#..###.................................
............................................#....#...#...##.####...#.................................
...........................................###....#...#.#......#.##.#................................
...........................................###....#.##.....#.##..#.##................................
............................................#....#...##.#.#.....##...................................
............................................#.#......#.#####..#...#..................................
...........................................#...#####..........##.######..............................
...........................................###..##..#.##.#.#.#...##.#.##.............................
.........................................##..#.#######.#...#..###....##.#............................
........................................#..#..######.##...#..#.##...#...#............................
.......................................#....#.#.##.#..######.#######...#.............................
.......................................#.####.##.#.####....##..##.#.##.#.............................
........................................#....####...#..#.######.##....###............................
...........................................#...#.##.#.###.#..##..##...###............................
..............................................#######....#..##.##.#.....#............................
......................................####..##.##..####.##.##.##..#.....#............................
.....................................#....#.#...###.##.###....#.####....#............................
....................................###.......###.#.#.#####....#.#......#............................
....................................#.#...###.####.##.#...##.###.##.....#............................
..........................................##.##..####....####.#.#.#.....#............................
.....................................#....#..##...###..###.....###......#............................
.....................................##...##.###.####..#......###...##..#............................
.....................................##.#.####.....#...#..#.##.###.##...#............................
....................................####.##...##.####..#.#..#..#..###...#............................
....................................#.##.###..#.#.##.#.#.....#.#.....#.#.............................
........................................#.#..#....##.##..#.#..###.##.................................
........................................##.#....#..#####.#....#....#..#.#............................
.......................................#.##.#..#....##.##.#..###......###............................
.....................................#.#...#..#..#..#..###...##..##....#.............................
....................................###.#.#####.######.###.#######.#.##..............................
....................................#.#.#....#####...##..#####.#####.................................
......................................#..##...#......#..#.##..###.###................................
...................................####...#####.#########...#.#......................................
..............................##....#..#.....###.#.#...#.###..###....................................
.............................#..#..####.##...###.##...###.##.....##..................................
............................###....#.##.#.#####...#....#..#..##.###..................................
............................#.#####.#.#...##..##.....#....#...#..#...................................
................................######.####..##.#...#..##..#.#.##....................................
..............................##......#.###.##..####...#...###.......................................
...............................#..#.#####..#...#.##...#..#..#........................................
...............................##.###.#######.....#.....#.##.........................................
..............................#.#..##.##......#...##....#............................................
.............................#..#.####........###..##..#.............................................
.............................#.##.###............##..##..............................................
..............................##.....................................................................
...............................##....................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................
.....................................................................................................


## Elm

import Maybe as Mimport Matrix import Time exposing (Time, every, second)import List exposing (..)import String exposing (join)import Html exposing (div, h1, text)import Html.App exposing (program)import Svg import Svg.Attributes exposing (version, viewBox, cx, cy, r, x, y, x1, y1, x2, y2, fill,style, width, height, preserveAspectRatio) w = 700h = 700dt = 0.0001 type Direction = North | West | South | East type alias Model =  { rows : Int  , cols : Int  , boxes : Matrix.Matrix Bool  , location : Matrix.Location  , direction : Direction  } initModel : Int -> Int -> ModelinitModel cols rows =      { rows = rows     , cols = cols      , boxes = Matrix.matrix rows cols (\location -> False)     , location = (rows//2,cols//2)     , direction = North     } view model =  let    borderLineStyle = style "stroke:black;stroke-width:0.3"     x1Min = x1 <| toString 0    y1Min = y1 <| toString 0    x1Max = x1 <| toString model.cols    y1Max = y1 <| toString model.rows    x2Min = x2 <| toString 0    y2Min = y2 <| toString 0    x2Max = x2 <| toString model.cols    y2Max = y2 <| toString model.rows     borders = [ Svg.line [ x1Min, y1Min, x2Max, y2Min, borderLineStyle ] []              , Svg.line [ x1Max, y1Min, x2Max, y2Max, borderLineStyle ] []              , Svg.line [ x1Max, y1Max, x2Min, y2Max, borderLineStyle ] []              , Svg.line [ x1Min, y1Max, x2Min, y2Min, borderLineStyle ] []              ]     circleInBox (row,col) color =       Svg.circle [ r "0.25"      , fill (color)      , cx (toString (toFloat col + 0.5))      , cy (toString (toFloat row + 0.5))      ] []      showUnvisited location box =       if box then [circleInBox location "black" ]              else []     unvisited = model.boxes                   |> Matrix.mapWithLocation showUnvisited                   |> Matrix.flatten                   |> concat     maze = [ Svg.g [] <| borders ++ unvisited ]    in      div           []           [ h1 [] [text "Langton's Ant"]          , Svg.svg               [ version "1.1"              , width (toString w)              , height (toString h)              , viewBox (join " "                            [ 0          |> toString                           , 0          |> toString                           , model.cols |> toString                           , model.rows |> toString ])              ]               maze          ] updateModel : Model -> ModelupdateModel model =       let current = model.location          inBox =    snd current >= 0 && snd current < model.cols                  && fst current >= 0 && fst current < model.rows      in if not inBox then           model         else           let currentValue = Matrix.get current model.boxes |> M.withDefault False                dir = case (model.direction, currentValue) of                       (North, True) -> East                       (East, True) -> South                       (South, True) -> West                       (West, True) -> North                        (North, False) -> West                       (East, False) -> North                       (South, False) -> East                       (West, False) -> South                next = case dir of                        North -> (fst current+1, snd current)                        South -> (fst current-1, snd current)                        East -> (fst current, snd current+1)                        West -> (fst current, snd current-1)                boxes = Matrix.set current (not currentValue) model.boxes             in {model | boxes=boxes, location=next, direction=dir} type Msg = Tick Time  subscriptions model = every (dt * second) Tick main =  let     update msg model = (updateModel model, Cmd.none)    init = (initModel 100 100 , Cmd.none)  in program        { init = init       , view = view       , update = update       , subscriptions = subscriptions       }

## Erlang

Over-engineered sine I have summer vacation. Ex: Display function only display lines with black cells.

 -module( langtons_ant ). -export( [task/0] ). -record( neighbour, {north, south, east, west} ).-record( state, {colour=white, controller, max_x, max_y, neighbour, position} ). task() ->       Controller = erlang:self(),       Max_x = Max_y = 100,       Pid_positions = plane_create( Controller, Max_x, Max_y ),       Pids = [X || {X, _} <- Pid_positions],       [X ! {pid_positions, Pid_positions} || X <- Pids],       {Pid, _Position} = lists:keyfind( {Max_x div 2, Max_y div 2}, 2, Pid_positions ),       Pid ! {ant_start, north, Controller},       receive       {ant_arrives, _Pid} -> ok       end,       display( Controller, Max_x, Max_y, Pids ),       [X ! {stop, Controller} || X <- Pids].   display( Controller, Max_x, Max_y, Pids ) ->        Positions_colours = display_positions_colours( Pids, Controller ),        All_lines = [display_line( Max_x, Positions_colours, Y ) || Y <- lists:seq(Max_y, 1, -1)],        Lines_with_black = [X || X <- All_lines, lists:member(black, X)],        [io:fwrite( "~s~n", [[display_on_screen(X) || X <- Lines]] ) || Lines <- Lines_with_black]. display_line( Max_x, Positions_colours, Y ) -> [proplists:get_value({X,Y}, Positions_colours, white) || X <- lists:seq(1, Max_x)]. display_on_screen( white ) -> $_;display_on_screen( black ) ->$#. display_positions_colours( Pids, Controller ) ->        [X ! {position_colour, Controller} || X <- Pids],        [display_positions_colours_receive() || _X <- Pids]. display_positions_colours_receive( ) ->        receive        {position_colour, Position, Colour} -> {Position, Colour}        end. loop( State ) ->    receive    {pid_positions, Pid_positions} ->        {_My_position, Neighbour} = lists:foldl( fun loop_neighbour/2, {State#state.position, #neighbour{}}, Pid_positions ),        erlang:garbage_collect(), % Shrink process after using large Pid_positions. For memory starved systems.        loop( State#state{neighbour=Neighbour} );    {ant_start, Direction, Controller} when Controller =:= State#state.controller ->                {Pid, New_state} = loop_ant_departs( Direction, State ),                Pid ! {ant_arrives, erlang:self()},                loop( New_state );    {ant_arrives, From} ->                {Direction, New_state} = loop_ant_arrives( From, State ),                {To, Newest_state} = loop_ant_departs( Direction, New_state ),                To ! {ant_arrives, erlang:self()},                loop( Newest_state );    {position_colour, Controller} when Controller =:= State#state.controller ->                Controller ! {position_colour, State#state.position, State#state.colour},                loop( State );    {stop, Controller} when Controller =:= State#state.controller -> ok    end. loop_ant_arrives( Pid, State ) ->        Neighbour = State#state.neighbour,        From = loop_ant_arrives_direction( Pid, Neighbour ),        {loop_ant_arrives_new_direction(From, State), State}. loop_ant_arrives_direction( Pid, #neighbour{north=Pid} ) -> north;loop_ant_arrives_direction( Pid, #neighbour{south=Pid} ) -> south;loop_ant_arrives_direction( Pid, #neighbour{east=Pid} ) -> east;loop_ant_arrives_direction( Pid, #neighbour{west=Pid} ) -> west. loop_ant_arrives_new_direction( north, #state{colour=white} ) -> west;loop_ant_arrives_new_direction( north, #state{colour=black} ) -> east;loop_ant_arrives_new_direction( south, #state{colour=white} ) -> east;loop_ant_arrives_new_direction( south, #state{colour=black} ) -> west;loop_ant_arrives_new_direction( east, #state{colour=white} ) -> north;loop_ant_arrives_new_direction( east, #state{colour=black} ) -> south;loop_ant_arrives_new_direction( west, #state{colour=white} ) -> south;loop_ant_arrives_new_direction( west, #state{colour=black} ) -> north. loop_ant_departs( north, #state{position={_X,Y}, max_y=Y}=State ) ->        {State#state.controller, State};loop_ant_departs( south, #state{position={_X,1}}=State ) ->        {State#state.controller, State};loop_ant_departs( east, #state{position={X,_Y}, max_x=X}=State ) ->        {State#state.controller, State};loop_ant_departs( west, #state{position={1,_Y}}=State ) ->        {State#state.controller, State};loop_ant_departs( Direction, State ) ->        Neighbour = State#state.neighbour,        Pid = loop_ant_departs_pid( Direction, Neighbour ),        {Pid, State#state{colour=other_colour(State)}}. loop_ant_departs_pid( north, #neighbour{north=Pid} ) -> Pid;loop_ant_departs_pid( south, #neighbour{south=Pid} ) -> Pid;loop_ant_departs_pid( east, #neighbour{east=Pid} ) -> Pid;loop_ant_departs_pid( west, #neighbour{west=Pid} ) -> Pid. loop_neighbour( {Pid, {X, Y}}, {{X, My_y}, Neighbour} ) when Y =:= My_y + 1 -> {{X, My_y}, Neighbour#neighbour{north=Pid}};loop_neighbour( {Pid, {X, Y}}, {{X, My_y}, Neighbour} ) when Y =:= My_y - 1 -> {{X, My_y}, Neighbour#neighbour{south=Pid}};loop_neighbour( {Pid, {X, Y}}, {{My_x, Y}, Neighbour} ) when X =:= My_x + 1 -> {{My_x, Y}, Neighbour#neighbour{east=Pid}};loop_neighbour( {Pid, {X, Y}}, {{My_x, Y}, Neighbour} ) when X =:= My_x - 1 -> {{My_x, Y}, Neighbour#neighbour{west=Pid}};loop_neighbour( _Pid_position, Acc ) -> Acc. other_colour( #state{colour=white} ) -> black;other_colour( #state{colour=black} ) -> white. plane_create( Controller, Max_x, Max_y ) -> [{plane_create_cell(Controller, Max_x, Max_y, {X, Y}), {X,Y}} || X <- lists:seq(1, Max_x), Y<- lists:seq(1, Max_y)].plane_create_cell( Controller, Max_x, Max_y, Position ) -> erlang:spawn_link( fun() -> loop( #state{controller=Controller, max_x=Max_x, max_y=Max_y, position=Position} ) end ).
Output:
___________________________________________________________________##_______________________________
____________________________________________________________________##______________________________
_____________________________________________##__##____________###_##_#_____________________________
____________________________________________#__##__###________####_#__#_____________________________
___________________________________________#____##___#______##_##__#_#______________________________
________________________________________##_#_____#_____#######_###_##_______________________________
_______________________________________#__#__#___##_#___#__#####_#__#_______________________________
______________________________________###___#___####__##_###_#______##______________________________
___________________________________##_#_#__##__#___#_##__####_######________________________________
__________________________________#__#___#____#_____##__##___#_#_#####_#____________________________
_________________________________###_##__#__#____#___#####_#_##_#____###____________________________
_________________________________##_____##_###___##_###___##_####__#__#_____________________________
___________________________________###__###_#___#_#_###_____#__#____##______________________________
_____________________________________#_#___#########_#####___####___________________________________
_______________________________###_###__##_#__#______#___##__#______________________________________
________________________________#####_#####__##___#####____#_#_#____________________________________
_____________________________##_#_#######_###_######_#####_#_###____________________________________
____________________________#____##__##___###__#__#__#__#___#_#_____________________________________
___________________________###______###__#_##_##____#__#_##_#_______________________________________
___________________________#_#__#____#____#_#####__#____#_##________________________________________
________________________________##_###__#_#__##_##____#__#_#________________________________________
____________________________#_#_____#_#_____#_#_##_#_#__###_##_#____________________________________
___________________________#___###__#__#__#_#__####_##___##_####____________________________________
___________________________#___##_###_##_#__#___#_____####_#_##_____________________________________
___________________________#__##___###______#__####_###_##___##_____________________________________
___________________________#______###_____###__###___##__#____#_____________________________________
___________________________#_____#_#_#_####____####__##_##__________________________________________
___________________________#_____##_###_##___#_##_####_###___#_#____________________________________
___________________________#______#_#____#####_#_#_###_______###____________________________________
___________________________#____####_#____###_##_###___#_#____#_____________________________________
___________________________#_____#__##_##_##_####__##_##__####______________________________________
___________________________#_____#_##_##__#____#######______________________________________________
___________________________###___##__##__#_###_#_##_#___#___________________________________________
___________________________###____##_######_#__#___####____#________________________________________
____________________________#_##_#_##__##____####_#_##_####_#_______________________________________
____________________________#___#######_######__#_##_#_#____#_______________________________________
___________________________#___#___##_#__#___##_######__#__#________________________________________
___________________________#_##____###__#___#_#######_#__##_________________________________________
____________________________##_#_##___#_#_#_##_#__##__###___________________________________________
_____________________________######_##__________#####___#___________________________________________
_________________________________#___#__#####_#______#_#____________________________________________
__________________________________##_____#_#_##___#____#____________________________________________
_______________________________##_#__##_#_____##_#____###___________________________________________
_______________________________#_##_#______#_#___#____###___________________________________________
________________________________#___####_##___#___#____#____________________________________________
________________________________###__#___#___###___####_____________________________________________
________________________________#___##__##_##___#___________________________________________________
___________________________________##__##__#___###__________________________________________________
____________________________________##__#_##_##___#_________________________________________________
_________________________________________##__#___###________________________________________________
__________________________________________#_##_##___#_______________________________________________
___________________________________________##__#___###______________________________________________
____________________________________________#_##_##___#_____________________________________________
_____________________________________________##__#___###____________________________________________
______________________________________________#_##_##___#___________________________________________
_______________________________________________##__#___###__________________________________________
________________________________________________#_##_##___#_________________________________________
_________________________________________________##__#___###________________________________________
__________________________________________________#_##_##___#_______________________________________
___________________________________________________##__#___###______________________________________
____________________________________________________#_##_##___#_____________________________________
_____________________________________________________##__#___###____________________________________
______________________________________________________#_##_##___#___________________________________
_______________________________________________________##__#___###__________________________________
________________________________________________________#_##_##___#_________________________________
_________________________________________________________##__#___###________________________________
__________________________________________________________#_##_##___#_______________________________
___________________________________________________________##__#___###______________________________
____________________________________________________________#_##_##___#_____________________________
_____________________________________________________________##__#___###____________________________
______________________________________________________________#_##_##___#___________________________
_______________________________________________________________##__#___###__________________________
________________________________________________________________#_##_##___#_________________________
_________________________________________________________________##__#___###________________________
__________________________________________________________________#_##_##___#_______________________
___________________________________________________________________##__#_#####______________________
____________________________________________________________________#_#___####______________________
_____________________________________________________________________##_###_#_______________________
______________________________________________________________________#___##________________________


## Euphoria

Works with: Euphoria version 4.0.3, 4.0.0 RC1 and later
include std\console.einclude std\graphics.e sequence grid = repeat(repeat(1,100),100) --fill 100 by 100 grid with white (1)sequence antData = {48, 53, 360} --ant x coordinate, y coordinate, facing angleinteger iterations = 0 --while ant isn't out of bounds of the 100 by 100 area..while antData[1] > 0 and antData[1] < 100 and antData[2] > 0 and antData[2] < 100 do    switch grid[antData[1]][antData[2]] do        case 1 then--cell is already white            grid[antData[1]][antData[2]] = 0 --cell turns black, ant turns right            antData[3] += 90            break        case 0 then--cell is already black            grid[antData[1]][antData[2]] = 1 --cell turns white, ant turns left            antData[3] -= 90            break    end switch    --wrap ant directions if > 360 or < 90 (by 90)    switch antData[3] do        case 450 then            antData[3] = 90            break        case 0 then            antData[3] = 360            break    end switch      --move ant based on its new facing, one square    --first north, then south, east, west    switch antData[3] do        case 360 then            antData[2] -= 1            break        case 180 then            antData[2] += 1            break        case 90 then            antData[1] += 1            break        case 270 then            antData[1] -= 1            break    end switchiterations += 1end while wrap(0) --don't wrap text output, the grid wouldnt display as a square for y=1 to 100 do    printf(1,"\n")    for x=1 to 100 do        switch grid[x][y] do--each grid block , based on color            case 0 then                printf(1,".")                break            case 1 then                printf(1,"#")                break        end switch    end forend for      printf(1,"\n%d Iterations\n",iterations)any_key()--wait for keypress, put default message 'press any key..'
SDL output

Code needed to run SDL example with Mark Akita's SDL_gfx_Test1.exw (as template) included with his SDL_gfx package from rapideuphoria.com's archive -

In initialization section :
 sequence grid = repeat(repeat(1,100),100) --fill 100 by 100 grid with white (1)sequence antData = {48, 53, 360} --x coordinate, y coordinate, facing angle

In main() , after keystate=SDL_GetKeyState(NULL) , you can adapt the program above to draw the ant's step each frame. Use dummy=pixelColor(surface,x+20,y+12,#000000FF) (for example) to replace the text output. Just before the close of the while loop, use dummy=pixelColor(surface,antData[1]+20,antData[2]+12,#FF0000FF) for the ant and SDL_UpdateRect(surface,0,0,0,0) to display the graphic.

## F#

 // Langton's ant  F#   https://rosettacode.org/wiki/Langton%27s_ant // A list of cells which are black is maintained and then printed out at the end type Cell = { X : int; Y : int }  type Direction = | North | South | East| West // direction the ant is facing let withinBounds (dim:int) (cell: Cell) = // ant's cell within dimensions ?    cell.X < dim && cell.Y < dim && cell.X >= 0 && cell.Y >= 0   let rotateLeft (currentDirection: Direction) =    match currentDirection with         | North -> West | South -> East | East -> North | West -> South let rotateRight (currentDirection: Direction ) =    match currentDirection with         | North -> East | South -> West | East -> South | West -> North  let nextCell (dir:Direction) (cell: Cell) = // compute next cell based on the direction    match dir with        | North -> {cell with Y = cell.Y + 1 }        | South -> {cell with Y = cell.Y - 1 }        | East ->  {cell with X = cell.X + 1 }        | West ->  {cell with X = cell.X - 1 }  let isBlackCell (blackCells: Cell list) (cell:Cell) =    blackCells |> List.exists ( fun c -> c = cell) let toggleCellColor (blackCells: Cell list) (cell: Cell) =     if cell |> isBlackCell blackCells     then blackCells |> List.where( fun c -> c <> cell) // remove the cell from list of black cells     else cell::blackCells // add the cell to the list of black cells let moveToCell (blackCells: Cell list) (currentDir : Direction) (cell: Cell) =    let ndir = if cell |> isBlackCell blackCells  // next step direction is computed                    then rotateLeft currentDir                    else rotateRight currentDir    let nlst  = cell |> toggleCellColor blackCells // next step updated list of black cells is computed    let ncell = cell |> nextCell ndir  // next step cell is computedd    (nlst, ndir, ncell) // return next step list of black cells, direction it will enter the cell, new cell  let rec doStep (dim:int) (blackCells: Cell list) (dir : Direction) (cell: Cell) =         let (nlst, ndir, ncell) = moveToCell blackCells dir cell        if withinBounds dim ncell // check if the next step is within bounds            then doStep dim nlst ndir ncell // recursive call to next step            else nlst, ndir, ncell [<EntryPoint>]let main _ =   let dim = 100   let (blacklist, _, _) = doStep dim []  North { X = dim/2 ; Y = dim/2 } // start with empty blacklist, facing north in the center     // print out by row, 0th row is at the bottom   seq { for row in [dim-1..-1..0] do for col in [0..dim-1]  -> (col,row) }        |> Seq.iter (fun (row,col) -> if {X = row; Y = col } |> isBlackCell blacklist                                         then printf "#"  else printf " "                                      if row = (dim - 1 )                                        then printf "\n"  else  ()                    )   0

##  ############  ##
#  ####          #  ##
###   ##            ## #
# #  #         #  #    #
##  ## # #         ###       #
### #  #   #     #     ## ##  ###
# #  ###  ## #### ##   # #  # ##  ##
# ### ##  # ##  ### # #     ###   ###
#     #   ##### # #  ####  #   ### # # #
### ##   # ####  ## ## ###### # ### #   #
# ### # ## # # ## ## ## #   ##### ### ##
# #   # ## ###   #   # #  ####    # ##
#  #         ## ##   #  ##     ## #     ##
###   # # ## ###  #  ##     #   ### ##  ## #
#  ###  ##   ## ##   ###  #    #  ## ####   #
###   #   # #  # # #### ##  # ## ###  #     #
#  ###  # ##    #  # ###  #      ### ## #  #  ##
###   #     # ## # ##  ##  ##### ####  #### ##   #
#  ###  # # #  # ### # # ##      ##   # # #    #   #
###   #  ## ###  ## #   ##       #### ####   #      #
#  ###  # #  #   ##  ########### #  ####  #    #    #
###   #  ##      # ####  ##  #########  #  ##    #  ##
#  ###  # #   ##  # ##   ## ## ### ###   #  # ##  #### #
###   #  ##   #  # ###### ## # ## # #    ### ###   ##   #
#  ###  # #   #     ##### # #####     # #  ## #    ##   #
###   #  ##    #     # ## ##### ##  # #   #  #  ## #  #  #
#  ###  # #     #    #   #### #  ##### ##   ##########   ##
###   #  ##      # ##   ##   #  #   ####  #   ## #### ##
#  ###  # #        ##### #  ##   ## #   #    # #  #  #  # #
###   #  ##          ##  ## # # #    ## ## # # ##  #  ##  ##
#  ###  # #                 #  #    # ######## # # ##  #### #
###   #  ##                  #  #   #       ## ##   #  #  ## #
#  ###  # #                    #  #  #      #  ##  ##   ## ####
###   #  ##                      ##   #       ##  ##    #   # ###
#  ###  # #                            # ##  ####    #### ### ####
###   #  ##                              ##  ####    ##  # ## # #  #
#  ###  # #                                ##    ##    ## ### ## #####
###   #  ##                                                # ## #  ####
#  ###  # #                                                     ## ## ##
###   #  ##                                                      ##
#  ###  # #                                                     # ##  #### #
###   #  ##                                                     #  # ###  ###
#  ###  # #                                                      # ## #  #  #
###   #  ##                                                        ##      ##
#  ###  # #                                                          ##
### #  ##
# # # # #
#### ##
# ## #
####
##



## Gambas

'This code will create a GUI Form to display the result hGridView As GridView                                               'The display is on a GridViewiCol As Integer = 38                                                'Column start positioniRow As Integer = 30                                                'Row start position Public Sub Form_show() SetUpForm                                                           'Run the SetUpForm routineGo                                                                  'Run the Go routine End Public Sub Go()                                                     'This is what does the workDim siDir As Short = 3                                              'Stores the Direction of the ant 0 = North, 1 = East, 2 = South ,3 = WestDim siCount As Short                                                'Counter Repeat                                                              'Repeat loop  Inc siCount                                                       'Increase siCount  If hGridView[iRow, iCol].background = -1 Then                     'If the Background of the cell is white then..(Right turn)    hGridView[iRow, iCol].background = 0                            'Make the Background black    siDir = Direction(siDir, True)                                  'Get the direction to turn    If siDir = 0 Then Dec iRow                                      'Decrease Row if facing North    If siDir = 1 Then Inc iCol                                      'Increase Column if facing East    If siDir = 2 Then Inc iRow                                      'Increase Row if facing South    If siDir = 3 Then Dec iCol                                      'Decrease Column if facing West  End If 'Wait                                                                'This will allow you to see the Grid being populated. Rem it out for an instant result  If hGridView[iRow, iCol].background = 0 Then                      'If the Background of the cell is black then.. Left Turn    hGridView[iRow, iCol].background = -1                           'Make the Background white    siDir = Direction(siDir, False)                                 'Get the direction to turn    If siDir = 0 Then Dec iRow                                      'Decrease Row if facing North    If siDir = 1 Then Inc iCol                                      'Increase Column if facing East    If siDir = 2 Then Inc iRow                                      'Increase Row if facing South    If siDir = 3 Then Dec iCol                                      'Decrease Column if facing West  End If Until siCount = 9660                                                'Loop 9660 times End Public Sub Direction(siDirection As Short, bWay As Boolean) As Byte 'To workout which way to go If bWay Then                                                        'If turning Right then  Inc siDirection                                                   'Increase siDirection e.g. 0 = North to 1 = East Else                                                                'Else if turning Left  Dec siDirection                                                   'Decrease siDirection e.g. 2 = South to 1 = East End If If siDirection < 0 Then siDirection = 3                             'To address 0 - 1 = -1If siDirection > 3 Then siDirection = 0                             'To address 3 + 1 = 4 Return siDirection                                                  'Return the correct direction End Public Sub SetUpForm()                                              'Set up the Form and Create the Gridview With Me                                                             'Change the Properties of the Form  .Height = 1012                                                    'Set the Form Height  .Width = 1012                                                     'Set the Form Width  .Arrangement = Arrange.Vertical                                   'Set the Form Arrangement  .Padding = 5                                                      'Set the Form Padding (Border)  .title = "Langton's ant"                                          'Set the Form TitleEnd With hGridView = New GridView(Me)                                        'Create a GridViewWith hGridView                                                      'Change the Properties of the GridView  .Columns.count = 100                                              'Create 100 Columns  .Rows.count = 100                                                 'Create 100 Rows  .Columns.Width = 10                                               'Set the Column Width  .Rows.Height = 10                                                 'Set the Column Height  .expand = True                                                    'Set the Gridview to Expand to fill the Form  .background = -1                                                  'Set the Gridview background to WhiteEnd With End

## GFA Basic

To make it easier to see the output on small Atari screens, the output is written to a text file.

 '' Langton's ant'' World is a global boolean array, 100x100 in sizewidth%=100height%=100DIM world!(width%,height%)ARRAYFILL world!(),FALSE' Time in worldtime%=0' Ant is represented by a global three-element array' holding: x, y, direction [0=north,1=west,2=south,3=east]DIM ant%(3)'@setup_ant@run_ant@display_world'' Displays the world to file "langton.out": . for false, # for true'PROCEDURE display_world  LOCAL i%,j%  OPEN "o",#1,"langton.out"  PRINT #1,"Time in world: ";time%;" ticks"  FOR i%=0 TO width%-1    FOR j%=0 TO height%-1      IF world!(i%,j%)        PRINT #1,"#";      ELSE        PRINT #1,".";      ENDIF    NEXT j%    PRINT #1,""  NEXT i%  CLOSE #1RETURN'' Set up the ant to start at (50,50) facing north'PROCEDURE setup_ant  ant%(0)=50  ant%(1)=50  ant%(2)=0RETURN'' check if ant position is within world's bounds'FUNCTION ant_in_world  RETURN ant%(0)>=0 AND ant%(0)<width% AND ant%(1)>=0 AND ant%(1)<height%ENDFUNC'' Turn ant direction to left'PROCEDURE ant_turn_left  ant%(2)=(ant%(2)+1) MOD 4RETURN'' Turn ant direction to right'PROCEDURE ant_turn_right  ant%(2)=(ant%(2)+3) MOD 4RETURN'' Ant takes a step forward in current direction'PROCEDURE ant_step_forward  SELECT ant%(2)  CASE 0    ant%(0)=ant%(0)+1  CASE 1    ant%(1)=ant%(1)+1  CASE 2    ant%(0)=ant%(0)-1  CASE 3    ant%(1)=ant%(1)-1  ENDSELECTRETURN'' Run the ant until it falls out of the world'PROCEDURE run_ant  WHILE @ant_in_world    time%=time%+1    IF world!(ant%(0),ant%(1)) ! true for white      world!(ant%(0),ant%(1))=FALSE      @ant_turn_left    ELSE ! false for black      world!(ant%(0),ant%(1))=TRUE      @ant_turn_right    ENDIF    @ant_step_forward  WENDRETURN

## Go

Output png
package main import (    "fmt"    "image"    "image/color"    "image/draw"    "image/png"    "os") const (    up = iota    rt    dn    lt) func main() {    bounds := image.Rect(0, 0, 100, 100)    im := image.NewGray(bounds)    gBlack := color.Gray{0}    gWhite := color.Gray{255}    draw.Draw(im, bounds, image.NewUniform(gWhite), image.ZP, draw.Src)    pos := image.Point{50, 50}    dir := up    for pos.In(bounds) {        switch im.At(pos.X, pos.Y).(color.Gray).Y {        case gBlack.Y:            im.SetGray(pos.X, pos.Y, gWhite)            dir--        case gWhite.Y:            im.SetGray(pos.X, pos.Y, gBlack)            dir++        }        if dir&1 == 1 {            pos.X += 1 - dir&2        } else {            pos.Y -= 1 - dir&2        }    }    f, err := os.Create("ant.png")    if err != nil {        fmt.Println(err)        return    }    if err = png.Encode(f, im); err != nil {        fmt.Println(err)    }    if err = f.Close(); err != nil {        fmt.Println(err)    }}

The set of black cells is represented as a set of points. Complementary set is regarded as white cells.

Necessary import:

import Data.Set (member,insert,delete,Set)

In order to express the ant's algorithm literally we define two operators:

-- functional sequence (>>>) = flip (.) -- functional choicep ?>> (f, g) = \x -> if p x then f x else g x

Finally define the datatype representing the state of ant and ant's universe

data State = State { antPosition :: Point                   , antDirection :: Point                   , getCells :: Set Point } type Point = (Float, Float)

Now we are ready to express the main part of the algorithm

step :: State -> Statestep = isBlack ?>> (setWhite >>> turnRight,                    setBlack >>> turnLeft) >>> move  where    isBlack   (State p _     m) = member p m    setBlack  (State p d     m) = State p d (insert p m)    setWhite  (State p d     m) = State p d (delete p m)    turnRight (State p (x,y) m) = State p (y,-x) m    turnLeft  (State p (x,y) m) = State p (-y,x) m    move (State (x,y) (dx,dy) m) = State (x+dx, y+dy) (dx, dy) m

That's it.

Here is the solution of the task:

task :: State -> Statetask = iterate step    >>> dropWhile ((< 50) . distance . antPosition)    >>> getCells . head  where distance (x,y) = max (abs x) (abs y)

For given initial configuration it returns the set of black cells at the end of iterations.

We can display it graphically using Gloss library

import Graphics.Gloss main = display w white (draw (task initial))  where    w = InWindow "Langton's Ant" (400,400) (0,0)    initial = State (0,0) (1,0) mempty    draw = foldMap drawCell    drawCell (x,y) = Translate (10*x) (10*y) $rectangleSolid 10 10 Or animate the ant's trajectory main = simulate w white 500 initial draw (\_ _ -> step) where w = InWindow "Langton's Ant" (400,400) (0,0) initial = State (0,0) (1,0) mempty draw (State p _ s) = pictures [foldMap drawCell s, color red$ drawCell p]    drawCell (x,y) = Translate (10*x) (10*y) $rectangleSolid 10 10 ## Icon and Unicon link graphics,printf procedure main(A) e := ( 0 < integer(\A[1])) | 100 # 100 or whole number from command line LangtonsAnt(e)end record antrec(x,y,nesw) procedure LangtonsAnt(e) size := sprintf("size=%d,%d",e,e) label := sprintf("Langton's Ant %dx%d [%d]",e,e,0) &window := open(label,"g","bg=white",size) | stop("Unable to open window") ant := antrec(e/2,e/2,?4%4) board := list(e) every !board := list(e,"w") k := 0 repeat { k +:= 1 WAttrib("fg=red") DrawPoint(ant.x,ant.y) cell := board[ant.x,ant.y] if cell == "w" then { # white cell WAttrib("fg=black") ant.nesw := (ant.nesw + 1) % 4 # . turn right } else { # black cell WAttrib( "fg=white") ant.nesw := (ant.nesw + 3) % 4 # . turn left = 3 x right } board[ant.x,ant.y] := map(cell,"wb","bw") # flip colour DrawPoint(ant.x,ant.y) case ant.nesw of { # go 0: ant.y -:= 1 # . north 1: ant.x +:= 1 # . east 2: ant.y +:= 1 # . south 3: ant.x -:= 1 # . west } if 0 < ant.x <= e & 0 < ant.y <= e then next else break } printf("Langton's Ant exited the field after %d rounds.\n",k) label := sprintf("label=Langton's Ant %dx%d [%d]",e,e,k) WAttrib(label) WDone()end ## J dirs=: 0 1,1 0,0 _1,:_1 0langton=:3 :0 loc=. <.-:$cells=. (_2{.y,y)$dir=. 0 while. *./(0<:loc), loc<$cells do.    color=. (<loc) { cells    cells=. (-.color) (<loc)} cells    dir=. 4 | dir +  _1 ^ color    loc=. loc + dir { dirs  end.  ' #' {~ cells)
   langton 100 100
# #
## # #
# ### ##
#### ### #
##### #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #
###   #  ##
#   ## ## #  ##
###   #  ##  ##
#   ## ##  ##   #
####   ###   #   #  ###
#    #   #   ## ####   #
###    #   # #      # ## #
###    # ##     # ##  # ##
#    #   ## # #     ##
# #      # #####  #   #
#   #####          ## ######
###  ##  # ## # # #   ## # ##
##  # ####### #   #  ###    ## #
#  #  ###### ##   #  # ##   #   #
#    # # ## #  ###### #######   #
# #### ## # ####    ##  ## # ## #
#    ####   #  # ###### ##    ###
#   # ## # ### #  ##  ##   ###
#######    #  ## ## #     #
####  ## ##  #### ## ## ##  #     #
#    # #   ### ## ###    # ####    #
###       ### # # #####    # #      #
# #   ### #### ## #   ## ### ##     #
## ##  ####    #### # # #     #
#    #  ##   ###  ###     ###      #
##   ## ### ####  #      ###   ##  #
## # ####     #   #  # ## ### ##   #
#### ##   ## ####  # #  #  #  ###   #
# ## ###  # # ## # #     # #     # #
# #  #    ## ##  # #  ### ##
## #    #  ##### #    #    #  # #
# ## #  #    ## ## #  ###      ###
# #   #  #  #  #  ###   ##  ##    #
### # ##### ###### ### ####### # ##
# # #    #####   ##  ##### #####
#  ##   #      #  # ##  ### ###
####   ##### #########   # #
##    #  #     ### # #   # ###  ###
#  #  #### ##   ### ##   ### ##     ##
###    # ## # #####   #    #  #  ## ###
# ##### # #   ##  ##     #    #   #  #
###### ####  ## #   #  ##  # # ##
##      # ### ##  ####   #   ###
#  # #####  #   # ##   #  #  #
## ### #######     #     # ##
# #  ## ##      #   ##    #
#  # ####        ###  ##  #
# ## ###            ##  ##
##
##



## Java

This implementation allows for sizes other than 100x100, marks the starting position with a green box (sometimes hard to see at smaller zoom levels and the box is smaller than the "pixels" so it doesn't cover up the color of the "pixel" it's in), and includes a "zoom factor" (ZOOM) in case the individual "pixels" are hard to see on your monitor.

import java.awt.Color;import java.awt.Graphics; import javax.swing.JFrame;import javax.swing.JPanel; public class Langton extends JFrame{	private JPanel planePanel;	private static final int ZOOM = 4; 	public Langton(final boolean[][] plane){		planePanel = new JPanel(){			@Override			public void paint(Graphics g) {				for(int y = 0; y < plane.length;y++){					for(int x = 0; x < plane[0].length;x++){						g.setColor(plane[y][x] ? Color.BLACK : Color.WHITE);						g.fillRect(x * ZOOM, y * ZOOM, ZOOM, ZOOM);					}				}				//mark the starting point				g.setColor(Color.GREEN);				g.fillRect(plane[0].length / 2 * ZOOM,				           plane.length / 2 * ZOOM, ZOOM/2, ZOOM/2);			}		};		planePanel.setSize(plane[0].length - 1, plane.length - 1);		add(planePanel);		setSize(ZOOM * plane[0].length, ZOOM * plane.length + 30);		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);		setVisible(true);	} 	public static void main(String[] args){		new Langton(runAnt(100, 100));	} 	private static boolean[][] runAnt(int height, int width){		boolean[][] plane = new boolean[height][width];		int antX = width/2, antY = height/2;//start in the middle-ish		int xChange = 0, yChange = -1; //start moving up		while(antX < width && antY < height && antX >= 0 && antY >= 0){			if(plane[antY][antX]){				//turn left				if(xChange == 0){ //if moving up or down					xChange = yChange;					yChange = 0;				}else{ //if moving left or right					yChange = -xChange;					xChange = 0;				}			}else{				//turn right				if(xChange == 0){ //if moving up or down					xChange = -yChange;					yChange = 0;				}else{ //if moving left or right					yChange = xChange;					xChange = 0;				}			}			plane[antY][antX] = !plane[antY][antX];			antX += xChange;			antY += yChange;		}		return plane;	}}

Output (click for a larger view):

## JavaScript

Utilises the HTML5 canvas element to procedurally generate the image... I wanted to see the progress of the grid state as it was generated, so this implementation produces a incrementally changing image until an 'ant' hits a cell outside of the coordinate system. It can also accept multiple ants, this adds minimal complexity with only the addition of an 'ants' array which is iterated in each step, no additional conditions are necessary to simulate multiple ants, they coexist quite well... good ants ! 1st argument is an array of ant objects, 2nd argument is an object property list of options to change grid size, pixel size and interval (animation speed).

 // create global canvasvar canvas = document.createElement('canvas');canvas.id = 'globalCanvas';document.body.appendChild(canvas); function langtonant(antx, optx) {	'use strict';	var x, y, i; 	// extend default opts	var opts = {		gridsize: 100,		pixlsize: 4,		interval: 4	};	for (i in optx) {		opts[i] = optx[i];	} 	// extend default ants	var ants = [{		x: 50,		y: 50,		d: 0	}];	for (i in antx) {		ants[i] = antx[i];	} 	// initialise grid	var grid = [];	for (x = 0; x < opts.gridsize; x ++) {		grid[x] = [];		for (y = 0; y < opts.gridsize; y ++) {			grid[x][y] = true;		}	} 	// initialise directions	var dirs = [		{x: 1, y: 0},		{x: 0, y: -1},		{x: -1, y: 0},		{x: 0, y: 1}	]; 	// initialise canvas	var canv = document.getElementById('globalCanvas');	var cont = canv.getContext('2d');	canv.width = opts.gridsize * opts.pixlsize;	canv.height = opts.gridsize * opts.pixlsize; 	// initialise pixels	var pixlblac = cont.createImageData(opts.pixlsize, opts.pixlsize);	for (i = 0; i < (opts.pixlsize * opts.pixlsize * 4); i += 4) {		pixlblac.data[i + 3] = 255;	}	var pixlwhit = cont.createImageData(opts.pixlsize, opts.pixlsize);	for (i = 0; i < (opts.pixlsize * opts.pixlsize * 4); i += 4) {		pixlwhit.data[i + 3] = 0;	} 	// run simulation	function simulate() {		var sane = true; 		// iterate over ants		for (i = 0; i < ants.length; i ++) {			var n = ants[i]; 			// invert, draw, turn			if (grid[n.x][n.y]) {				grid[n.x][n.y] = false;				cont.putImageData(pixlblac, n.x * opts.pixlsize, n.y * opts.pixlsize);				n.d --;			} else {				grid[n.x][n.y] = true;				cont.putImageData(pixlwhit, n.x * opts.pixlsize, n.y * opts.pixlsize);				n.d ++;			} 			// modulus wraparound			n.d += dirs.length;			n.d %= dirs.length; 			// position + direction			n.x += dirs[n.d].x;			n.y += dirs[n.d].y; 			// sanity check			sane = (n.x < 0 || n.x > opts.gridsize || n.y < 0 || n.y > opts.gridsize) ? false : sane;		} 		// loop with interval		if (sane) {			setTimeout(simulate, opts.interval);		}	} 	simulate();}

Usage: default ants, custom opts

 langtonant({}, {	gridsize: 100,	pixlsize: 4,	interval: 4});
Output:

Usage: custom ants, default opts

 langtonant([	{		x: (100 / 2) + 7,		y: (100 / 2) + 7,		d: 1	}, {		x: (100 / 2) + 7,		y: (100 / 2) - 7,		d: 2	}, {		x: (100 / 2) - 7,		y: (100 / 2) - 7,		d: 3	}, {		x: (100 / 2) - 7,		y: (100 / 2) + 7,		d: 0	}]);
Output:

More functional approach to Javascript.

Requires lodash. Wants a canvas with id = "c"

 ///////////////////// LODASH IMPORT ///////////////////// // import all lodash functions to the main namespace, but isNaN not to cause conflicts_.each(_.keys(_), k => window[k === 'isNaN' ? '_isNaN' : k] = _[k]); constWORLD_WIDTH  = 100,WORLD_HEIGHT = 100,PIXEL_SIZE   = 4,DIRTY_COLOR  = '#000',VIRGIN_COLOR = '#fff',RUNS         = 10000,SPEED        = 50, //            up right down leftDIRECTIONS = [0, 1,    2,    3], displayWorld = (world) => each(world, (row, rowidx) => {  each(row, (cell, cellidx) => {    canvas.fillStyle = cell === 1 ? DIRTY_COLOR : VIRGIN_COLOR;    canvas.fillRect(rowidx * PIXEL_SIZE, cellidx * PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE);  });}), moveAnt = (world, ant) => {  world[ant.x][ant.y] = world[ant.x][ant.y] === 1 ? 0 : 1;  ant.dir             = DIRECTIONS[(4 + ant.dir + (world[ant.x][ant.y] === 0 ? 1 : -1)) % 4];  switch (ant.dir) {    case DIRECTIONS[0]:      ant.y -= 1;      break;    case DIRECTIONS[1]:      ant.x -= 1;      break;    case DIRECTIONS[2]:      ant.y += 1;      break;    case DIRECTIONS[3]:      ant.x += 1;      break;  }   return [world, ant];}, updateWorld = (world, ant, runs) => {  [world, ant] = moveAnt(world, ant);  displayWorld(world);   if (runs > 0) setTimeout(partial(updateWorld, world, ant, --runs), SPEED);}, canvas = document.getElementById('c').getContext('2d'); letworld = map(range(WORLD_HEIGHT), i => map(range(WORLD_WIDTH), partial(identity, 0))),ant   = {  x:   WORLD_WIDTH  / 2,  y:   WORLD_HEIGHT / 2,  dir: DIRECTIONS[0]}; canvas.canvas.width  = WORLD_WIDTH  * PIXEL_SIZE;canvas.canvas.height = WORLD_HEIGHT * PIXEL_SIZE; updateWorld(world, ant, RUNS);

## jq

In the following, the grid is boolean, and white is represented by true.

## zkl

Translation of: XPL0

Uses the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#zkl

white:=0xff|ff|ff; black:=0;w:=h:=100; bitmap:=PPM(w,h,white);x:=w/2; y:=h/2; dir:=0;	// start in middle facing eastdo{   if(bitmap[x,y]){ dir-=1; bitmap[x,y]=black; } // white-->black, turn left      else        { dir+=1; bitmap[x,y]=white; } // black-->white, turn right   switch(dir.bitAnd(3)){  // dir is always <0      case(0){ x+=1; }	// east      case(1){ y-=1; }	// south      case(2){ x-=1; }	// west      case(3){ y+=1; }  // north   }}while((0<=x<w) and (0<=y<h)); bitmap.write(File("foo.ppm","wb"));
Output:

Same as XPL0 (and using their image).