# 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, 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 pixels wide. Conceptually the ant can then travel infinitely far away.

For this task, start the ant near the center of a 100 by 100 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.

## Contents

with Ada.Text_IO; procedure Langtons_Ant is    Size: constant Positive := 100; -- change this to extend the playground    subtype Step is Integer range -1 .. +1;    procedure Right(N, W: in out Step) is      Tmp: Step := W;   begin      W := - N;      N := Tmp;   end Right;    procedure Left(N, W: in out Step) is   begin      for I in 1 .. 3 loop         Right(N, W);      end loop;   end Left;    Color_Character: array(Boolean) of Character :=     (False => ' ', True => '#');    Is_Black: array (1 .. Size, 1 .. Size) of Boolean :=     (others => (others => False)); -- initially, the world is white;    Ant_X, Ant_Y: Natural := Size/2; -- Position of Ant;   Ant_North: Step := 1; Ant_West: Step := 0; -- initially, Ant looks northward    Iteration: Positive := 1; begin   loop -- iterate the loop until an exception is raised      if Is_Black(Ant_X, Ant_Y) then         Left(Ant_North, Ant_West);      else         Right(Ant_North, Ant_West);      end if;      Is_Black(Ant_X, Ant_Y) := not Is_Black(Ant_X, Ant_Y);      Ant_X := Ant_X - Ant_North; -- this may raise an exception      Ant_Y := Ant_Y - Ant_West;  -- this may raise an exception      Iteration := Iteration + 1;    end loop; exception   when Constraint_Error => -- Ant has left its playground ... now output      for X in 1 .. Size loop         for Y in 1 .. Size loop            Ada.Text_IO.Put(Color_Character(Is_Black(X, Y)));         end loop;         Ada.Text_IO.New_Line;      end loop;      Ada.Text_IO.Put_Line("# Iteration:" & Integer'Image(Iteration));end Langtons_Ant;

Ouptut (to save space, I have removed the all-blank lines):

                                         ##  ############  ##
#  ####          #  ##
###   ##            ## #
# #  #         #  #    #
##  ## # #         ###       #
### #  #   #     #     ## ##  ###
# #  ###  ## #### ##   # #  # ##  ##
# ### ##  # ##  ### # #     ###   ###
#     #   ##### # #  ####  #   ### # # #
### ##   # ####  ## ## ###### # ### #   #
# ### # ## # # ## ## ## #   ##### ### ##
# #   # ## ###   #   # #  ####    # ##
#  #         ## ##   #  ##     ## #     ##
###   # # ## ###  #  ##     #   ### ##  ## #
#  ###  ##   ## ##   ###  #    #  ## ####   #
###   #   # #  # # #### ##  # ## ###  #     #
#  ###  # ##    #  # ###  #      ### ## #  #  ##
###   #     # ## # ##  ##  ##### ####  #### ##   #
#  ###  # # #  # ### # # ##      ##   # # #    #   #
###   #  ## ###  ## #   ##       #### ####   #      #
#  ###  # #  #   ##  ########### #  ####  #    #    #
###   #  ##      # ####  ##  #########  #  ##    #  ##
#  ###  # #   ##  # ##   ## ## ### ###   #  # ##  #### #
###   #  ##   #  # ###### ## # ## # #    ### ###   ##   #
#  ###  # #   #     ##### # #####     # #  ## #    ##   #
###   #  ##    #     # ## ##### ##  # #   #  #  ## #  #  #
#  ###  # #     #    #   #### #  ##### ##   ##########   ##
###   #  ##      # ##   ##   #  #   ####  #   ## #### ##
#  ###  # #        ##### #  ##   ## #   #    # #  #  #  # #
###   #  ##          ##  ## # # #    ## ## # # ##  #  ##  ##
#  ###  # #                 #  #    # ######## # # ##  #### #
###   #  ##                  #  #   #       ## ##   #  #  ## #
#  ###  # #                    #  #  #      #  ##  ##   ## ####
###   #  ##                      ##   #       ##  ##    #   # ###
#  ###  # #                            # ##  ####    #### ### ####
###   #  ##                              ##  ####    ##  # ## # #  #
#  ###  # #                                ##    ##    ## ### ## #####
###   #  ##                                                # ## #  ####
#  ###  # #                                                     ## ## ##
###   #  ##                                                      ##
#  ###  # #                                                     # ##  #### #
###   #  ##                                                     #  # ###  ###
#  ###  # #                                                      # ## #  #  #
###   #  ##                                                        ##      ##
##  # #                                                          ##
##  #  ##
# # # #
#### ##
# ## #
####
##
# Iteration: 11656


## Aime

integeris_white(list map, integer x, integer y){    integer p, w;    data b;     b = l_q_data(map, y);    w = b_character(b, x >> 3);    p = 1 << (7 - (x & 7));    b_replace(b, x >> 3, w ^ p);     return !(w & p);} voidant(integer x, integer y, integer d, list map){    while (-1 < x && x < 100 && -1 < y && y < 100) {        if (is_white(map, x, y)) {            d += 3;            d &= 3;        } else {            d += 1;            d &= 3;        }         if (d & 1) {            y += (d & 2) - 1;        } else {            x += 1 - (d & 2);        }    }} integermain(void){    integer i;    file f;    list l;     i = 100;    while (i) {        data b;        integer j;         i -= 1;        j = 13;        while (j) {            j -= 1;            b_append(b, 0);        }         l_l_data(l, -1, b);    }     ant(50, 50, 2, l);     f_open(f, "ant.pbm", OPEN_CREATE | OPEN_TRUNCATE | OPEN_WRITEONLY, 00644);     f_text(f, "P4\n100 100\n");    i = 100;    while (i) {        f_b_post(f, l_q_data(l, -i));        i -= 1;    }     return 0;}

## 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

## AutoIt

 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 ## 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[31m@\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++ 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 );}//--------------------------------------------------------------------------------------------------  ## 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> # # ## # # # ### ## #### ### # ##### # ## # ## ## # ### # ## # ## ## # ### # ## # ## ## # ### # ## # ## ## # ### # ## # ## ## # ### # ## # ## ## # ### # ## # ## ## # ### # ## # ## ## # ### # ## # ## ## # ### # ## # ## ## # ### # ## # ## ## # ### # ## # ## ## # ### # ## # ## ## # ### # ## # ## ## # ## ### # ## ## # ## ## ## # #### ### # # ### # # # ## #### # ### # # # # ## # ### # ## # ## # ## # # ## # # ## # # # ##### # # # ##### ## ###### ### ## # ## # # # ## # ## ## # ####### # # ### ## # # # ###### ## # # ## # # # # # ## # ###### ####### # # #### ## # #### ## ## # ## # # #### # # ###### ## ### # # ## # ### # ## ## ### ####### # ## ## # # #### ## ## #### ## ## ## # # # # # ### ## ### # #### # ### ### # # ##### # # # # # ### #### ## # ## ### ## # ## ## #### #### # # # # # # ## ### ### ### # ## ## ### #### # ### ## # ## # #### # # # ## ### ## # #### ## ## #### # # # # ### # # ## ### # # ## # # # # # # # # # ## ## # # ### ## ## # # ##### # # # # # # ## # # ## ## # ### ### # # # # # # ### ## ## # ### # ##### ###### ### ####### # ## # # # ##### ## ##### ##### # ## # # # ## ### ### #### ##### ######### # # ## # # ### # # # ### ### # # #### ## ### ## ### ## ## ### # ## # ##### # # # ## ### # ##### # # ## ## # # # # ###### #### ## # # ## # # ## ## # ### ## #### # ### # # ##### # # ## # # # ## ### ####### # # ## # # ## ## # ## # # # #### ### ## # # ## ### ## ## ## ##  ## 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");} ## 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 A straightforward implementation (assumes that we start with ant looking forward): 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 Translation of: Ruby defmodule Langtons do def ant(sizex, sizey) do {px, py} = {div(sizex,2), div(sizey,2)} # start position move(HashSet.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 Set.member?(plane, {px,py}), do: {Set.delete(plane, {px,py}), turn(dir, :right)}, else: {Set.put(plane, {px,py}), turn(dir, :left)} move(plane2, sx, sy, px+dx, py+dy, {dx,dy}, step+1) end defp turn({dx, dy}, :right), do: {dy, -dx} defp turn({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 -> Enum.map(0..sx, fn i -> if Set.member?(plane, {i,j}), do: "#", else: "." end) |> Enum.join |> IO.puts end) endend Langtons.ant(100, 100) Output: out of bounds after 11669 moves: (26, -1) ..........................#.#........................................................................ ........................##.#.#....................................................................... .......................#.###.##...................................................................... ......................####.###.#..................................................................... ......................#####.#..##.................................................................... .......................#...##.##.#................................................................... ........................###...#..##.................................................................. .........................#...##.##.#................................................................. ..........................###...#..##................................................................ ...........................#...##.##.#............................................................... ............................###...#..##.............................................................. .............................#...##.##.#............................................................. ..............................###...#..##............................................................ ...............................#...##.##.#........................................................... ................................###...#..##.......................................................... .................................#...##.##.#......................................................... ..................................###...#..##........................................................ ...................................#...##.##.#....................................................... ....................................###...#..##...................................................... .....................................#...##.##.#..................................................... ......................................###...#..##.................................................... .......................................#...##.##.#................................................... ........................................###...#..##.................................................. .........................................#...##.##.#................................................. ..........................................###...#..##................................................ ...........................................#...##.##.#............................................... ............................................###...#..##.............................................. .............................................#...##.##.#............................................. ..............................................###...#..##............................................ ...............................................#...##.##.#........................................... ................................................###...#..##.......................................... .................................................#...##.##.#..##..................................... ..................................................###...#..##..##.................................... ...................................................#...##.##..##...#................................. .............................................####...###...#...#..###................................. ............................................#....#...#...##.####...#................................. ...........................................###....#...#.#......#.##.#................................ ...........................................###....#.##.....#.##..#.##................................ ............................................#....#...##.#.#.....##................................... ............................................#.#......#.#####..#...#.................................. ...........................................#...#####..........##.######.............................. ...........................................###..##..#.##.#.#.#...##.#.##............................. .........................................##..#.#######.#...#..###....##.#............................ ........................................#..#..######.##...#..#.##...#...#............................ .......................................#....#.#.##.#..######.#######...#............................. .......................................#.####.##.#.####....##..##.#.##.#............................. ........................................#....####...#..#.######.##....###............................ ...........................................#...#.##.#.###.#..##..##...###............................ ..............................................#######....#..##.##.#.....#............................ ......................................####..##.##..####.##.##.##..#.....#............................ .....................................#....#.#...###.##.###....#.####....#............................ ....................................###.......###.#.#.#####....#.#......#............................ ....................................#.#...###.####.##.#...##.###.##.....#............................ ..........................................##.##..####....####.#.#.#.....#............................ .....................................#....#..##...###..###.....###......#............................ .....................................##...##.###.####..#......###...##..#............................ .....................................##.#.####.....#...#..#.##.###.##...#............................ ....................................####.##...##.####..#.#..#..#..###...#............................ ....................................#.##.###..#.#.##.#.#.....#.#.....#.#............................. ........................................#.#..#....##.##..#.#..###.##................................. ........................................##.#....#..#####.#....#....#..#.#............................ .......................................#.##.#..#....##.##.#..###......###............................ .....................................#.#...#..#..#..#..###...##..##....#............................. ....................................###.#.#####.######.###.#######.#.##.............................. ....................................#.#.#....#####...##..#####.#####................................. ......................................#..##...#......#..#.##..###.###................................ ...................................####...#####.#########...#.#...................................... ..............................##....#..#.....###.#.#...#.###..###.................................... .............................#..#..####.##...###.##...###.##.....##.................................. ............................###....#.##.#.#####...#....#..#..##.###.................................. ............................#.#####.#.#...##..##.....#....#...#..#................................... ................................######.####..##.#...#..##..#.#.##.................................... ..............................##......#.###.##..####...#...###....................................... ...............................#..#.#####..#...#.##...#..#..#........................................ ...............................##.###.#######.....#.....#.##......................................... ..............................#.#..##.##......#...##....#............................................ .............................#..#.####........###..##..#............................................. .............................#.##.###............##..##.............................................. ..............................##..................................................................... ...............................##.................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... ..................................................................................................... .....................................................................................................  ## 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. ## Fantom  class World{ Int height Int width Bool[] state new make (Int height, Int width) { this.height = height this.width = width state = List(Bool#, height * width) (height*width).times { state.add (false) } } Bool inWorld (Int x, Int y) { x >= 0 && x < width && y >= 0 && y < height } Void show () { height.times |h| { width.times |w| { Env.cur.out.writeChar (state[w*width+h] ? '#' : '.') } Env.cur.out.writeChar ('\n') } } Void flip (Int x, Int y) { state[x*width + y] = !state[x*width + y] } Bool stateOf (Int x, Int y) { state[x*width + y] }} enum class Direction { up (0, -1), down (0, 1), left (-1, 0), right (1, 0) private new make (Int deltaX, Int deltaY) { this.deltaX = deltaX this.deltaY = deltaY } Direction rotateLeft () { if (this == up) return left if (this == down) return right if (this == left) return down // if (this == right) return up } Direction rotateRight () { if (this == up) return right if (this == down) return left if (this == left) return up // if (this == right) return down } const Int deltaX const Int deltaY} class Ant{ World world Int currX Int currY Direction direction new make (World world, Int x, Int y) { this.world = world currX = x currY = y direction = Direction.up } Bool inWorld () { world.inWorld (currX, currY) } // the ant movement rules Void move () { if (world.stateOf (currX, currY)) { direction = direction.rotateLeft } else { direction = direction.rotateRight } world.flip (currX, currY) currX += direction.deltaX currY += direction.deltaY }} class Main{ Void main () { world := World (100, 100) ant := Ant (world, 50, 50) numIterations := 0 while (ant.inWorld) { ant.move numIterations += 1 } world.show echo ("Finished in$numIterations iterations")  }} 

Output (snipping the blank lines):

..........................................##..############..##......................................
.........................................#..####..........#..##.....................................
........................................###...##............##.#....................................
........................................#.#..#.........#..#....#....................................
....................................##..##.#.#.........###.......#..................................
.................................###.#..#...#.....#.....##.##..###..................................
..................................#.#..###..##.####.##...#.#..#.##..##..............................
..................................#.###.##..#.##..###.#.#.....###...###.............................
................................#.....#...#####.#.#..####..#...###.#.#.#............................
...............................###.##...#.####..##.##.######.#.###.#...#............................
...............................#.###.#.##.#.#.##.##.##.#...#####.###.##.............................
...................................#.#...#.##.###...#...#.#..####....#.##...........................
................................#..#.........##.##...#..##.....##.#.....##..........................
...............................###...#.#.##.###..#..##.....#...###.##..##.#.........................
..............................#..###..##...##.##...###..#....#..##.####...#.........................
.............................###...#...#.#..#.#.####.##..#.##.###..#.....#..........................
............................#..###..#.##....#..#.###..#......###.##.#..#..##........................
...........................###...#.....#.##.#.##..##..#####.####..####.##...#.......................
..........................#..###..#.#.#..#.###.#.#.##......##...#.#.#....#...#......................
.........................###...#..##.###..##.#...##.......####.####...#......#......................
........................#..###..#.#..#...##..###########.#..####..#....#....#.......................
.......................###...#..##......#.####..##..#########..#..##....#..##.......................
......................#..###..#.#...##..#.##...##.##.###.###...#..#.##..####.#......................
.....................###...#..##...#..#.######.##.#.##.#.#....###.###...##...#......................
....................#..###..#.#...#.....#####.#.#####.....#.#..##.#....##...#.......................
...................###...#..##....#.....#.##.#####.##..#.#...#..#..##.#..#..#.......................
..................#..###..#.#.....#....#...####.#..#####.##...##########...##.......................
.................###...#..##......#.##...##...#..#...####..#...##.####.##...........................
................#..###..#.#........#####.#..##...##.#...#....#.#..#..#..#.#.........................
...............###...#..##..........##..##.#.#.#....##.##.#.#.##..#..##..##.........................
..............#..###..#.#.................#..#....#.########.#.#.##..####.#.........................
.............###...#..##..................#..#...#.......##.##...#..#..##.#.........................
............#..###..#.#....................#..#..#......#..##..##...##.####.........................
...........###...#..##......................##...#.......##..##....#...#.###........................
..........#..###..#.#............................#.##..####....####.###.####........................
.........###...#..##..............................##..####....##..#.##.#.#..#.......................
........#..###..#.#................................##....##....##.###.##.#####......................
.......###...#..##................................................#.##.#..####......................
......#..###..#.#.....................................................##.##.##......................
.....###...#..##......................................................##............................
....#..###..#.#.....................................................#.##..####.#....................
...###...#..##.....................................................#..#.###..###....................
..#..###..#.#......................................................#.##.#..#..#.....................
.###...#..##........................................................##......##......................
#..###..#.#..........................................................##.............................
.###.#..##..........................................................................................
#.#.#.#.#...........................................................................................
.####.##............................................................................................
.#.##.#.............................................................................................
..####..............................................................................................
...##...............................................................................................
Finished in 11669 iterations


## Fortran

Works with: Fortran version 90 and later
program Langtons_Ant  implicit none   integer, parameter :: csize = 100  integer :: direction = 0, maxsteps = 20000  integer :: i, x, y    logical :: cells(csize,csize) = .true.  logical :: cflag   x = csize / 2;   y = x   do i = 1, maxsteps    cflag = cells(x,y)    if(cflag) then      direction = direction + 1      if(direction == 4) direction = direction - 4    else      direction = direction - 1      if(direction == -1) direction = direction + 4    end if     cells(x,y) = .not. cells(x,y)     select case(direction)      case(0)        y = y - 1      case(1)        x = x + 1      case(2)        y = y + 1      case(3)        x = x - 1    end select     if(x < 1 .or. x > csize .or. y < 1 .or. y > csize) exit  end do   do y = 1, csize    do x = 1, csize      if(cells(x,y)) then        write(*, "(a)", advance="no") "."      else        write(*, "(a)", advance="no") "#"      end if    end do    write(*,*)  end doend program
Output:
(Cropped to save space)
...................................................................................
...................................................................................
.........................................##..############..##......................
........................................#..####..........#..##.....................
.......................................###...##............##.#....................
.......................................#.#..#.........#..#....#....................
...................................##..##.#.#.........###.......#..................
................................###.#..#...#.....#.....##.##..###..................
.................................#.#..###..##.####.##...#.#..#.##..##..............
.................................#.###.##..#.##..###.#.#.....###...###.............
...............................#.....#...#####.#.#..####..#...###.#.#.#............
..............................###.##...#.####..##.##.######.#.###.#...#............
..............................#.###.#.##.#.#.##.##.##.#...#####.###.##.............
..................................#.#...#.##.###...#...#.#..####....#.##...........
...............................#..#.........##.##...#..##.....##.#.....##..........
..............................###...#.#.##.###..#..##.....#...###.##..##.#.........
.............................#..###..##...##.##...###..#....#..##.####...#.........
............................###...#...#.#..#.#.####.##..#.##.###..#.....#..........
...........................#..###..#.##....#..#.###..#......###.##.#..#..##........
..........................###...#.....#.##.#.##..##..#####.####..####.##...#.......
.........................#..###..#.#.#..#.###.#.#.##......##...#.#.#....#...#......
........................###...#..##.###..##.#...##.......####.####...#......#......
.......................#..###..#.#..#...##..###########.#..####..#....#....#.......
......................###...#..##......#.####..##..#########..#..##....#..##.......
.....................#..###..#.#...##..#.##...##.##.###.###...#..#.##..####.#......
....................###...#..##...#..#.######.##.#.##.#.#....###.###...##...#......
...................#..###..#.#...#.....#####.#.#####.....#.#..##.#....##...#.......
..................###...#..##....#.....#.##.#####.##..#.#...#..#..##.#..#..#.......
.................#..###..#.#.....#....#...####.#..#####.##...##########...##.......
................###...#..##......#.##...##...#..#...####..#...##.####.##...........
...............#..###..#.#........#####.#..##...##.#...#....#.#..#..#..#.#.........
..............###...#..##..........##..##.#.#.#....##.##.#.#.##..#..##..##.........
.............#..###..#.#.................#..#....#.########.#.#.##..####.#.........
............###...#..##..................#..#...#.......##.##...#..#..##.#.........
...........#..###..#.#....................#..#..#......#..##..##...##.####.........
..........###...#..##......................##...#.......##..##....#...#.###........
.........#..###..#.#............................#.##..####....####.###.####........
........###...#..##..............................##..####....##..#.##.#.#..#.......
.......#..###..#.#................................##....##....##.###.##.#####......
......###...#..##................................................#.##.#..####......
.....#..###..#.#.....................................................##.##.##......
....###...#..##......................................................##............
...#..###..#.#.....................................................#.##..####.#....
..###...#..##.....................................................#..#.###..###....
.#..###..#.#......................................................#.##.#..#..#.....
###...#..##........................................................##......##......
...##..#.#..........................................................##.............
##..#..##..........................................................................
.#.#.#.#...........................................................................
####.##............................................................................
#.##.#.............................................................................
.####..............................................................................
..##...............................................................................
...................................................................................
...................................................................................

### But, if one remembers complex numbers

       PROGRAM LANGTONSANTC   Langton's ant wanders across an initially all-white board, stepping one cell at a go.C   If the current cell is white, it becomes black and the ant turns right.C   If the current cell is black, it becomes white and the ant turns left.C   The ant advances one cell in its latest direction, and reconsiders.      INTEGER ENUFF      PARAMETER (ENUFF = 100)		!Said to be so.      CHARACTER*1 CELL(ENUFF,ENUFF)	!The work area.      COMPLEX WAY,PLACE		!A direction and a position.      INTEGER X,Y,XN,Y1		!Integer versions.      INTEGER STEP		!A counter.      CELL = ""				!Clear for action.      PLACE = CMPLX(ENUFF/2,ENUFF/2)	!Start at the middle.      WAY = (1,0)		!Initial direction is +x.Commence wandering.      DO STEP = 1,20000	!Enough to be going on with.        X = REAL(PLACE)		!Change languages.        Y = AIMAG(PLACE)	!Could mess about with EQUIVALENCE...        IF (X.LE.0 .OR. X.GT.ENUFF	!Are we still     1  .OR.Y.LE.0 .OR. Y.GT.ENUFF) THEN!Within bounds?          WRITE (6,1) STEP - 1,X,Y		!No! Offer details.    1     FORMAT ("Step ",I0," to (",I0,",",I0,") is out of bounds!")          EXIT					!And wander no further.        END IF				!But, if we're within bounds,        IF (CELL(X,Y).NE."#") THEN	!Consider our position.          CELL(X,Y) = "#"		!A blank cell becomes black. Ish.          WAY = WAY*(0,-1)		!Turn right.         ELSE				!Otherwise,          CELL(X,Y) = "+"		!A black cell becomes white. Ish.          WAY = WAY*(0,+1)		!Turn left.        END IF			!So much for changing direction.        PLACE = PLACE + WAY	!Advance one step.      END DO		!On to the next step.Consider the bounds...      DO Y1 = 1,ENUFF		!Work up from the bottom.        IF (ANY(CELL(:,Y1).NE." ")) EXIT	!The last line with a splot.      END DO			!Subsequent lines would be blank.      DO XN = ENUFF,1,-1	!Work back from the right hand side.        IF (ANY(CELL(XN,:).NE." ")) EXIT	!The last column with a splot.      END DO			!Subsequent columns would be blank.Cast forth the splotches.      DO Y = ENUFF,Y1,-1	!The topmost y-coordinate first!        WRITE (6,"(666A1)") CELL(1:XN,Y)	!Roll a line's worth.      END DO			!On to the next line.Completed.      END 

Output is the same, except for orientation. Here I have stuck to (x,y) Cartesian orientation rather than lines (y) increasing downwards. Just for fun, + signs mark cells that have been trampled and then cleaned. But not to pure white... Notice that some interior cells have never been trampled.

Output:
Step 11669 to (26,101) is out of bounds!
#+#
## #+#
#+###+##
####+###+#
#####+#++##
#+++##+##+#
###+++#++##
#+++##+##+#
###+++#++##
#+++##+##+#
###+++#++##
#+++##+##+#
###+++#++##
#+++##+##+#
###+++#++##
#+++##+##+#
###+++#++##
#+++##+##+#
###+++#++##
#+++##+##+#
###+++#++##
#+++##+##+#
###+++#++##
#+++##+##+#
###+++#++##
#+++##+##+#
###+++#++##
#+++##+##+#
###+++#++##
#+++##+##+#
###+++#++##
#+++##+##+#  ##
###+++#++## +##
#+++##+##++##+++#
####   ###+++#+++#++###
#++++#   #+++##+####+++#
###++++#   #+#++++++#+##+#
###++++# ##  +++#+##++#+##
#++++#  +## #+#+++++##++
#+#++++++#+#####++#+++#+
#+++#####++++++++++##+######
###++##++#+##+#+#+#+++##+#+##
## +#+#######+#+++#++###++++##+#
#++#++######+##+++#++#+## ++#+++#
#++++#+#+##+#++######+#######+++#
#+####+##+#+####++++##++##+#+##+#
#++++####+++#++#+######+##++++###
#+++#+##+#+###+#++##++##+++###
+++#######++++#++##+##+#+++++#
#### +##+##++####+##+##+##++#+++++#
#++++#+#+++###+##+###++++#+####++++#
###+++++++###+#+#+#####++++#+#++++++#
#+#+++###+####+##+#+++##+###+##+++++#
++++##+##++####++++####+#+#+#+++++#
#++++#++##+++###++###+++++###++++++#
##+++##+###+####++#++++++###+++##++#
##+#+####+++++#+++#++#+##+###+##+++#
####+##+++##+####++#+#++#++#++###+++#
#+##+###++#+#+##+#+#+++++#+#+++++#+#
++#+#++#++++##+##++#+#++###+##+++
++##+#++++#++#####+#++++#++++#++#+#
+#+##+#++#++++##+##+#++###++++++###
#+#+++#++#++#++#++###+++##++##++++#
###+#+#####+######+###+#######+#+##
#+#+#++++#####+++##++#####+#####+
#++##+++#++++++#++#+##++###+###
####+++#####+#########+++#+#+++
##   +#++#+++++###+#+#+++#+###++###+
#++#  ####+##+++###+##+++###+##+++++##
###++++#+##+#+#####+++#++++#++#++##+###
#+#####+#+#+++##++##++++ #++++#+  #++#
++######+####++## #+++#+ ##++#+# ##
##++++++#+###+##++####++ #+++###
#++#+#####++#+++#+##+++#+ #++#
##+###+#######+++++#+++++# ##
#+#++##+##++++++#+++##++++#
#++#+####        ###++##++#
#+##+###            ##  ##
##+
##


## 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)    }}

data Color = Black | White  deriving (Read, Show, Enum, Eq, Ord) putCell c = putStr (case c of Black -> "#"                              White -> ".") toggle :: Color -> Colortoggle color = toEnum $1 - fromEnum color data Dir = East | North | West | South deriving (Read, Show, Enum, Eq, Ord) turnLeft South = EastturnLeft dir = succ dir turnRight East = SouthturnRight dir = pred dir data Pos = Pos { x :: Int, y :: Int } deriving (Read) instance Show Pos where show p@(Pos x y) = "(" ++ (show x) ++ "," ++ (show y) ++ ")" -- Return the new position after moving one unit in the given directionmoveOne pos@(Pos x y) dir = case dir of East -> Pos (x+1) y South -> Pos x (y+1) West -> Pos (x-1) y North -> Pos x (y-1) -- Grid is just a list of liststype Grid = [[Color]] colorAt g p@(Pos x y) = (g !! y) !! x replaceNth n newVal (x:xs) | n == 0 = newVal:xs | otherwise = x:replaceNth (n-1) newVal xs toggleCell g p@(Pos x y) = let newVal = toggle$ colorAt g p  in replaceNth y (replaceNth x newVal (g !! y)) g printRow r = do { mapM_ putCell r ; putStrLn "" } printGrid g = mapM_ printRow g  data State = State { move :: Int, pos :: Pos, dir :: Dir, grid :: Grid } printState s = do {  putStrLn $show s; printGrid$ grid s} instance Show State where   show s@(State m p@(Pos x y) d g) =     "Move: " ++ (show m) ++  " Pos: " ++ (show p) ++ " Dir: " ++ (show d) nextState s@(State m p@(Pos x y) d g) =  let color = colorAt g p      new_d = case color of White -> (turnRight d)                            Black -> (turnLeft d)      new_m = m + 1      new_p = moveOne p new_d      new_g = toggleCell g p  in State new_m new_p new_d new_g inRange size s@(State m p@(Pos x y) d g) =  x >= 0 && x < size && y >= 0 && y < size initialState size = (State 0 (Pos (sizediv2) (sizediv2)) East [ [ White | x <- [1..size] ] | y <- [1..size] ]) --- mainsize = 100allStates = initialState size : [nextState s | s <- allStates] main = printState $last$ takeWhile (inRange size) allStates

## 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

## 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).