.orig x3000
ld r1, ASCIIDIFF1

; user input for grid size
lea r0, STGRIDSIZE
puts
in

add r0, r0, r1
add r0, r0, #-1
brz SELECTED100
ld r0, GRID300
st r0, GRIDSIZE
brnzp GRIDSELECTED

SELECTED100
ld r0, GRID100
st r0, GRIDSIZE

GRIDSELECTED

; User input for number of additional ants
lea r0, STHOWMANY
puts
in
add r1, r1, r0 ; r1 = number of additional ants
add r1, r1, #1
st r1, LIVINGANTS

; INITIALIZE FIRST ANT
and r7, r7, x0
add r7, r7, #9 ; loop counter for the other ants

and r1, r1, x0  ; x and y coordinates go in here
and r3, r3, x0  ; to be mapped to a cell id

; check grid size for starting coordinates
ld r4, GRIDSIZE
ld r6, GRID100
not r6, r6
add r6, r6, #1
add r6, r6, r4  ; grid size - 100
brz GRID100B

ld r1, START300
ld r3, START300
brnzp FIRSTANTCOORDINATES

GRID100B
ld r1, START100
ld r3, START100

FIRSTANTCOORDINATES

JSR MAPPY   ; takes r1 and r3 values, converts to cell id in r5

ld r6, LIVEANTTEMPLATE  ; = x8000, alive and facing north
add r6, r6, r5  ; complete antword for ant 1
lea r4, ANTWORD
str r6, r4, #0  ; put first ant in base address of ANTWORD array

ld r2, LIVINGANTS
ANTSETUPLOOP
add r4, r4, #1  ;   increment address of ant

add r2, r2, #-1
brnz INITIALIZEDEAD
JSR ANTCOORDS
JSR MAPPY
ld r6, LIVEANTTEMPLATE
add r6, r5, r6
brnzp READYTOSTORE

INITIALIZEDEAD
and r6, r6, x0

READYTOSTORE
str r6, r4, #0

add r7, r7, #-1
brnz DONESETUP
brnzp ANTSETUPLOOP

DONESETUP

BIGMOVELOOP ; one iteration of this loop moves all 10 ants (doing nothing if they're dead)
ld r1, LIVINGANTS
brz EVERYONEISDEAD
ld r1, ANTWORD

; FOR LOOP TO MOVE ALL 10 ANTS

ld r1, STEPCOUNT
add r1, r1, #1
st r1, STEPCOUNT

BRNZP BIGMOVELOOP
EVERYONEISDEAD ; :(

halt
STGRIDSIZE .stringz "Grid size? 1 for 100, 3 for 300 "
STHOWMANY .stringz "How many additional ants? "
ASCIIDIFF1 .fill #-48
SUBTEMP1 .fill #0
LIVINGANTS .fill #0
GRIDSIZE .fill #0
GRID100 .fill #100
GRID300 .fill #300
STEPCOUNT .fill #0
ANTWORD .blkw #10
START100 .fill #50
START300 .fill #150
LIVEANTTEMPLATE .fill x8000
ANTCOORDTEMP .fill #0
ANTCOORDTEMP2 .fill #0

;************************************************************************
;************************************************************************
;                             SUBROUTINES
;************************************************************************
;************************************************************************

; SUBROUTINE
ANTSONTHEMOVE
; [1] check if dead
; [2] extract current location
; [3] extract current direction
; [4] check current colour
; [5] turn
; [7] change location or kill

; INPUT: R1:
address of ant
;        R4:
grid size

; LOCAL: R2: ant word
;           R3: cell id of ant

st r2, MOVETEMP2
st r3, MOVETEMP3
st r5, MOVETEMP5
st r6, MOVETEMP6
st r7, MOVETEMP7
ldr r2, r1, #0  ; r2 = copy of ant-word

; [1] CHECK FOR DEATH. word for dead ants == x0000
add r2, r2, #0
brz ENDOFMOVE ; if ant-word + 0 == 0, ant is dead.

; [2] extract current location
ld r3, IDMASK ; for getting rid of first 3 bits of ant-word, leaving only location
and r3, r2, r3 ; r3 = cell id of ant

; [4] check current colour and flip it

jsr FLIPPITY    ; flips bit, puts original colour in R5
                ; white/0: turn right; black/1: turn left

; [5] turn the ant according to pre-flipped colour

add r0, r5, #0
brnp LEFTTURN

jsr TAKEARIGHTTURN
brnzp DONETURNING

LEFTTURN
jsr TAKEALEFTTURN
DONETURNING

; [7] change location and kill

ldr r2, r1, #0 ; reload modified antword from memory

ld r5, SOUTH    ; butmasks
ld r6, EAST

and r5, r5, r2
and r6, r6, r2  ; isolating the two direction bits, 2b and 3b, to determine direction

add r5, r5, #0  ;    check if 2b is 0
brnp SECTIOND   ;
add r6, r6, #0  ;   check if 3b is 0
brnp SECTIONC

; if both are zero, direction is north
;; if cell id <= grid size, ant is already at the top and will die
not r0, r4
add r0, r0, #1  ; r0 = negative grid size
add r3, r0, r3  ; r3 = cell id - grid
brn ANTDEATHISPERMANENT ; if negative, kill it
add r2, r2, r0  ; antword - grid size
brnzp ENDOFMOVE

SECTIONC
; if direction is 01, ant faces east
;; if (cellID % grid != grid -1)
;; then cellid++, else die
not r0, r4
add r0, r0, #1

add r5, r3, #0  ;    copy celll id to r5 to repeatedly subtract grid size
EASTMODLOOP
add r5, r5, r0  ;   cell id - grid
add r5, r5, #1  ; if this is 0, then r5 == grid - 1
brz ANTDEATHISPERMANENT
add r5, r5, #-1 ; but if not, undo it and re-loop
brn MOVEEAST    ; if negative, allowed to move east
                ; if equal to grid-1, ant is on eastern border and will die

BRNZP EASTMODLOOP

MOVEEAST
add r2, r2, #1  ; move east: CellID++
brnzp ENDOFMOVE

SECTIOND    ; first direction bit is 1
add r6, r6, #0  ; check if second bit is 0
brnp SECTIONF
; if it is 0, then direction is 10 = south
; if ant is on southern border, it dies
; if cellID >= grid^2-grid, then ant is on southern border

ld r0, N100
add r0, r0, r3  ; checking if grid size = 100
brz GRIDIS100
ld r0, GRIDSQ300HALF
add r3, r3, r0
add r3, r3, r0
add r3, r3, r0
add r3, r3, r0
brzp ANTDEATHISPERMANENT
add r2, r2, r4
brnzp ENDOFMOVE

GRIDIS100
ld r0, GRIDSQ100
add r3, r3, r0
brzp ANTDEATHISPERMANENT
add r2, r2, r4
brnzp ENDOFMOVE

SECTIONF
; direction bits are 11 = WEST
; if cellID % grid != 0, ant can go west, otherwise dead

add r6, r3, #0  ; copy cell id to r6
not r0, r4
add r0, r0, #1  ; r0 = -grid
WESTMODLOOP
add r6, r6, r0
brz ANTDEATHISPERMANENT
brn CANMOVEWEST
brp WESTMODLOOP

CANMOVEWEST
add r2, r2, #-1
brnzp ENDOFMOVE

ANTDEATHISPERMANENT
and r2, r2, #0
ld r7, LIVINGANTS
add r7, r7, #-1
st r7, LIVINGANTS

ENDOFMOVE
str r1, r2, #0  ;    double check this syntax
ld r2, MOVETEMP2
ld r3, MOVETEMP3
ld r5, MOVETEMP5
ld r6, MOVETEMP6
ld r7, MOVETEMP7
RET

N100 .fill #-100
GRIDSQ100 .fill #-9900
GRIDSQ300HALF .fill #-22425
MOVETEMP3 .fill #0
MOVETEMP2 .fill #0
MOVETEMP4 .fill #0
MOVETEMP5 .fill #0
MOVETEMP6 .fill #0
MOVETEMP7 .fill x0
IDMASK .fill x1FFF    ;   for extracting bits 12-0, the cell ID of the ant

; end of ANTSONTHEMOVE subroutine

FAKEXOR ; subroutine

; XOR of two registers
; INPUT r2, r4
; OUTPUT r6 = r2 XOR r4

; A in r4, not A in r5
; B in r2; not B in r6
; r4 XOR r2

st r5, XORTEMP5

not r6, r2
and r6, r6, r4  ; r6 = a & ~b
not r6, r6      ; r6 = ~(a & ~b)

not r5, r4      ; r5 = ~ a
and r5, r5, r2  ; r5 = ~a & b
not r5, r5      ; r5 = ~(~a & b)
and r6, r5, r6  ; r6 = ~(a & ~b) & ~(~a & b)
not r6, r6      ; r6 = ~( ~(a & ~b) & ~(~a & b) ) = a XOR b

ld r5, XORTEMP5

RET

XORTEMP5 .fill #0

; SUBROUTINE
 FLIPPITY
; Takes a cell id and flips the bit in the grid, returns the original colour
; INPUT     r1: cell id
; LOCAL     r2: which bit to flip, then bitmask
;           r3: quotient, then address of byte to change
; OUTOUT    r5: original colour of cell id, before flipping. 1 if black, 0 if white.
;
; First, get byte (GRID + OFFSET)
; CELL ID / 16

st r4, FLIPTEMP4
st r5, FLIPTEMP5
st r6, FLIPTEMP6

and r3, r3, #0
add r2, r1, #0  ; copy cell id into r2

; loop to divide cellid by 16
FLIPLOOP
add r2, r2, #-16 ; cell id - 16
brn FLIPLOOPDONE    ; if negative, division done
add r3, r3, #1      ; if not negative, increment quotient and subtract again
BRNZP FLIPLOOP

FLIPLOOPDONE
add r2, r2, #8      ; add 16 back to negative number to get cellid % 16
add r2, r2, #8      ; this is which bit within the byte that the cell ID refers to

lea r4, GRID        ; starting address of GRID array
add r3, r3, r4      ; r3 = address of byte that will be changed = GRID base address + CELL ID / 16

lea r4, BM1         ; r4 = address of butmask array
add r4, r4, r2      ; r4 + which bit to flip = address of appropriate bitmask
ldr r2, r4, #0      ; r2 = bitmask to flip one bit

ldr r4, r3, #0      ; r4 = byte to be changed

and r0, r2, r4      ; indicates original colour of bit. 0 if white, non-zero if black

; A in r4, not A in r5
; B in r2; not B in r6
; r4 XOR r2
not r6, r2
and r6, r6, r4  ; r6 = a & ~b
not r6, r6      ; r6 = ~(a & ~b)

not r5, r4      ; r5 = ~ a
and r5, r5, r2  ; r5 = ~a & b
not r5, r5      ; r5 = ~(~a & b)
and r6, r5, r6  ; r6 = ~(a & ~b) & ~(~a & b)
not r6, r6      ; r6 = ~( ~(a & ~b) & ~(~a & b) ) = a XOR b

str r6, r3, #0

ld r4, FLIPTEMP4
ld r6, FLIPTEMP6

add r5, r0, #0  ; move colour of bit into r5 for output

ret
GRID .fill x8000
FLIPTEMP4 .fill #0
FLIPTEMP5 .fill #0
FLIPTEMP6 .fill #0

; bitmasks for flipping one bit
BM1 .fill x8000
BM2 .fill x4000
BM3 .fill x2000
BM4 .fill x1000
BM5 .fill x0800
BM6 .fill x0400
BM7 .fill x0200
BM8 .fill x0100
BM9 .fill x0080
BM10 .fill x0040
BM11 .fill x0020
BM12 .fill x0010
BM13 .fill x0008
BM14 .fill x0004
BM15 .fill x0002
BM16 .fill x0001

; END OF FLIPPITY SUBROUTINE

; SUBROUTINE
TAKEALEFTTURN
; turns the ant 90 degrees left

; INPUT R1: address in memory of ANT
; LOCAL R2: ant
;       R3: bitmask
;       R4: 3rdbit
;       R5: 2nd and 3rd bit
;       R6:
;       R7:
;       R0:

st r2, LEFTTURNTEMP2
st r3, LEFTTURNTEMP3
st r4, LEFTTURNTEMP4
st r6, LEFTTURNTEMP6
st r7, LEFTTURNTEMP7  ;  store r7, load before RET
ldr r2, r1, #0  ;  load ant into r2
ld r3, EAST
and r4, r2, r3 ; r4 = 3rdbit

ld r3, WEST
;and r5, r2, r3 ; r5 = 2nd and 3rd bits

add r4, r4, #0 ; check if 3rd bit is 0
brnp THIRDBIT1  ; If so, continue. If not, jump to next part.
; 3rd bit is 0, so XOR r2 ant-word with WEST bitmask, already in R3

BRNZP LEFTTURNEND

THIRDBIT1
; third bit is 1, so use EAST bitmask
ld r3, EAST

LEFTTURNEND

add r0, r4, #0  ; move r4 3rdbit into r0 temporarily
add r4, r3, #0  ; move r3 bitmask into r4 for the XOR subroutine
JSR FAKEXOR   ; r6 = r2 XOR r4
              ; flips the correct bit to turn left

add r3, r4, #0 ; moves r4 bitmask back into r3
add r4, r0, #0  ; moves r0 3rdbit back into r3

str r6, r1, #0  ; store tweaked ant-word with new direction back in memory

ld r2, LEFTTURNTEMP2
ld r3, LEFTTURNTEMP3
ld r4, LEFTTURNTEMP4
ld r6, LEFTTURNTEMP6
ld r7, LEFTTURNTEMP7
RET

WEST .fill X6000
EAST .fill x2000
NORTH .fill x0000
SOUTH .fill x4000

LEFTTURNTEMP2 .fill #0
LEFTTURNTEMP3 .fill #0
LEFTTURNTEMP4 .fill #0
LEFTTURNTEMP6 .fill #0
LEFTTURNTEMP7 .fill #0

; end of TAKEALEFTTURN subroutine

; SUBROUTINE
TAKEARIGHTTURN
; turns the ant 90 degrees right

; INPUT R1: address in memory of ANT
; LOCAL R2: ant
;       R3: bitmask
;       R4: 3rdbit
;   R5: 2nd and 3rd bit
;   R6:
;   R7:
;   R0:

st r2, RIGHTTURNTEMP2
st r3, RIGHTTURNTEMP3
st r4, RIGHTTURNTEMP4
st r6, RIGHTTURNTEMP6
st r7, RIGHTTURNTEMP7  ;  store r7, load before RET
ldr r2, r1, #0  ;  load ant into r2
ld r3, EAST
and r4, r2, r3 ; r4 = 3rdbit

;ld r3, WEST
;and r5, r2, r3 ; r5 = 2nd and 3rd bits

add r4, r4, #0 ; check if 3rd bit is 0
brnp THIRDBIT1RIGHT  ; If so, continue. If not, jump to next part.
; 3rd bit is 0, so XOR r2 ant-word with EAST bitmask
ld r3, EAST

BRNZP RIGHTTURNEND

THIRDBIT1RIGHT
; third bit is 1, so use WEST bitmask
ld r3, WEST

RIGHTTURNEND

add r0, r4, #0  ; move r4 3rdbit into r0 temporarily
add r4, r3, #0  ; move r3 bitmask into r4 for the XOR subroutine
JSR FAKEXOR   ; r6 = r2 XOR r4
              ; flips the correct bit to turn right

add r3, r4, #0 ; moves r4 bitmask back into r3
add r4, r0, #0  ; moves r0 3rdbit back into r3

str r6, r1, #0  ; store modified ant-word with new direction back in memory

ld r2, RIGHTTURNTEMP2
ld r3, RIGHTTURNTEMP3
ld r4, RIGHTTURNTEMP4
ld r6, RIGHTTURNTEMP6
ld r7, RIGHTTURNTEMP7
RET

RIGHTTURNTEMP2 .fill #0
RIGHTTURNTEMP3 .fill #0
RIGHTTURNTEMP4 .fill #0
RIGHTTURNTEMP6 .fill #0
RIGHTTURNTEMP7 .fill #0

; end of TAKEARIGHTTURN subroutine

; SUBROUTINE
ANTCOORDS
; INPUT     r2: index of ant
; OUTPUT    r1: x coordinate value
;           r3: y coordinate value
; "Enter x coordinates for ant #whatever"

st r4, COORD2

ld r0, NEWLINE
out
lea r0, ENTERXCOORDS
puts
ld r3, ASCIIPLUS
;add r0, r2, r3
;out
ld r0, NEWLINE
out

ld r5, ASCIIDIFF
getc
out
add r4, r0, r5  ; r4 holds first digit of x

add r1, r4, r4  ; r1 = 2 * r4
add r1, r1, r1  ; r1 = 4 * r4
add r1, r1, r1  ; r1 = 8 * r4
add r1, r1, r4  ; r1 = 9 * r4
add r1, r1, r4  ; r1 = 10 * r4

getc
out
add r4, r0, r5  ; r4 holds 2nd digit of x
add r1, r1, r4  ; full value of x coordt
st r1, COORD1

; "enter y coords"
ld r0, NEWLINE
out
lea r0, ENTERYCOORDS
puts
ld r3, ASCIIPLUS
;add r0, r2, r3
;out
ld r0, NEWLINE
out

ld r5, ASCIIDIFF
getc
out
add r4, r0, r5  ; r4 holds first digit of y

add r1, r4, r4  ; r1 = 2 * r4
add r1, r1, r1  ; r1 = 4 * r4
add r1, r1, r1  ; r1 = 8 * r4
add r1, r1, r4  ; r1 = 9 * r4
add r1, r1, r4  ; r1 = 10 * r4

getc
out
add r4, r0, r5  ; r4 holds 2nd digit of y
add r3, r1, r4  ; full value of y coord
ld r1, COORD1
ld r4, COORD2
RET

ENTERXCOORDS .STRINGZ "Enter x coordinates for ant "
ENTERYCOORDS .STRINGZ "Enter y coordinates for ant "
ASCIIDIFF .fill #-48
ASCIIPLUS .fill #48
COORD1 .fill #0
NEWLINE .fill #10
COORD2 .fill #0
COORD3 .fill #0

; END OF ANT_COORDINATES_SUBROUTINE

MAPPY
; Maps the coordinates of the ant
; Input:  R1: x coord
;  R3: y coord
;  R4: grid size
; Output: R5: Cell ID
; Cell ID = grid size * y coord + x coord

st r6, MAP1
st r7, MAP2

; multiply by 100
add R0, R3, R3 ; 2y
add R0, R0, R0 ; 4y
add R6, R0, R0 ; 8y
add R6, R6, R6 ; 16y
add R6, R6, R6 ; 32y
add R0, R0, R6 ; 36y
add R6, R6, R6 ; 64y
add R0, R0, R6 ; 100y

ld R7, N100a
add R7, R4, R7

brz GRID100a
add R0, R0, R0 ;200y
add R0, R0, R3 ;300y

GRID100a
Add R5, R0, R1  ; OUTPUT: R5 = grid*y + x

ld r6, MAP1
ld r7, MAP2
RET
N100a .fill #-100
MAP1 .fill #0
MAP2 .fill #0

; END OF MAPPY SUBROUTINE

.end


dim arena(100,100)
black=0
white=not(black)
for i = 1 to 100
  for j = 1 to 100
    arena(i,j)=white
  next
next
'north=1 east=2 south=3 west=4

nomainwin
graphicbox #1.g, 0, 0, 100, 100
open "Langton's Ant" for window as #1
#1 "trapclose Quit"
#1.g "down"

antX=50:antY=50
nsew=1    'ant initially points north

while (antX>0) and (antX<100) and (antY>0) and (antY<100)
    if arena(antX,antY) then
      nsew=nsew-1
      if nsew<1 then nsew=4
    else
      nsew=nsew+1
      if nsew>4 then nsew=1
    end if

    select case nsew
      case 1: antY=antY-1
      case 2: antX=antX+1
      case 3: antY=antY+1
      case 4: antX=antX-1
      end select

    arena(antX,antY)=not(arena(antX,antY))
    #1.g "color ";GetColor$(antX,antY)
    #1.g "set ";antX;" ";antY
wend

#1.g "flush"
wait

function GetColor$(x,y)
    if arena(x,y) then
        GetColor$="white"
    else
        GetColor$="black"
    end if
    end function

sub Quit handle$
    close #handle$
    end
    end sub


10 mode 1:defint a-z:deg
20 ink 1,0:ink 0,26
30 x=50:y=50:ang=270
40 dim play(100,100)
50 graphics pen 3:move 220,100:drawr 200,0:drawr 0,200:drawr -200,0:drawr 0,-200
60 ' move ant
70 if play(x,y) then ang=ang-90 else ang=ang+90
80 play(x,y)=1-play(x,y)
90 plot 220+2*x,100+2*y,play(x,y)
100 ang=ang mod 360
110 x=x+sin(ang)
120 y=y+cos(ang)
130 if x<1 or x>100 or y<1 or y>100 then end
140 goto 70


make "size 100
make "white 1
make "black 2
make "sum sum :white :black
make "chars [. #]
make "origin quotient :size 2
make "grid mdarray (list :size :size)
make "directions [ [1 0] [0 1] [-1 0] [0 -1] ]

repeat size [
  local "y
  make "y repcount
  repeat size [
    mdsetitem (list repcount :y) :grid :white
  ]
]
make "x quotient :size 2
make "y quotient :size 2
make "direction sum 1 random count :directions

while [(and (:x > 0) (:x <= :size) (:y > 0) (:y <= :size))] [
  local "color
  make "color mditem (list :x :y) :grid
  local "delta
  ifelse [equal? :color :white] [
     make "delta 1
  ] [
     make "delta -1
  ]
  make "direction sum 1 (modulo (:direction + :delta - 1) count :directions)
  make "dir (item :direction :directions)
  mdsetitem (list :x :y) :grid (sum :sum minus :color)
  make "x sum :x first :dir
  make "y sum :y last :dir
]

repeat size [
  local "y
  local "blank
  make "y repcount
  make "blank "true
  repeat size [if ( (mditem (list repcount :y) :grid) = :black ) [make "blank "false]]

  if [not :blank] [
    repeat size [
      type item (mditem (list repcount :y) :grid) :chars
    ]
    print []
  ]
]
bye


HAI 1.3

I HAS A plane ITZ A BUKKIT
IM IN YR init UPPIN YR i TIL BOTH SAEM i AN 10000
    plane HAS A SRS i ITZ FAIL
IM OUTTA YR init

I HAS A x ITZ 50, I HAS A y ITZ 50
I HAS A dir ITZ 0, I HAS A pos, I HAS A cell

BTW, WE PURRTIND WE HAS A 2D STRUKSHUR FUR EZ AKSESS
IM IN YR walker
    pos R SUM OF PRODUKT OF y AN 100 AN x
    cell R NOT plane'Z SRS pos
    plane'Z SRS pos R cell
    dir R MOD OF SUM OF dir AN SUM OF 5 AN PRODUKT OF cell AN 2 AN 4

    dir, WTF?
    OMG 0, x R  SUM OF x AN 1, GTFO
    OMG 1, y R DIFF OF y AN 1, GTFO
    OMG 2, x R DIFF OF x AN 1, GTFO
    OMG 3, y R  SUM OF y AN 1, GTFO
    OIC

    BTW, CHEKIN TEH ANTZ BOUNDZ
    WON OF BOTH SAEM x AN -1 AN BOTH SAEM x AN 100, O RLY?, YA RLY, GTFO, OIC
    WON OF BOTH SAEM y AN -1 AN BOTH SAEM y AN 100, O RLY?, YA RLY, GTFO, OIC
IM OUTTA YR walker

IM IN YR printer UPPIN YR cell TIL BOTH SAEM cell AN 10000
    plane'Z SRS cell, O RLY?
        YA RLY, VISIBLE "#"!
        NO WAI, VISIBLE "."!
    OIC

    NOT MOD OF SUM OF cell AN 1 AN 100, O RLY?, YA RLY, VISIBLE "", OIC
IM OUTTA YR printer BTW, UR OUTTA CYAN

KTHXBYE


local socket = require 'socket' -- needed for socket.sleep
local curses = require 'curses' -- used for graphics

local naptime = 0.02 -- seconds
local world_x, world_y = 100, 100

local world = (function (x, y)
	local wrl = {}
	for i = 1, y do
		wrl[i] = {}
		for j = 1, x do
			wrl[i][j] = 0
		end
	end
	return wrl
end)(world_x, world_y)

-- directions: 0 up, clockwise
local ant = {
	x = math.floor(world_x / 2),
	y = math.floor(world_y / 2),
	dir = 0,
	step = function(self)
		if self.dir == 0 then self.y = self.y - 1
		elseif self.dir == 1 then self.x = self.x + 1
		elseif self.dir == 2 then self.y = self.y + 1
		else self.x = self.x - 1
		end
	end
}

world.step = function (self, ant)
	if self[ant.y][ant.x] == 0 then	-- white
		-- change cell color
		self[ant.y][ant.x] = 1
		-- change dir
		ant.dir = (ant.dir + 1) % 4
		ant:step()
		-- boundary conditions
		if ant.x < 1 then ant.x = world_x
		elseif ant.x > world_x then ant.x = 1
		end
		if ant.y < 1 then ant.y = world_y
		elseif ant.y > world_y then ant.y = 1
		end
	else
		-- change cell color
		self[ant.y][ant.x] = 0
		-- change dir
		ant.dir = (ant.dir - 1) % 4
		ant:step()
		-- boundary conditions
		if ant.x < 1 then ant.x = world_x
		elseif ant.x > world_x then ant.x = 1
		end
		if ant.y < 1 then ant.y = world_y
		elseif ant.y > world_y then ant.y = 1
		end
	end
end

world.draw = function (self, ant)
	for i = 1, #self do
		for j = 1, #self[i] do
			if i == ant.y and j == ant.x then
				win:attron(curses.color_pair(3))
				win:mvaddch(i,j,"A")
				--win:attroff(curses.color_pair(3))
			elseif self[i][j] == 0 then
				win:attron(curses.color_pair(1))
				win:mvaddch(i,j," ")
				--win:attroff(curses.color_pair(1))
			elseif self[i][j] == 1 then
				win:attron(curses.color_pair(2))
				win:mvaddch(i,j," ")
				--win:attroff(curses.color_pair(2))
			else error("self[" .. i .. "][" .. j .. "] is " .. self[i][j] .. "!")
			end
		end
	end
end

local it = 1
curses.initscr()
curses.start_color()
curses.echo(false)
curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_WHITE)
curses.init_pair(2, curses.COLOR_BLACK, curses.COLOR_BLACK)
curses.init_pair(3, curses.COLOR_RED, curses.COLOR_WHITE)
curses.init_pair(4, curses.COLOR_WHITE, curses.COLOR_BLACK)
win = curses.newwin(world_y + 1, world_x, 0, 0)
win:clear()
repeat
	world:draw(ant)
	win:move(world_y, 0)
	win:clrtoeol()
	win:attron(curses.color_pair(4))
	win:addstr("Iteration: " .. it .. ", nap = " .. naptime*1000 .. "ms")
	win:refresh()
	world:step(ant)
	it = it + 1
	--local c = stdscr:getch()
	--if c == '+' then naptime = naptime - (naptime / 10)
	--elseif c == '-' then naptime = naptime + (naptime / 10)
	--end
	socket.sleep(naptime)
until false


Module Ant {
	Form 120,102
	N=100
	Enum CellColor {black=0,white=#FFFFFF}
	Enum Direction{North=90, West=180, South=270, East=0}
	Function Rotate(cd as Direction, clockwise=true) {
			cd=(cd+if(clockwise->270,90)) mod 360
			=cd  ' return a Direction Enum type
	}

	dim rect(1 to N, 1 to N)=white
	cx=N div 2
	cy=N div 2
	cd=North
	rect(cx,cy)=black
	endmove=False
	while not endmove
		movecell()

	end while
	Disp()

	sub movecell()
		select case rect(cx,cy)
		case black
			cd=Rotate(cd, false) : rect(cx, cy)=white
		case white
			cd=Rotate(cd) : rect(cx, cy)=black
		end select
		select case cd
		case North
			cy--
		case West
			cx--
		case South
			cy++
		case East
			cx++
		end select
		endmove= cx<1 or cx>N or cy<1 or cy>N
	end sub
	sub disp()
		Local Doc$, i, j
		Document Doc$
		for i=1 to N:for j=1 to N
			Doc$=if$(rect(j,i)=White->"_","#")
		next
		Doc$={
		}
		next
		cls
		Print #-2,Doc$
		clipboard Doc$
	end sub
}
Ant


direction = 1;
data = SparseArray[{{50, 50} -> -1}, {100, 100}, 1];
NestWhile[
  {[email protected]#, [email protected]#} &@(direction *= (data[[Sequence @@ #]] *= -1) I) + # &,
  {50, 50}, 1 <= [email protected]# <= [email protected]# <= 100 &];
[email protected]


function u = langton_ant(n)
	if nargin<1, n=100; end;
	A = sparse(n,n);	% white
	P = [n/2;n/2];	% Positon
	D = 3;	         % index of direction 0-3
	T = [1,0,-1,0;0,1,0,-1];	% 4 directions
	k = 0;
	while (1)
		k = k+1;
		a = A(P(1),P(2));
		A(P(1),P(2)) = ~a;
		if ( a )
			D = mod(D+1,4);
		else
			D = mod(D-1,4);
		end;
		P = P+T(:,D+1);

		if (~mod(k,100)),spy(A);pause(.1);end;  %display after every 100 interations
	end;
end


import strutils, sequtils

type
  Direction = enum up, right, down, left
  Color = enum white, black

const
  width = 75
  height = 52
  maxSteps = 12_000

var
  m: array[height, array[width, Color]]
  dir = up
  x = width div 2
  y = height div 2

var i = 0
while i < maxSteps and x in 0 ..< width and y in 0 ..< height:
  let turn = m[y][x] == black
  m[y][x] = if m[y][x] == black: white else: black

  dir = Direction((4 + int(dir) + (if turn: 1 else: -1)) mod 4)
  case dir
  of up:    dec y
  of right: dec x
  of down:  inc y
  of left:  inc x

  inc i

for row in m:
  echo map(row, proc(x: Color): string =
    if x == white: "." else: "#").join("")


open Graphics

type dir = North | East | South | West

let turn_left = function
  | North -> West
  | East  -> North
  | South -> East
  | West  -> South

let turn_right = function
  | North -> East
  | East  -> South
  | South -> West
  | West  -> North

let move (x, y) = function
  | North -> x, y + 1
  | East  -> x + 1, y
  | South -> x, y - 1
  | West  -> x - 1, y

let () =
  open_graph "";
  let rec loop (x, y as pos) dir =
    let color = point_color x y in
    set_color (if color = white then black else white);
    plot x y;
    let dir = (if color = white then turn_right else turn_left) dir in
    if not(key_pressed()) then loop (move pos dir) dir
  in
  loop (size_x()/2, size_y()/2) North


#!/usr/bin/ol
(import (otus random!))

(define MAX 65536)  ; should be power of two
; size of game board (should be less than MAX)
(define WIDTH 170)
(define HEIGHT 96)

; helper function
(define (hash x y)
   (let ((x (mod (+ x WIDTH) WIDTH))
         (y (mod (+ y HEIGHT) HEIGHT)))
   (+ (* y MAX) x)))

;; ; helper function
(define directions '(
   (0 . 1) (1 . 0) (0 . -1) (-1 . 0)
))

; ---------------
(import (lib gl2))
(gl:set-window-title "Langton's Ant")

(glShadeModel GL_SMOOTH)
(glClearColor 0.11 0.11 0.11 1)
(glOrtho 0 WIDTH 0 HEIGHT 0 1)

(glPointSize (/ 854 WIDTH))

; generate random field
(gl:set-userdata
   (list->ff (map (lambda (i) (let ((x (rand! WIDTH)) (y (rand! HEIGHT)))
                                 (cons (hash x y) #t))) (iota 1000))))

(define ant (cons
   (rand! WIDTH)
   (rand! HEIGHT)))
(define dir (list (rand! 4))) ; 0, 1, 2, 3

; main game loop
(gl:set-renderer (lambda (mouse)
(let ((generation (gl:get-userdata)))
   (glClear GL_COLOR_BUFFER_BIT)

   ; draw the cells
   (glColor3f 0.2 0.5 0.2)
   (glBegin GL_POINTS)
      (ff-fold (lambda (st key value)
         (glVertex2f (mod key MAX)
                     (div key MAX))
      ) #f generation)
      (glColor3f 0.8 0.2 0.1)
      (glVertex2f (car ant) (cdr ant))
   (glEnd)

   (gl:set-userdata
      (let*((x (car ant))
            (y (cdr ant))
            (generation (case (get generation (hash x y) #f)
                           (#true ; black cell
                              (set-car! dir (mod (+ (car dir) 1) 4))
                              (del generation (hash x y)))
                           (#false
                              (set-car! dir (mod (+ (car dir) 7) 4))
                              (put generation (hash x y) #true)))))
         (set-car! ant (mod (+ x (car (lref directions (car dir)))) WIDTH))
         (set-cdr! ant (mod (+ y (cdr (lref directions (car dir)))) HEIGHT))
         generation))

)))


{$B- Early and safe resolution of  If x <> 0 and 1/x...}
Program LangtonsAnt; Uses CRT;
{Perpetrated by R.N.McLean (whom God preserve), Victoria University, December MMXV.}
 Var AsItWas: record mode: word; ta: word; end;
 Var LastLine,LastCol: byte;

 Procedure Swap(var a,b: integer);	{Oh for a compiler-recognised statement.}
  var t: integer;			{Such as A=:=B;}
   Begin
    t:=a; a:=b; b:=t;
   End;

 var Stepwise: boolean;
 Var Cell: Array[1..80,1..50] of byte;	{The screen is of limited size, alas.}
 Var x,y,Step: integer;		{In the absence of complex numbers,}
 Var dx,dy: integer;		{And also of array action statements.}

 Procedure Croak(Gasp: string);	{Exit message...}
  Begin
   GoToXY(1,12); TextColor(Yellow);	{Reserve line twelve.}
   WriteLn(Gasp,' on step ',Step,' to (',x,',',y,')');
   HALT;
  End;

 Procedure Harken;		{Waits for a keystroke.}
  var ch: char;			{The character. Should really be 16-bit.}
  Begin
   ch:=ReadKey;			{Fancy keys evoke double characters. I don't care.}
   if (ch = 'S') or (ch = 's') then Stepwise:=not Stepwise	{Quick, slow, quick, quick, slow...}
    else if ch = #27 then Croak('ESC!');	{Or perhaps, enough already!}
  End;				{Fancy keys will give a twostep.}
 Procedure Waitabit;		{Slows the action.}
  Begin
   if Stepwise or KeyPressed then Harken;	{Perhaps a change while on the run.}
  End;	{of Waitabit.}

 Procedure Turn(way:integer);	{(dx,dy)*(0,w) = (-w*dy,+w*dx)}
  Begin
   Swap(dx,dy);			{In the absence of complex arithmetic,}
   dx:=-way*dx; dy:=way*dy;	{Do this in two stages.}
  End;

 const Arrow: array[-1..+1,-1..+1] of integer	{Only four entries are of interest.}
  = ((1,27,3),(25,5,24),(7,26,9));		{For the four arrow symbols.}
 Procedure ShowDirection(Enter,How: byte);	{Show one.}
  Begin
   GoToXY(x,LastLine - y + 1);	{(x,y) position, in Cartesian style.}
   TextBackground(Enter);	{The value in Cell[x,y] may have been changed.}
   TextColor(How);
   Writeln(chr(Arrow[dx,dy]));	{Not an ASCII control character, but an arrow symbol.}
   Waitabit;			{Having gone to all this trouble.}
  End;
 Procedure ShowState;		{Special usage for line two of the screen.}
  Begin
   GoToXY(1,2); TextBackground(LightGray); TextColor(Black);
   Write(Step:5,' (',x:2,',',y:2,') ');
   TextColor(Yellow);		{Yellow indicates the direction in mind.}
   Write(chr(Arrow[dx,dy]));	{On *arrival* at a position.}
  End;

 Var i,j: integer;		{Steppers. No whole-array assault as in Cell:=LightGray;}
 var Enter: byte;		{Needed to remember the cell state on arrival.}
 BEGIN
  AsItWas.mode:=LastMode;	{Grr. I might want to save the display content too!}
  AsItWas.ta:=TextAttr;		{Not just its colour and style.}
  TextMode(C80+Font8x8);	{Crazed gibberish gives less unsquare character cells, and 80x50 of them.}
  LastLine:=Hi(WindMax);	{ + 1 omitted, as a write to the last line scrolls the screen up one...}
  LastCol:=Lo(WindMax) + 1;	{Counting starts at zero, even though GoToXY starts with one.}
  x:=LastCol div 2;		{Start somewhere middleish.}
  y:=LastLine div 2;		{Consider (x,y) as being (0,0) for axes.}
  dx:=+1; dy:=0;		{Initial direction.}
  TextBackground(LightGray);	{"White" is not valid for background colour.}
  TextColor(Black);		{This will show up on a light background.}
  ClrScr;			{Here we go.}

  WriteLn('Langton''s Ant, on x = 1:',LastCol,', y = 1:',LastLine);
  ShowState;					{Where we start.}
  WriteLn; TextColor(Black);
  WriteLn('Press a key for each step.');	{Some encouragement.}
  WriteLn('"S" to pause each step or not.');
  WriteLn('ESC to quit.');

  for i:=1 to LastLine do begin GoToXY(x,i); Write('|'); end;			{Draw a y-axis.}
  for i:=1 to LastCol do begin GoToXY(i,LastLine - y + 1); Write('-'); end;	{And x.}
  gotoxy(1,6);	{Can't silence the cursor!}

  for i:=1 to LastCol do	{Prepare the cells.}
   for j:=1 to LastLine do	{One by one.}
    Cell[i,j]:=LightGray;	{Cell:=LightGray. Sigh.}

  Stepwise:=true;		{The action is of interest.}
  for Step:=1 to 12000 do	{Here we go.}
   if (x <= 0) or (x > LastCol) or (y <= 0) or (y > LastCol) then Croak('Out of bounds')
    else				{We're in a cell.}
     begin				{So, inspect it.}
      if Stepwise or (Step mod 10 = 0) then ShowState	{On arrival.}
       else if KeyPressed then Harken;			{If we're not pausing, check for a key poke.}
      Enter:=cell[x,y];					{This is what awaits the feet.}
      if Stepwise then ShowDirection(Enter,Yellow);	{Current direction, about to be changed.}
      case cell[x,y] of					{So, what to do?}
   LightGray: begin Cell[x,y]:=Black;     Turn(-1); end;{White. Make black and turn right.}
       Black: begin Cell[x,y]:=LightGray; Turn(+1); end;{Black. Make white and turn left.}
      end;						{Having decided,}
      if Stepwise then ShowDirection(Enter,Green);	{Show the direction about to be stepped.}
      GoToXY(x,LastLine - y + 1);	{Screen location (column,line) for (x,y)}
      TextBackground(Cell[x,y]);	{Change the state I'm about to leave.}
      Write(' ');			{Foreground colour irrelevant for spaces.}
      x:=x + dx; y:=y + dy;		{Make the step!}
     end;			{On to consider our new position.}

  Croak('Finished');		{That was fun.}

 END.


#!/usr/bin/perl
use strict;
# Perl 5 implementation of Langton's Ant

# Using screen coordinates - 0,0 in upper-left, +X right, +Y down -
# these directions (right, up, left, down) are counterclockwise
# so advance through the array to turn left, retreat to turn right
my @dirs = ( [1,0], [0,-1], [-1,0], [0,1] );
my $size = 100;

# we treat any false as white and true as black, so undef is fine for initial all-white grid
my @plane;
for (0..$size-1) { $plane[$_] = [] };

# start out in approximate middle
my ($x, $y) = ($size/2, $size/2);

# pointing in a random direction
my $dir = int rand @dirs;

my $move;
for ($move = 0; $x >= 0 && $x < $size && $y >= 0 && $y < $size; $move++) {
  # toggle cell's value (white->black or black->white)
  if ($plane[$x][$y] = 1 - ($plane[$x][$y] ||= 0)) {
        # if it's now true (black), then it was white, so turn right
        $dir = ($dir - 1) % @dirs;
  } else {
        # otherwise it was black, so turn left
        $dir = ($dir + 1) % @dirs;
  }
  $x += $dirs[$dir][0];
  $y += $dirs[$dir][1];
}

print "Out of bounds after $move moves at ($x, $y)\n";
for (my $y=0; $y<$size; ++$y) {
  for (my $x=0; $x<$size; ++$x) {
    print $plane[$x][$y] ? '#' : '.';
  }
  print "\n";
}


sequence grid = repeat(repeat(' ',100),100)
integer aX = 50, aY = 50,
        gXY, angle = 1                      -- ' '/'#';  0,1,2,3 = NESW
constant dX = {0,-1,0,1}                    -- (dY = reverse(dX))

while aX>=1 and aX<=100
  and aY>=1 and aY<=100 do
    gXY = grid[aX][aY]
    grid[aX][aY] = 67-gXY           -- ' '<=>'#', aka 32<->35
    angle = mod(angle+2*gXY+3,4)    -- +/-1, ie 0,1,2,3 -> 1,2,3,0 or 3,0,1,2
    aX += dX[angle+1]
    aY += dX[4-angle]
end while

puts(1,join(grid,"\n"))


// INIT AND DEFINITION
define('dest_name', 'output.png'); // destination image
define('width', 100);
define('height', 100);

$x = 50;
$y = 70;
$dir = 0; // 0-up, 1-left, 2-down, 3-right
$field = array();
$step_count = 0;

// LANGTON´S ANT PROCEDURE
while(0 <= $x && $x <= width && 0 <= $y && $y <= height){
	if(isset($field[$x][$y])){
		unset($field[$x][$y]);
		$dir = ($dir + 3) % 4;
	}else{
		$field[$x][$y] = true;
		$dir = ($dir + 1) % 4;
	}
	switch($dir){
		case 0: $y++; break;
		case 1: $x--; break;
		case 2: $y--; break;
		case 3: $x++; break;
	}
	$step_count++;
}
// ARRAY TO IMAGE
$img = imagecreatetruecolor(width, height);
$white = imagecolorallocate($img, 255, 255, 255);
for($x = 0; $x < width; $x++){
	for($y = 0; $y < height; $y++){
		if(isset($field[$x][$y])){
			imagesetpixel($img, $x, $y, $white);
		}
	}
}
// TEXT TO IMAGE
$color = array();
$color[0] = imagecolorallocate($img, 255, 0, 0);
$color[1] = imagecolorallocate($img, 0, 255, 0);
$color[2] = imagecolorallocate($img, 0, 0, 255);
$print_array = array(
	0 => 'Langton`s Ant', 1=>'PHP Version', 2=>'Steps: ' . $step_count
);
foreach($print_array as $key => $line){
	imagestring($img, 3, 3, 3 + $key*11, $line, $color[$key]);
}
// SAVE IMAGE
imagepng($img, dest_name);


(de ant (Width Height X Y)
   (let (Field (make (do Height (link (need Width)))) Dir 0)
      (until (or (le0 X) (le0 Y) (> X Width) (> Y Height))
         (let Cell (nth Field X Y)
            (setq Dir (% (+ (if (car Cell) 1 3) Dir) 4))
            (set Cell (not (car Cell)))
            (case Dir
               (0 (inc 'X))
               (1 (inc 'Y))
               (2 (dec 'X))
               (3 (dec 'Y)) ) ) )
      (prinl "P1")
      (prinl Width " " Height)
      (for Row Field
         (prinl (mapcar '[(X) (if X 1 0)] Row)) ) ) )
(out '(display -) (ant 100 100 50 50))
(bye)


$Size = 100

$G = @()
1..$Size | ForEach { $G += ,( @( 1 ) * $Size ) }

$x = $y = $Size / 2

#  Direction of next move
$Dx = 1
$Dy = 0

#  While we are still on the grid...
While ( $x -ge 0 -and $y -ge 0 -and $x -lt $Size -and $y -lt $Size )
    {
    #  Change direction
    $Dx, $Dy = ( $Dy * $G[$x][$y] ), -( $Dx * $G[$x][$y] )

    #  Change state of current square
    $G[$x][$y] = -$G[$x][$y]

    #  Move forward
    $x += $Dx
    $y += $Dy
    }

#  Convert to strings for output
ForEach ( $Row in $G ) { ( $Row | ForEach { ( ' ', '', '#')[$_+1] } ) -join '' }


/*
 * we use the following conventions:
 * directions 0: up, 1: left, 2: down: 3: right
 *
 * pixel white: true, black: false
 *
 * turn right: true, left: false
 *
 */

// number of iteration steps per frame
// set this to 1 to see a slow animation of each
// step or to 10 or 100 for a faster animation

final int STEP=100;

int x;
int y;
int direction;

void setup() {
  // 100x100 is large enough to show the
  // corridor after about 10000 cycles
  size(100, 100, P2D);

  background(#ffffff);

  x=width/2;
  y=height/2;

  direction=0;
}

int count=0;

void draw() {
  for(int i=0;i<STEP;i++) {
    count++;
    boolean pix=get(x,y)!=-1; //white =-1
    setBool(x,y,pix);

    turn(pix);
    move();

    if(x<0||y<0||x>=width||y>=height) {
      println("finished");
      noLoop();
      break;
    }
  }
  if(count%1000==0) {
    println("iteration "+count);
  }
}

void move() {
  switch(direction) {
    case 0:
      y--;
      break;
    case 1:
      x--;
      break;
    case 2:
      y++;
      break;
    case 3:
      x++;
      break;
  }
}

void turn(boolean rightleft) {
  direction+=rightleft?1:-1;
  if(direction==-1) direction=3;
  if(direction==4) direction=0;
}

void setBool(int x, int y, boolean white) {
  set(x,y,white?#ffffff:#000000);
}


%_______________________________________________________________
% Langtons ant.
:-dynamic
	black/1.

plot_point(Row, Col) :-   % Output a 5x5 black box at R,C
	new(C, box(5,5)), X is Col * 5 - 2, Y is Row * 5 - 2,
	send(C, colour, colour(black)), send(C, fill_pattern, colour(blue)),
	send(C, center(point(X,Y))), send(@win, display, C).
update_win :-  % Make a 500x500 window, find all the black points and plot them
	new(@win, window('Langtons Ant')),
	send(@win, size, size(500,500)), send(@win, open),
	black(Row/Col),plot_point(Row,Col),fail.
update_win.

direction(Row, Col, left) :- black(Row/Col), !, retract(black(Row/Col)).
direction(Row, Col, right):- not(black(Row/Col)), !, assert(black(Row/Col)).

move(_, Row,Col) :- (Row < 0; Col < 0; Row > 99; Col > 99), !.
move(north,Row,Col) :-
	(direction(Row,Col,left), C is Col - 1, !, move(west, Row, C));
	(direction(Row,Col,right), C is Col + 1, !, move(east, Row, C)).
move(south,Row,Col) :-
	(direction(Row,Col,right), C is Col - 1, !, move(west, Row, C));
	(direction(Row,Col,left), C is Col + 1, !, move(east, Row, C)).
move(east,Row,Col) :-
	(direction(Row,Col,right), R is Row + 1, !, move(south, R, Col));
	(direction(Row,Col,left), R is Row - 1, !, move(north, R, Col)).
move(west,Row,Col) :-
	(direction(Row,Col,left), R is Row + 1, !, move(south, R, Col));
	(direction(Row,Col,right), R is Row - 1, !, move(north, R, Col)).

go :-   retractall(black(_)), move(north,49,49), update_win.


#White = $FFFFFF
#Black = 0
#planeHeight = 100
#planeWidth = 100
#canvasID = 0
#windowID = 0
OpenWindow(#windowID, 0, 0, 150, 150, "Langton's ant", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(#canvasID, 25, 25, #planeWidth, #planeHeight)
StartDrawing(CanvasOutput(#canvasID))
  Box(0, 0, #planeWidth, #planeHeight, #White)
StopDrawing()

Define event, quit, ant.POINT, antDirection, antSteps

ant\x = #planeHeight / 2
ant\y = #planeWidth / 2
Repeat
  Repeat
    event = WindowEvent()
    If event = #PB_Event_CloseWindow
      quit = 1
      event = 0
    EndIf
  Until event = 0

  StartDrawing(CanvasOutput(#canvasID))
    Select Point(ant\x, ant\y)
      Case #Black
        Plot(ant\x, ant\y, #White)
        antDirection = (antDirection + 1) % 4 ;turn left
      Case #White
        Plot(ant\x, ant\y, #Black)
        antDirection = (antDirection - 1 + 4) % 4 ;turn right
    EndSelect
  StopDrawing()

  Select antDirection
    Case 0 ;up
      ant\y - 1
    Case 1 ;left
      ant\x - 1
    Case 2 ;down
      ant\y + 1
    Case 3 ;right
      ant\x + 1
  EndSelect
  antSteps + 1

  If ant\x < 0 Or ant\x >= #planeWidth Or ant\y < 0 Or ant\y >= #planeHeight
    MessageRequester("Langton's ant status", "Out of bounds after " + Str(antSteps) + " steps.")
    quit = 1
  EndIf

  Delay(10) ;control animation speed and avoid hogging CPU
Until quit = 1


"""Langton's ant implementation."""
from enum import Enum, IntEnum

class Dir(IntEnum):
    """Possible directions."""

    UP = 0
    RIGHT = 1
    DOWN = 2
    LEFT = 3

class Color(Enum):
    """Possible colors."""

    WHITE = " "
    BLACK = "#"

def invert_color(grid, x, y):
    """Invert the color of grid at x, y coordinate."""
    if grid[y][x] == Color.BLACK:
        grid[y][x] = Color.WHITE
    else:
        grid[y][x] = Color.BLACK

def next_direction(grid, x, y, direction):
    """Compute next direction according to current position and direction."""
    if grid[y][x] == Color.BLACK:
        turn_right = False
    else:
        turn_right = True
    direction_index = direction.value
    if turn_right:
        direction_index = (direction_index + 1) % 4
    else:
        direction_index = (direction_index - 1) % 4
    directions = [Dir.UP, Dir.RIGHT, Dir.DOWN, Dir.LEFT]
    direction = directions[direction_index]
    return direction

def next_position(x, y, direction):
    """Compute next position according to direction."""
    if direction == Dir.UP:
        y -= 1
    elif direction == Dir.RIGHT:
        x -= 1
    elif direction == Dir.DOWN:
        y += 1
    elif direction == Dir.LEFT:
        x += 1
    return x, y

def print_grid(grid):
    """Display grid."""
    print(80 * "#")
    print("\n".join("".join(v.value for v in row) for row in grid))

def ant(width, height, max_nb_steps):
    """Langton's ant."""
    grid = [[Color.WHITE] * width for _ in range(height)]
    x = width // 2
    y = height // 2
    direction = Dir.UP

    i = 0
    while i < max_nb_steps and 0 <= x < width and 0 <= y < height:
        invert_color(grid, x, y)
        direction = next_direction(grid, x, y, direction)
        x, y = next_position(x, y, direction)
        print_grid(grid)
        i += 1

if __name__ == "__main__":
    ant(width=75, height=52, max_nb_steps=12000)


#lang racket

;; contracts allow us to describe expected behaviour of funcitons
(define direction/c (or/c 'u 'r 'l 'd))
(define turn/c (-> direction/c direction/c))
(define grid/c (hash/c integer? (hash/c integer? boolean?)))
(define-struct/contract ant ([d direction/c] [x integer?] [y integer?]))

(define/contract (turn-right dir) turn/c
  (case dir ((u) 'r) ((d) 'l) ((r) 'd) ((l) 'u)))

(define/contract (turn-left dir) turn/c
  (case dir ((u) 'l) ((d) 'r) ((r) 'u) ((l) 'd)))

(define/contract (move d x y)
  (-> direction/c integer? integer? (list/c direction/c integer? integer?))
  (list
   d
   (+ x (case d ((l) -1) ((r) 1) (else 0)))
   (+ y (case d ((u) -1) ((d) 1) (else 0)))))

(define/contract (move-ant d a) (-> direction/c ant? ant?)
  (apply make-ant (move d (ant-x a) (ant-y a))))

(define/contract (langton a grid) (-> ant? grid/c grid/c)
  (let ((ax (ant-x a)) (ay (ant-y a)))
    (if (and (<= 1 ax 100) (<= 1 ay 100))
        (let* ((grid-row (hash-ref grid ay hash))
               (cell-black? (hash-ref grid-row ax #f)))
          (langton
           (move-ant ((if cell-black? turn-left turn-right) (ant-d a)) a)
           (hash-set grid ay (hash-set grid-row ax (not cell-black?)))))
        grid)))

(define/contract (show-grid/text grid) (-> grid/c void?)
  (for* ; for* allows us to refer to y in rw
      ((y (in-range 1 101))
       (rw (in-value (hash-ref grid y #f)))
       #:when rw        ; if there is no row, the ant never visisted it
       #:when (newline) ; when can be used simply for its side effect
       (x (in-range 1 101)))
    (case (hash-ref rw x #\?)
      ((#\?) (display #\space)) ; distingush between "ant-visited white" vs. pure white
      ((#f)  (display #\:))     ; little anty footprints left
      ((#t)  (display #\#)))))

(show-grid/text (langton (make-ant 'u 50 50) (hash)))

(require 2htdp/image)
(define/contract (show-grid/png grid) (-> grid/c image?)
  (for*/fold
      ((scn (empty-scene 408 408)))
       ((y (in-range 1 101))
       (rw (in-value (hash-ref grid y #f)))
       #:when rw        ; if there is no row, the ant never visisted it
       (x (in-range 1 101)))
    (case (hash-ref rw x #\?)
      ((#\?) scn) ; distingush between "ant-visited white" vs. pure white
      ((#f)  (place-image (circle 2 "outline" "gray") (* x 4) (* y 4) scn))     ; little anty footprints left
      ((#t)  (place-image (circle 2 "solid" "black")  (* x 4) (* y 4) scn)))))
(show-grid/png (langton (make-ant 'u 50 50) (hash)))


constant @vecs = [1,0,1], [0,-1,1], [-1,0,1], [0,1,1];
constant @blocky = ' ▘▝▀▖▌▞▛▗▚▐▜▄▙▟█'.comb;
constant $size = 100;
enum Square <White Black>;
my @plane = [White xx $size] xx $size;
my ($x, $y) = $size/2, $size/2;
my $dir = @vecs.keys.pick;
my $moves = 0;
loop {
    given @plane[$x][$y] {
        when :!defined { last }
        when White { $dir--; $_ = Black; }
        when Black { $dir++; $_ = White; }
    }
    ($x,$y,$moves) »+=« @vecs[$dir %= @vecs];
}
say "Out of bounds after $moves moves at ($x, $y)";
for 0,2,4 ... $size - 2 -> $y {
    say join '', gather for 0,2,4 ... $size - 2 -> $x {
        take @blocky[ 1 * @plane[$x][$y]
                    + 2 * @plane[$x][$y+1]
                    + 4 * @plane[$x+1][$y]
                    + 8 * @plane[$x+1][$y+1] ];
    }
}


/*REXX program implements Langton's ant walk and displays the ant's path (finite field).*/
parse arg dir char seed .                        /*obtain optional arguments from the CL*/
if datatype(seed, 'W')   then call random ,,seed /*Integer? Then use it as a RANDOM SEED*/
if  dir=='' |  dir==","  then dir= random(1, 4)  /*ant is facing a random direction,    */
if char=='' | char==","  then char= '#'          /*binary colors:   0≡white,  1≡black.  */
parse value scrSize() with sd          sw .      /*obtain the terminal's depth and width*/
                           sd= sd -6;  sw= sw -1 /*adjust for     "      useble area.   */
   xHome= 1000000;      yHome= 1000000           /*initially in the middle of nowhere.  */
x= xHome;            y= yHome                    /*start ant's walk in middle of nowhere*/
$.= 1  ;  $.0= 4 ;   $.2= 2 ;   $.3= 3;   $.4= 4 /* 1≡north   2≡east   3≡south   4≡west.*/
minX= x;  minY= y;   maxX= x;   maxY= y          /*initialize the min/max values for X,Y*/
@.= 0                                            /*the universe  (walk field)  is white.*/
     do #=1  until (maxX-minY>sw)|(maxY-minY>sd) /*is the path out─of─bounds for screen?*/
     black= @.x.y;                 @.x.y= \@.x.y /*invert (flip)  ant's cell color code.*/
     if black  then dir= dir - 1                 /*if cell color was black,  turn  left.*/
               else dir= dir + 1                 /* "   "    "    "  white,  turn right.*/
     dir= $.dir                                  /*$ array handles/adjusts under & over.*/
               select                            /*ant walks the direction it's facing. */
               when dir==1  then y= y + 1        /*is ant walking north?  Then go up.   */
               when dir==2  then x= x + 1        /* "  "     "     east?    "  "  right.*/
               when dir==3  then y= y - 1        /* "  "     "    south?    "  "  down. */
               when dir==4  then x= x - 1        /* "  "     "     west?    "  "  left. */
               end   /*select*/                  /*the  DIRection  is always normalized.*/
     minX= min(minX, x);    maxX= max(maxX, x)   /*find the minimum and maximum of  X.  */
     minY= min(minY, y);    maxY= max(maxY, y)   /*  "   "     "     "     "     "  Y.  */
     end   /*steps*/                             /* [↑]  ant walks  hither and thither. */
                                                 /*finished walking, it's out-of-bounds.*/
say center(" Langton's ant walked "     #     ' steps ', sw, "─")
@.xHome.yHome= '█'                               /*show the ant's initial starting point*/
@.x.y=         '∙'                               /*show where the ant went out─of─bounds*/
                                                 /* [↓]  show Langton's ant's trail.    */
     do    y=maxY  to minY  by -1;  _=           /*display a single  row  of cells.     */
        do x=minX  to maxX;         _=_ || @.x.y /*build a cell row for the display.    */
        end   /*x*/                              /* [↓]  strip trailing blanks from line*/
     _= strip( translate(_, char, 10),  'T')     /*color the cells:   black  or  white. */
     if _\==''  then say _                       /*display line (strip trailing blanks).*/
     end      /*y*/                              /*stick a fork in it,  we're all done. */


load "guilib.ring"
load "stdlib.ring"

new qapp
        {
        win1 = new qwidget() {
                   setwindowtitle("drawing using qpainter")
                   setgeometry(100,100,500,500)
                   label1 = new qlabel(win1) {
                             setgeometry(10,10,400,400)
                             settext("")
                  }
                  new qpushbutton(win1) {
                         setgeometry(200,400,100,30)
                         settext("draw")
                         setclickevent("draw()")
                  }
                  show()
         }
         exec()
         }

func draw
        p1 = new qpicture()
             color = new qcolor() {
             setrgb(0,0,255,255)
        }
        pen = new qpen() {
                  setcolor(color)
                  setwidth(1)
        }
        new qpainter() {
               begin(p1)
               setpen(pen)

        fieldsize=100
        field = newlist(fieldsize,fieldsize)
        x=fieldsize/2
        y=fieldsize/2
        d=0
        while x<=fieldsize and x>=0 and y<=fieldsize and y>=0
                if field[x][y]=0  field[x][y]=1 d-=1 else field[x][y]=0 d+=1 ok
                drawpoint(x*2, y*2)
                d=(d+4) % 4
                switch d
                        on 0 y+=1
                        on 1 x+=1
                        on 2 y-=1
                        on 3 x-=1
                off
        end

        endpaint()
        }
        label1 { setpicture(p1) show() }


class Ant

  class OutOfBoundsException < StandardError; end

  class Plane
    def initialize(x, y)
      @size_x, @size_y = x, y
      @cells = Array.new(y) {Array.new(x, :white)}
    end

    def white?(px, py)
      @cells[py][px] == :white
    end

    def toggle_colour(px, py)
      @cells[py][px] = (white?(px, py) ? :black : :white)
    end

    def check_bounds(px, py)
      unless (0 <= px and px < @size_x) and (0 <= py and py < @size_y)
        raise OutOfBoundsException, "(#@size_x, #@size_y)"
      end
    end

    def to_s
      @cells.collect {|row|
        row.collect {|cell| cell == :white ? "." : "#"}.join + "\n"
      }.join
    end
  end

  dir_move = [[:north, [0,-1]], [:east, [1,0]], [:south, [0,1]], [:west, [-1,0]]]
  Move = Hash[dir_move]
  directions = dir_move.map{|dir, move| dir}       # [:north, :east, :south, :west]
  Right = Hash[ directions.zip(directions.rotate).to_a ]
  Left  = Right.invert

  def initialize(size_x, size_y, pos_x=size_x/2, pos_y=size_y/2)
    @plane = Plane.new(size_x, size_y)
    @pos_x, @pos_y = pos_x, pos_y
    @direction = :south
    @plane.check_bounds(@pos_x, @pos_y)
  end

  def run
    moves = 0
    loop do
      begin
        moves += 1
        move
      rescue OutOfBoundsException
        break
      end
    end
    moves
  end

  def move
    @plane.toggle_colour(@pos_x, @pos_y)
    advance
    if @plane.white?(@pos_x, @pos_y)
      @direction = Right[@direction]
    else
      @direction = Left[@direction]
    end
  end

  def advance
    dx, dy = Move[@direction]
    @pos_x += dx
    @pos_y += dy
    @plane.check_bounds(@pos_x, @pos_y)
  end

  def position
    "(#@pos_x, #@pos_y)"
  end

  def to_s
    @plane.to_s
  end
end

#
# the simulation
#
ant = Ant.new(100, 100)
moves = ant.run
puts "out of bounds after #{moves} moves: #{ant.position}"
puts ant


dim plane(100,100)
x  = 50: y = 50: minY = 100

while (x>0) and (x<100) and (y>0) and (y<100)
 if plane(x,y) then
   nxt = nxt - 1
   if nxt < 1 then nxt = 4
  else
   nxt = nxt + 1
   if nxt > 4 then nxt = 1
 end if

 x          = x + (nxt = 2) - (nxt = 4)
 y          = y + (nxt = 3) - (nxt = 1)
 plane(x,y) = (plane(x,y) <> 1)
 minY       = min(y,minY)          ' find lowest and
 maxY       = max(y,maxY)          '  highest y to prevent printing blank lines
wend

graphic #g, 100,100
for y = minY to maxY
  for x = 1 to 100
   print chr$((plane(x,y)*3) + 32);
     if plane(x,y) = 1 then  #g "color green ; set "; x; " "; y else #g "color blue ; set "; x; " "; y
  next x
  print y
next y
render #g
#g "flush""


struct Ant {
    x: usize,
    y: usize,
    dir: Direction
}

#[derive(Clone,Copy)]
enum Direction {
    North,
    East,
    South,
    West
}

use Direction::*;

impl Ant {
    fn mv(&mut self, vec: &mut Vec<Vec<u8>>) {
        let pointer = &mut vec[self.y][self.x];
        //change direction
        match *pointer {
            0 => self.dir = self.dir.right(),
            1 => self.dir = self.dir.left(),
            _ => panic!("Unexpected colour in grid")
        }
        //flip colour
        //if it's 1 it's black
        //if it's 0 it's white
        *pointer ^= 1;

        //move direction
        match self.dir {
            North => self.y -= 1,
            South => self.y += 1,
            East => self.x += 1,
            West => self.x -= 1,
        }

    }
}

impl Direction {
    fn right(self) -> Direction {
        match self {
            North => East,
            East => South,
            South => West,
            West => North,
        }
    }

    fn left(self) -> Direction {
        //3 rights equal a left
        self.right().right().right()
    }
}

fn main(){
    //create a 100x100 grid using vectors
    let mut grid: Vec<Vec<u8>> = vec![vec![0; 100]; 100];
    let mut ant = Ant {
        x: 50, y: 50, dir: Direction::North
    };

    while ant.x < 100 && ant.y < 100 {
        ant.mv(&mut grid);
    }
    for each in grid.iter() {
        //construct string
        //using iterator methods to quickly convert the vector
        //to a string
        let string = each.iter()
                         .map(|&x| if x == 0 { " " } else { "#" })
                         .fold(String::new(), |x, y| x+y);
        println!("{}", string);
    }
}


class Langton(matrix:Array[Array[Char]], ant:Ant) {
  import Langton._
  val rows=matrix.size
  val cols=matrix(0).size

  def isValid = 0 <= ant.row && ant.row < cols && 0 <= ant.col  && ant.col < rows
  def isBlack=matrix(ant.row)(ant.col)==BLACK
  def changeColor(c:Char)={matrix(ant.row)(ant.col)=c; matrix}

  def evolve():Langton={
    val (newCol, newAnt)=if(isBlack) (WHITE, ant.turnLeft) else (BLACK, ant.turnRight)
    new Langton(changeColor(newCol), newAnt.move)
  }
  override def toString()=matrix map (_.mkString("")) mkString "\n"
}

case class Ant(row:Int, col:Int, d:Int=0) {
  def turnLeft=Ant(row,col,(d-1)&3)
  def turnRight=Ant(row,col,(d+1)&3)
  def move=d match {
    case 0 => Ant(row-1,col,d)	// north
    case 1 => Ant(row,col+1,d)	// east
    case 2 => Ant(row+1,col,d)	// south
    case 3 => Ant(row,col-1,d)	// west
  }
}

object Langton {
  val BLACK='#'
  val WHITE='.'
  def apply(x:Int=100, y:Int=100)=new Langton(Array.fill(y, x)(WHITE), Ant(x>>>1, y>>>1, 0))

  def main(args: Array[String]): Unit = {
    var l=Langton(100,100)
    var moves=0
    while (l.isValid) {
      moves += 1
      l=l.evolve
    }
    println("Out of bounds after "+moves+" moves")
    println(l)
  }
}


grid_size=100;                              //side length of the square grid
ant_pos=round([grid_size/2 grid_size/2]);   //ant's initial position at center of grid
head_direction='W';                         //ant's initial direction can be either
                                            //'N' north, 'S' south, 'E' east, or 'W' west

grid=~zeros(grid_size,grid_size)    //blank grid
col=[];                             //cell color handler
next_step=%T;                       //step flag
i=0;                                //step counter

while next_step

    col=grid(ant_pos(1),ant_pos(2));    //get cell color

    if col then                         //if white cell
        grid(ant_pos(1),ant_pos(2))=~grid(ant_pos(1),ant_pos(2));  //switch color
        if head_direction=='N' then     //if head to N
            head_direction='E';         //turn right to E
            ant_pos(2)=ant_pos(2)+1;    //step forward

        elseif head_direction=='E' then //if head to E
            head_direction='S';         //turn right to S
            ant_pos(1)=ant_pos(1)+1;    //step forward

        elseif head_direction=='S' then //if head to S
            head_direction='W';         //turn right to W
            ant_pos(2)=ant_pos(2)-1;    //step forward

        elseif head_direction=='W' then //if head to W
            head_direction='N';         //turn right to N
            ant_pos(1)=ant_pos(1)-1;    //step forward
        end
    else                                //if black cell
        grid(ant_pos(1),ant_pos(2))=~grid(ant_pos(1),ant_pos(2));  //switch color
        if head_direction=='N' then     //if head to N
            head_direction='W';         //turn left to E
            ant_pos(2)=ant_pos(2)-1;    //step foward

        elseif head_direction=='W' then //if head to W
           head_direction='S';          //turn left to S
            ant_pos(1)=ant_pos(1)+1;    //step forward

        elseif head_direction=='S' then //if head to S
            head_direction='E';         //turn left to E
            ant_pos(2)=ant_pos(2)+1;    //step forward

        elseif head_direction=='E' then //if head to E
            head_direction='N';         //turn left to N
            ant_pos(1)=ant_pos(1)-1;    //step forward
        end
    end

    i=i+1;

    if ant_pos(1)<1 | ant_pos(1)>100 | ant_pos(2)<0 | ant_pos(2)>100 then   //check ant's position
        disp("Out of bounds after "+string(i)+" steps");
        next_step=~next_step;                                               //break loop if out of bounds
    end
end

ascii_grid=string(zeros(grid));     //create grid of chars to display
                                    //on the console
for a=1:length(grid)
    if grid(a) then
        ascii_grid(a)=" ";          //blank space if cell is white
    else
        ascii_grid(a)="#";          //# if cell is black
    end
end

disp(ascii_grid);


$ include "seed7_05.s7i";

const type: direction is new enum UP, RIGHT, DOWN, LEFT end enum;

const proc: main is func
  local
    const integer: width is 75;
    const integer: height is 52;
    var array array boolean: m is height times width times FALSE;
    var direction: dir is UP;
    var integer: x is width div 2;
    var integer: y is height div 2;
  begin
    while x in {1 .. width} and y in {1 .. height} do
      dir := direction conv ((ord(dir) + 2 * ord(m[y][x]) - 1) mod 4);
      m[y][x] := not m[y][x];
      case dir of
        when {UP}:    decr(y);
        when {RIGHT}: decr(x);
        when {DOWN}:  incr(y);
        when {LEFT}:  incr(x);
      end case;
    end while;
    for key x range m do
      for y range 1 to width do
        write(".#"[succ(ord(m[x][y]))]);
      end for;
      writeln;
    end for;
  end func;


define dirs = [[1,0], [0,-1], [-1,0], [0,1]]
define size = 100

enum |White, Black|
var plane = size.of { size.of (White) }

var (x, y) = ([size >> 1] * 2)...
var dir = dirs.len.irand

var moves = 0
loop {
    (x >= 0) && (y >= 0) && (x < size) && (y < size) || break

    given (plane[x][y]) {
        when (White) { dir--; plane[x][y] = Black }
        when (Black) { dir++; plane[x][y] = White }
    }

    ++moves
    [[\x, \y], dirs[dir %= dirs.len]].zip {|a,b| *a += b }
}

say "Out of bounds after #{moves} moves at (#{x}, #{y})"
plane.map{.map {|square| square == Black ? '#' : '.' }}.each{.join.say}


import Foundation

let WIDTH = 100
let HEIGHT = 100

struct Point {
    var x:Int
    var y:Int
}

enum Direction: Int {
    case North = 0, East, West, South
}

class Langton {
    let leftTurn = [Direction.West, Direction.North, Direction.South, Direction.East]
    let rightTurn = [Direction.East, Direction.South, Direction.North, Direction.West]
    let xInc = [0, 1,-1, 0]
    let yInc = [-1, 0, 0, 1]
    var isBlack:[[Bool]]
    var origin:Point
    var antPosition = Point(x:0, y:0)
    var outOfBounds = false
    var antDirection = Direction.East

    init(width:Int, height:Int) {
        self.origin = Point(x:width / 2, y:height / 2)
        self.isBlack = Array(count: width, repeatedValue: Array(count: height, repeatedValue: false))
    }

    func moveAnt() {
        self.antPosition.x += xInc[self.antDirection.rawValue]
        self.antPosition.y += yInc[self.antDirection.rawValue]
    }

    func step() -> Point {
        if self.outOfBounds {
            println("Ant tried to move while out of bounds.")
            exit(0)
        }

        var ptCur = Point(x:self.antPosition.x + self.origin.x, y:self.antPosition.y + self.origin.y)
        let black = self.isBlack[ptCur.x][ptCur.y]
        let direction = self.antDirection.rawValue

        self.antDirection = (black ? self.leftTurn : self.rightTurn)[direction]

        self.isBlack[ptCur.x][ptCur.y] = !self.isBlack[ptCur.x][ptCur.y]

        self.moveAnt()
        ptCur = Point(x:self.antPosition.x + self.origin.x, y:self.antPosition.y + self.origin.y)
        self.outOfBounds =
            ptCur.x < 0 ||
            ptCur.x >= self.isBlack.count ||
            ptCur.y < 0 ||
            ptCur.y >= self.isBlack[0].count

        return self.antPosition
    }
}

let ant = Langton(width: WIDTH, height: HEIGHT)
while !ant.outOfBounds {
    ant.step()
}

for row in 0 ..< WIDTH {
    for col in 0 ..< HEIGHT {
        print(ant.isBlack[col][row] ? "#" : " ")
    }
    println()
}


package require Tk

proc step {workarea} {
    global x y dir
    if {[lindex [$workarea get $x $y] 0]} {
	$workarea put black -to $x $y
	if {[incr dir] > 3} {set dir 0}
    } else {
	$workarea put white -to $x $y
	if {[incr dir -1] < 0} {set dir 3}
    }
    switch $dir {
	0 {incr x}
	1 {incr y}
	2 {incr x -1}
	3 {incr y -1}
    }
    expr {$x < 0 || $x >= [image width $workarea] || $y < 0 || $y >= [image height $workarea]}
}

image create photo antgrid -width 100 -height 100
pack [label .l -image antgrid]
antgrid put white -to 0 0 99 99
set x [set y 50]
set dir 0

while 1 {
    update
    if {[step antgrid]} break
}

# Produce output in file
antgrid write ant.gif -format gif


PROGRAM:LANT
:ClrDraw
:0→N
:47→A
:31→B
:90→Θ
:Repeat getKey
:If pxl-Test(B,A)
:Then
:Θ+90→Θ
:Else
:Θ-90→Θ
:End
:Pxl-Change(B,A)
:A+cos(Θ°)→A
:B+sin(Θ°)→B
:N+1→N
:End


Option Explicit

Sub Ant()
Dim TablDatas(1 To 200, 1 To 256) As String, sDir As String, sFile As String, Str As String
Dim ColA As Integer, LigA As Long, ColF As Integer, LigF As Long, i As Long, j As Integer, Num As Long
Dim Top As Boolean, Left As Boolean, Bottom As Boolean, Right As Boolean

    'init variables
    Top = True
    LigF = 80
    ColF = 50
    For i = 1 To 200
        For j = 1 To 256
            TablDatas(i, j) = " "
        Next
    Next
    'directory
    sDir = "C:\Users\yourname\Desktop\"
    'name txt file
    sFile = "Langton_Ant.txt"

    'start
    For i = 1 To 15000
        LigA = LigF
        ColA = ColF
        If LigA = 1 Or ColA = 1 Or ColA = 256 Or LigA = 200 Then GoTo Fin
        If TablDatas(LigA, ColA) = " " Then
            TablDatas(LigA, ColA) = "#"
            Select Case True
                Case Top: Top = False: Left = True: LigF = LigA: ColF = ColA - 1
                Case Left: Left = False: Bottom = True: LigF = LigA + 1: ColF = ColA
                Case Bottom: Bottom = False: Right = True: LigF = LigA: ColF = ColA + 1
                Case Right: Right = False: Top = True: LigF = LigA - 1: ColF = ColA
            End Select
        Else
            TablDatas(LigA, ColA) = " "
            Select Case True
                Case Top: Top = False: Right = True: LigF = LigA: ColF = ColA + 1
                Case Left: Left = False: Top = True: LigF = LigA - 1: ColF = ColA
                Case Bottom: Bottom = False: Left = True: LigF = LigA: ColF = ColA - 1
                Case Right: Right = False: Bottom = True: LigF = LigA + 1: ColF = ColA
            End Select
        End If
    Next i
    'result in txt file
    Num = FreeFile
    Open sDir & sFile For Output As #Num
    For i = 1 To UBound(TablDatas, 1)
        Str = vbNullString
        For j = 1 To UBound(TablDatas, 2)
            Str = Str & TablDatas(i, j)
        Next j
        Print #1, Str
    Next i
    Close #Num
    Exit Sub
Fin:
MsgBox "Stop ! The ant is over limits."
End Sub


" return character under cursor
function! CurrChar()
   return matchstr(getline('.'), '\%' . col('.') . 'c.')
endfunction

" draw all-white grid (arguments are characters to use for white and black)
function! LangtonClear(white, black)
  let l:bufname = 'langtons.ant'
  if bufexists(l:bufname)
    let l:winnum = bufwinnr(l:bufname)
    if l:winnum == -1
      execute 'sbuffer ' . bufnr(l:bufname)
    else
      execute l:winnum . 'wincmd w'
    endif
  else
    execute 'new ' . l:bufname
  end
  execute '1,$ delete _'
  call append(0, repeat(a:white,100))
  execute 'normal! 1Gyy99p'
  goto 5100
  let b:directions = [ 'k', 'l', 'j', 'h' ]
  let b:direction = 0
  let b:white = a:white
  let b:black = a:black
endfunction

" move the ant one step
function! LangtonStep()
  let l:ch = CurrChar()
  if l:ch == b:white
    let l:ch = b:black
    let b:direction = (b:direction  + 1) % 4
  elseif l:ch == b:black
    let l:ch = b:white
    let b:direction = (b:direction  + 3) % 4
  endif
  execute 'normal! r'.l:ch.b:directions[b:direction]
endfunction

" run until we hit the edge
" optional arguments specify white and black characters;
" default . and @, respectively.
function! RunLangton(...)
  let l:white='.'
  let l:black='@'
  if a:0 > 0
    let l:white=a:1
    if a:0 > 1
      let l:black=a:2
    endif
  endif
  call LangtonClear(l:white, l:black)
  while 1
    let l:before = getpos('.')
    call LangtonStep()
    let l:after = getpos('.')
    if l:before == l:after
      break
    endif
  endwhile
endfunction


var width  = 75
var height = 52
var maxSteps = 12000

var up    = 0
var right = 1
var down  = 2
var left  = 3
var direction = [up, right, down, left]

var white = 0
var black = 1

var x = (width/2).floor
var y = (height/2).floor
var m = List.filled(height, null)
for (i in 0...height) m[i] = List.filled(width, 0)
var dir = up
var i = 0
while (i < maxSteps && 0 <= x && x < width && 0 <= y && y < height) {
    var turn = (m[y][x] == black)
    var index = (dir + (turn ? 1 : -1)) & 3
    dir = direction[index]
    m[y][x] = (m[y][x] == black) ? white : black
    if (dir == up) {
        y = y - 1
    } else if (dir == right) {
        x = x - 1
    } else if (dir == down) {
        y = y + 1
    } else {
        x = x + 1
    }
    i = i + 1
}
for (j in 0...height) {
    for (k in 0...width) System.write((m[j][k] == white) ? "." : "#")
    System.print()
}


include c:\cxpl\codes;          \intrinsic 'code' declarations
int X, Y, Dir;
[SetVid($13);                   \set 320x200 graphic video mode
X:= 50;  Y:= 50;  Dir:= 0;      \start in middle facing east
repeat  if ReadPix(X,Y) then    \(black and white are reversed)
                [Dir:= Dir-1;\left\   Point(X,Y, 0\black\)]
        else    [Dir:= Dir+1;\right\  Point(X,Y,$F\white\)];
        case Dir & 3 of
          0:    X:= X+1;        \east
          1:    Y:= Y+1;        \south
          2:    X:= X-1;        \west
          3:    Y:= Y-1         \north
        other   [];
until   X<0 ! X>=100 ! Y<0 ! Y>=100;
X:= ChIn(1);                    \wait for keystroke
SetVid(3);                      \restore normal text mode
]


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 east
do{
   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"));


F knuth_shuffle(&x)
   L(i) (x.len - 1 .< 0).step(-1)
      V j = random:(0..i)
      swap(&x[i], &x[j])

V x = Array(0..9)
knuth_shuffle(&x)
print(‘shuffled: ’x)


*        Knuth shuffle             02/11/2015
KNUTHSH  CSECT
         USING  KNUTHSH,R15
         LA     R6,1               i=1
LOOPI1   C      R6,=A(CARDS)       do i=1 to cards
         BH     ELOOPI1
         STC    R6,PACK(R6)        pack(i)=i
         LA     R6,1(R6)           i=i+1
         B      LOOPI1
ELOOPI1  LA     R7,CARDS           n=cards
LOOPN    C      R7,=F'2'           do n=cards to 2 by -1
         BL     ELOOPN
         L      R5,RANDSEED        r5=seed
         M      R4,=F'397204094'   r4r5=seed*const
         D      R4,=X'7FFFFFFF'    r5=r5 div (2^31-1)
         ST     R4,RANDSEED        r4=r5 mod (2^31-1); seed=r4
         LR     R5,R4              r5=seed
         LA     R4,0               r4=0
         DR     R4,R7              r5=seed div n; r4=seed mod n
         LA     R9,1(R4)           r2=randint(n)+1 [1:n]
         LA     R4,PACK(R7)        @pack(n)
         LA     R5,PACK(R9)        @pack(nw)
         MVC    TMP,0(R4)          tmp=pack(n)
         MVC    0(1,R4),0(R5)      pack(n)=pack(nw)
         MVC    0(1,R5),TMP        pack(nw)=tmp
         BCTR   R7,0               n=n-1
         B      LOOPN
ELOOPN   LA     R6,1               i=1
         LA     R8,PG              [email protected]
LOOPI2   C      R6,=A(CARDS)       do i=1 to cards
         BH     ELOOPI2
         XR     R2,R2              r2=0
         IC     R2,PACK(R6)        pack(i)
         XDECO  R2,XD              edit pack(i)
         MVC    0(3,R8),XD+9       output pack(i)
         LA     R8,3(R8)           pgi=pgi+3
         LA     R6,1(R6)           i=i+1
         B      LOOPI2
ELOOPI2  XPRNT  PG,80              print buffer
         XR     R15,R15            set return code
         BR     R14                return to caller
CARDS    EQU    20                 number of cards
PACK     DS     (CARDS+1)C         pack of cards
TMP      DS     C                  temp for swap
PG       DC     CL80' '            buffer
XD       DS     CL12               to decimal
RANDSEED DC     F'16807'           running seed
         YREGS
         END    KNUTHSH


define sysRandom $fe
define tempMask $ff
define range $00
define tempX $01
define tempY $02
define tempRandIndex $03
define temp $04
CreateIdentityTable:
    txa
    sta $0200,x
    sta $1000,x
    inx
    bne CreateIdentityTable
;creates a sorted array from 0-255 starting at addr $1000
;also creates another one at $0200 for our test input

lda #1
sta range

ConstrainRNG:
ldx #255
;max range of RNG
lda range
bne outerloop
jmp end

outerloop:
cpx range
bcc continue	;if X >= range, we need to lower X
pha
  txa
  sta tempX

  lsr
  cmp range
  bcc continue2

  tax
pla
jmp outerloop

continue2:
pla
ldx tempX

continue:
ldy range

KnuthShuffle:
lda sysRandom
and $1000,x	;and with range constrictor
tay

lda $0200,y
sty tempRandIndex
sta temp
ldy range
lda $0200,y
pha
    lda temp
    sta $0200,y
pla
ldy tempRandIndex
sta $0200,y
dec range
jmp ConstrainRNG

end:
brk


/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program knuthshuffle64.s   */

/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
/*********************************/
/* Initialized data              */
/*********************************/
.data
sMessResult:      .asciz "Value  : @ \n"
szCarriageReturn: .asciz "\n"

.align 4
TableNumber:         .quad   1,2,3,4,5,6,7,8,9,10
                     .equ NBELEMENTS, (. - TableNumber) / 8
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConversion:         .skip 30
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                                        // entry of program
    ldr x0,qAdrTableNumber                   // address number table
    mov x1,NBELEMENTS                       // number of élements
    bl knuthShuffle
    ldr x2,qAdrTableNumber
    mov x3,0
1:                                           // loop display table
    ldr x0,[x2,x3,lsl 3]
    ldr x1,qAdrsZoneConversion               // display value
    bl conversion10S                          // call function
    ldr x0,qAdrsMessResult
    ldr x1,qAdrsZoneConversion
    bl strInsertAtCharInc
    bl affichageMess                         // display message
    add x3,x3,1
    cmp x3,NBELEMENTS - 1
    ble 1b

    ldr x0,qAdrszCarriageReturn
    bl affichageMess
    /*    2e shuffle             */
    ldr x0,qAdrTableNumber                   // address number table
    mov x1,NBELEMENTS                        // number of élements
    bl knuthShuffle
    ldr x2,qAdrTableNumber
    mov x3,0
2:                                           // loop display table
    ldr x0,[x2,x3,lsl 3]
    ldr x1,qAdrsZoneConversion               // display value
    bl conversion10S                         // call function
    ldr x0,qAdrsMessResult
    ldr x1,qAdrsZoneConversion
    bl strInsertAtCharInc
    bl affichageMess                         // display message
    add x3,x3,1
    cmp x3,NBELEMENTS - 1
    ble 2b

100:                                         // standard end of the program
    mov x0,0                                 // return code
    mov x8,EXIT                              // request to exit program
    svc 0                                    // perform the system call

qAdrszCarriageReturn:     .quad szCarriageReturn
qAdrsMessResult:          .quad sMessResult
qAdrTableNumber:          .quad TableNumber
qAdrsZoneConversion:      .quad sZoneConversion
/******************************************************************/
/*     Knuth Shuffle                                  */
/******************************************************************/
/* x0 contains the address of table */
/* x1 contains the number of elements */
knuthShuffle:
    stp x1,lr,[sp,-16]!         // save  registers
    stp x2,x3,[sp,-16]!         // save  registers
    stp x4,x5,[sp,-16]!         // save  registers
    stp x6,x7,[sp,-16]!         // save  registers
    mov x5,x0                   // save table address
    mov x6,x1                   // save number of elements
    mov x2,0                    // start index
1:
    mov x0,0
    mov x1,x2                   // generate aleas
    bl extRandom
    ldr x3,[x5,x2,lsl 3]        // swap number on the table
    ldr x4,[x5,x0,lsl 3]
    str x4,[x5,x2,lsl 3]
    str x3,[x5,x0,lsl 3]
    add x2,x2,1                 // next number
    cmp x2,x6                   // end ?
    blt 1b                      // no -> loop

100:
    ldp x6,x7,[sp],16           // restaur  2 registers
    ldp x4,x5,[sp],16           // restaur  2 registers
    ldp x2,x3,[sp],16           // restaur  2 registers
    ldp x1,lr,[sp],16           // restaur  2 registers
    ret
/******************************************************************/
/*     random number                                          */
/******************************************************************/
/*  x0 contains inferior value */
/*  x1 contains maxi value */
/*  x0 return random number */
extRandom:
    stp x1,lr,[sp,-16]!        // save  registers
    stp x2,x8,[sp,-16]!        // save  registers
    stp x19,x20,[sp,-16]!      // save  registers
    sub sp,sp,16               // reserve 16 octets on stack
    mov x19,x0
    add x20,x1,1
    mov x0,sp                  // store result on stack
    mov x1,8                   // length 8 bytes
    mov x2,0
    mov x8,278                 //  call system Linux 64 bits Urandom
    svc 0
    mov x0,sp                  // load résult on stack
    ldr x0,[x0]
    sub x2,x20,x19             // calculation of the range of values
    udiv x1,x0,x2              // calculation range modulo
    msub x0,x1,x2,x0
    add  x0,x0,x19             // and add inferior value
100:
    add sp,sp,16               // alignement stack
    ldp x19,x20,[sp],16        // restaur  2 registers
    ldp x2,x8,[sp],16          // restaur  2 registers
    ldp x1,lr,[sp],16          // restaur  2 registers
    ret                        // return to address lr x30
/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"


:set-state-ok t

(defun array-swap (name array i j)
   (let ((ai (aref1 name array i))
         (aj (aref1 name array j)))
      (aset1 name
             (aset1 name array j ai)
             i aj)))

(defun shuffle-r (name array m state)
   (if (zp m)
       (mv array state)
       (mv-let (i state)
               (random$ m state)
          (shuffle-r name
                     (array-swap name array i m)
                     (1- m)
                     state))))

(defun shuffle (name array state)
   (shuffle-r name
              array
              (1- (first (dimensions name array)))
              state))


PROC PrintTable(INT ARRAY tab BYTE size)
  BYTE i

  FOR i=0 TO size-1
  DO
    PrintF("%I ",tab(i))
  OD
  PutE()
RETURN

PROC KnuthShuffle(INT ARRAY tab BYTE size)
  BYTE i,j
  INT tmp

  i=size-1
  WHILE i>0
  DO
    j=Rand(i+1)
    tmp=tab(i)
    tab(i)=tab(j)
    tab(j)=tmp
    i==-1
  OD
RETURN

PROC Main()
  BYTE i,size=[20]
  INT ARRAY tab(size)

  FOR i=0 TO size-1
  DO
    tab(i)=-50+10*i
  OD

  PrintE("Original data:")
  PrintTable(tab,size)
  PutE()

  KnuthShuffle(tab,size)

  PrintE("Shuffled data:")
  PrintTable(tab,size)
RETURN


generic
   type Element_Type is private;
   type Array_Type is array (Positive range <>) of Element_Type;

procedure Generic_Shuffle (List : in out Array_Type);


void
shuffle(list l)
{
    integer i;

    i = ~l;
    if (i) {
        i -= 1;
        while (i) {
            l.spin(i, drand(i));
            i -= 1;
        }
    }
}


PROC between = (INT a, b)INT :
(
  ENTIER (random * ABS (b-a+1) + (a<b|a|b))
);

PROC knuth shuffle = (REF[]INT a)VOID:
(
  FOR i FROM LWB a TO UPB a DO
    INT j = between(LWB a, UPB a);
    INT t = a[i];
    a[i] := a[j];
    a[j] := t
  OD
);


set n to 25

set array to {}
repeat with i from 1 to n
	set end of array to i
end repeat
copy {array, array} to {unshuffled, shuffled}
repeat with i from n to 1 by -1
	set j to (((random number) * (i - 1)) as integer) + 1
	set shuffled's item i to array's item j
	if j ≠ i's contents then set array's item j to array's item i
end repeat

return {unshuffled, shuffled}


/* ARM assembly Raspberry PI  */
/*  program knuthShuffle.s   */

/************************************/
/* Constantes                       */
/************************************/
.equ STDOUT, 1     @ Linux output console
.equ EXIT,   1     @ Linux syscall
.equ WRITE,  4     @ Linux syscall
/*********************************/
/* Initialized data              */
/*********************************/
.data
sMessResult:      .ascii "Value  : "
sMessValeur:       .fill 11, 1, ' '            @ size => 11
szCarriageReturn: .asciz "\n"

.align 4
iGraine:  .int 123456
.equ NBELEMENTS,      10
TableNumber:	     .int   1,2,3,4,5,6,7,8,9,10

/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                                           @ entry of program
    ldr r0,iAdrTableNumber                      @ address number table
    mov r1,#NBELEMENTS                          @ number of élements
    bl knuthShuffle
    ldr r2,iAdrTableNumber
    mov r3,#0
1:                                              @ loop display table
    ldr r0,[r2,r3,lsl #2]
    ldr r1,iAdrsMessValeur                      @ display value
    bl conversion10                             @ call function
    ldr r0,iAdrsMessResult
    bl affichageMess                            @ display message
    add r3,#1
    cmp r3,#NBELEMENTS - 1
    ble 1b

    ldr r0,iAdrszCarriageReturn
    bl affichageMess
    /*    2e shuffle             */
    ldr r0,iAdrTableNumber                     @ address number table
    mov r1,#NBELEMENTS                         @ number of élements
    bl knuthShuffle
    ldr r2,iAdrTableNumber
    mov r3,#0
2:                                             @ loop display table
    ldr r0,[r2,r3,lsl #2]
    ldr r1,iAdrsMessValeur                     @ display value
    bl conversion10                            @ call function
    ldr r0,iAdrsMessResult
    bl affichageMess                           @ display message
    add r3,#1
    cmp r3,#NBELEMENTS - 1
    ble 2b

100:                                            @ standard end of the program
    mov r0, #0                                  @ return code
    mov r7, #EXIT                               @ request to exit program
    svc #0                                      @ perform the system call

iAdrsMessValeur:          .int sMessValeur
iAdrszCarriageReturn:     .int szCarriageReturn
iAdrsMessResult:          .int sMessResult
iAdrTableNumber:          .int TableNumber

/******************************************************************/
/*     Knuth Shuffle                                             */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains the number of elements */
knuthShuffle:
    push {r2-r5,lr}                                    @ save registers
    mov r5,r0                                          @ save table address
    mov r2,#0                                          @ start index
1:
    mov r0,r2                                          @ generate aleas
    bl genereraleas
    ldr r3,[r5,r2,lsl #2]                              @ swap number on the table
    ldr r4,[r5,r0,lsl #2]
    str r4,[r5,r2,lsl #2]
    str r3,[r5,r0,lsl #2]
    add r2,#1                                           @ next number
    cmp r2,r1                                           @ end ?
    blt 1b                                              @ no -> loop

100:
    pop {r2-r5,lr}
    bx lr                                               @ return

/******************************************************************/
/*     display text with size calculation                         */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
    push {r0,r1,r2,r7,lr}                          @ save  registres
    mov r2,#0                                      @ counter length
1:                                                 @ loop length calculation
    ldrb r1,[r0,r2]                                @ read octet start position + index
    cmp r1,#0                                      @ if 0 its over
    addne r2,r2,#1                                 @ else add 1 in the length
    bne 1b                                         @ and loop
                                                   @ so here r2 contains the length of the message
    mov r1,r0                                      @ address message in r1
    mov r0,#STDOUT                                 @ code to write to the standard output Linux
    mov r7, #WRITE                                 @ code call system "write"
    svc #0                                         @ call systeme
    pop {r0,r1,r2,r7,lr}                           @ restaur des  2 registres */
    bx lr                                          @ return
/******************************************************************/
/*     Converting a register to a decimal unsigned                */
/******************************************************************/
/* r0 contains value and r1 address area   */
/* r0 return size of result (no zero final in area) */
/* area size => 11 bytes          */
.equ LGZONECAL,   10
conversion10:
    push {r1-r4,lr}                                @ save registers
    mov r3,r1
    mov r2,#LGZONECAL

1:	                                           @ start loop
    bl divisionpar10U                              @unsigned  r0 <- dividende. quotient ->r0 reste -> r1
    add r1,#48                                     @ digit
    strb r1,[r3,r2]                                @ store digit on area
    cmp r0,#0                                      @ stop if quotient = 0
    subne r2,#1                                    @ else previous position
    bne 1b	                                   @ and loop
                                                   @ and move digit from left of area
    mov r4,#0
2:
    ldrb r1,[r3,r2]
    strb r1,[r3,r4]
    add r2,#1
    add r4,#1
    cmp r2,#LGZONECAL
    ble 2b
                                                      @ and move spaces in end on area
    mov r0,r4                                         @ result length
    mov r1,#' '                                       @ space
3:
    strb r1,[r3,r4]                                   @ store space in area
    add r4,#1                                         @ next position
    cmp r4,#LGZONECAL
    ble 3b                                            @ loop if r4 <= area size

100:
    pop {r1-r4,lr}                                    @ restaur registres
    bx lr                                             @return

/***************************************************/
/*   division par 10   unsigned                    */
/***************************************************/
/* r0 dividende   */
/* r0 quotient */
/* r1 remainder  */
divisionpar10U:
    push {r2,r3,r4, lr}
    mov r4,r0                                          @ save value
    //mov r3,#0xCCCD                                   @ r3 <- magic_number lower  raspberry 3
    //movt r3,#0xCCCC                                  @ r3 <- magic_number higter raspberry 3
    ldr r3,iMagicNumber                                @ r3 <- magic_number    raspberry 1 2
    umull r1, r2, r3, r0                               @ r1<- Lower32Bits(r1*r0) r2<- Upper32Bits(r1*r0)
    mov r0, r2, LSR #3                                 @ r2 <- r2 >> shift 3
    add r2,r0,r0, lsl #2                               @ r2 <- r0 * 5
    sub r1,r4,r2, lsl #1                               @ r1 <- r4 - (r2 * 2)  = r4 - (r0 * 10)
    pop {r2,r3,r4,lr}
    bx lr                                              @ leave function
iMagicNumber:  	.int 0xCCCCCCCD
/***************************************************/
/*   Generation random number                  */
/***************************************************/
/* r0 contains limit  */
genereraleas:
    push {r1-r4,lr}                                    @ save registers
    ldr r4,iAdriGraine
    ldr r2,[r4]
    ldr r3,iNbDep1
    mul r2,r3,r2
    ldr r3,iNbDep1
    add r2,r2,r3
    str r2,[r4]                                        @ maj de la graine pour l appel suivant
    cmp r0,#0
    beq 100f
    mov r1,r0                                          @ divisor
    mov r0,r2                                          @ dividende
    bl division
    mov r0,r3                                          @ résult = remainder

100:                                                   @ end function
    pop {r1-r4,lr}                                     @ restaur registers
    bx lr                                              @ return
/*****************************************************/
iAdriGraine: .int iGraine
iNbDep1: .int 0x343FD
iNbDep2: .int 0x269EC3
/***************************************************/
/* integer division unsigned                       */
/***************************************************/
division:
    /* r0 contains dividend */
    /* r1 contains divisor */
    /* r2 returns quotient */
    /* r3 returns remainder */
    push {r4, lr}
    mov r2, #0                                         @ init quotient
    mov r3, #0                                         @ init remainder
    mov r4, #32                                        @ init counter bits
    b 2f
1:                                                     @ loop
    movs r0, r0, LSL #1                                @ r0 <- r0 << 1 updating cpsr (sets C if 31st bit of r0 was 1)
    adc r3, r3, r3                                     @ r3 <- r3 + r3 + C. This is equivalent to r3 ? (r3 << 1) + C
    cmp r3, r1                                         @ compute r3 - r1 and update cpsr
    subhs r3, r3, r1                                   @ if r3 >= r1 (C=1) then r3 <- r3 - r1
    adc r2, r2, r2                                     @ r2 <- r2 + r2 + C. This is equivalent to r2 <- (r2 << 1) + C
2:
    subs r4, r4, #1                                    @ r4 <- r4 - 1
    bpl 1b                                             @ if r4 >= 0 (N=0) then loop
    pop {r4, lr}
    bx lr


knuth: function [arr][
	if 0=size arr -> return []

 	loop ((size arr)-1)..0 'i [
 		j: random 0 i

 		tmp: arr\[i]
 		set arr i arr\[j]
 		set arr j tmp
 	]

 	return arr
]

print knuth []
print knuth [10]
print knuth [10 20]
print knuth [10 20 30]


MsgBox % shuffle("1,2,3,4,5,6,7,8,9")
MsgBox % shuffle("1,2,3,4,5,6,7,8,9")

shuffle(list) {                          ; shuffle comma separated list, converted to array
   StringSplit a, list, `,               ; make array (length = a0)
   Loop % a0-1 {
      Random i, A_Index, a0              ; swap item 1,2... with a random item to the right of it
      t := a%i%, a%i% := a%A_Index%, a%A_Index% := t
   }
   Loop % a0                             ; construct string from sorted array
      s .= "," . a%A_Index%
   Return SubStr(s,2)                    ; drop leading comma
}


Dim $a[10]
ConsoleWrite('array before permutation:' & @CRLF)
For $i = 0 To 9
	$a[$i] = Random(20,100,1)
	ConsoleWrite($a[$i] & ' ')
Next
ConsoleWrite(@CRLF)

_Permute($a)
ConsoleWrite('array after permutation:' & @CRLF)
For $i = 0 To UBound($a) -1
	ConsoleWrite($a[$i] & ' ')
Next
ConsoleWrite(@CRLF)

Func _Permute(ByRef $array)
	Local $random, $tmp
	For $i = UBound($array) -1 To 0 Step -1
		$random = Random(0,$i,1)
		$tmp = $array[$random]
		$array[$random] = $array[$i]
		$array[$i] = $tmp
	Next
EndFunc


# Shuffle an _array_ with indexes from 1 to _len_.
function shuffle(array, len,    i, j, t) {
	for (i = len; i > 1; i--) {
		# j = random integer from 1 to i
		j = int(i * rand()) + 1

		# swap array[i], array[j]
		t = array[i]
		array[i] = array[j]
		array[j] = t
	}
}

# Test program.
BEGIN {
	len = split("11 22 33 44 55 66 77 88 99 110", array)
	shuffle(array, len)

	for (i = 1; i < len; i++) printf "%s ", array[i]
	printf "%s\n", array[len]
}


RANDOMIZE TIMER

DIM cards(51) AS INTEGER
DIM L0 AS LONG, card AS LONG

PRINT "before:"
FOR L0 = 0 TO 51
    cards(L0) = L0
    PRINT LTRIM$(STR$(cards(L0))); " ";
NEXT

FOR L0 = 51 TO 0 STEP -1
    card = INT(RND * (L0 + 1))
    IF card <> L0 THEN SWAP cards(card), cards(L0)
NEXT

PRINT : PRINT "after:"
FOR L0 = 0 TO 51
    PRINT LTRIM$(STR$(cards(L0))); " ";
NEXT
PRINT


seed = 1   /* seed of the random number generator */
scale = 0

/* Random number from 0 to 32767. */
define rand() {
	/* Formula (from POSIX) for random numbers of low quality. */
	seed = (seed * 1103515245 + 12345) % 4294967296
	return ((seed / 65536) % 32768)
}

/* Shuffle the first _count_ elements of shuffle[]. */
define shuffle(count) {
	auto b, i, j, t

	i = count
	while (i > 0) {
		/* j = random number in [0, i) */
		b = 32768 % i  /* want rand() >= b */
		while (1) {
			j = rand()
			if (j >= b) break
		}
		j = j % i

		/* decrement i, swap shuffle[i] and shuffle[j] */
		t = shuffle[--i]
		shuffle[i] = shuffle[j]
		shuffle[j] = t
	}
}

/* Test program. */
define print_array(count) {
	auto i
	for (i = 0; i < count - 1; i++) print shuffle[i], ", "
	print shuffle[i], "\n"
}

for (i = 0; i < 10; i++) shuffle[i] = 11 * (i + 1)
"Original array: "; trash = print_array(10)

trash = shuffle(10)
"Shuffled array: "; trash = print_array(10)
quit


Knuth ← {
  𝕊 arr:
  l ← ≠arr
  {
    arr ↩ ⌽⌾(⟨•rand.Range l, 𝕩⟩⊸⊏)arr
  }¨↕l
  arr
}
P ← •Show Knuth

P ⟨⟩
P ⟨10⟩
P ⟨10, 20⟩
P ⟨10, 20, 30⟩


shuffle = { a |
  (a.length - 1).to 1 { i |
    random_index = random(0, i)
    temp = a[i]
    a[i] = a[random_index]
    a[random_index] = temp
  }

  a
}

p shuffle [1 2 3 4 5 6 7]


#include <stdlib.h>
#include <string.h>

int rrand(int m)
{
  return (int)((double)m * ( rand() / (RAND_MAX+1.0) ));
}

#define BYTE(X) ((unsigned char *)(X))
void shuffle(void *obj, size_t nmemb, size_t size)
{
  void *temp = malloc(size);
  size_t n = nmemb;
  while ( n > 1 ) {
    size_t k = rrand(n--);
    memcpy(temp, BYTE(obj) + n*size, size);
    memcpy(BYTE(obj) + n*size, BYTE(obj) + k*size, size);
    memcpy(BYTE(obj) + k*size, temp, size);
  }
  free(temp);
}


public static void KnuthShuffle<T>(T[] array)
{
    System.Random random = new System.Random();
    for (int i = 0; i < array.Length; i++)
    {
        int j = random.Next(i, array.Length); // Don't select from the entire array on subsequent loops
        T temp = array[i]; array[i] = array[j]; array[j] = temp;
    }
}


#include <cstdlib>
#include <algorithm>
#include <iterator>

template<typename RandomAccessIterator>
void knuthShuffle(RandomAccessIterator begin, RandomAccessIterator end) {
  for(unsigned int n = end - begin - 1; n >= 1; --n) {
    unsigned int k = rand() % (n + 1);
    if(k != n) {
      std::iter_swap(begin + k, begin + n);
    }
  }
}


(defn shuffle [vect]
  (reduce (fn [v i] (let [r (rand-int i)]
                      (assoc v i (v r) r (v i))))
          vect (range (dec (count vect)) 1 -1)))


knuth_shuffle = proc [T: type] (a: array[T])
    lo: int := array[T]$low(a)
    hi: int := array[T]$high(a)
    for i: int in int$from_to_by(hi, lo+1, -1) do
        j: int := lo + random$next(i-lo+1)
        temp: T := a[i]
        a[i] := a[j]
        a[j] := temp
    end
end knuth_shuffle

start_up = proc ()
    po: stream := stream$primary_output()
    d: date := now()
    random$seed(d.second + 60*(d.minute + 60*d.hour))
    arr: array[int] := array[int]$[1,2,3,4,5,6,7,8,9]
    knuth_shuffle[int](arr)
    for i: int in array[int]$elements(arr) do
        stream$puts(po, int$unparse(i) || " ")
    end
end start_up


# shuffle(<output variable> [<value>...]) shuffles the values, and
# stores the result in a list.
function(shuffle var)
  set(forever 1)

  # Receive ARGV1, ARGV2, ..., ARGV${last} as an array of values.
  math(EXPR last "${ARGC} - 1")

  # Shuffle the array with Knuth shuffle (Fisher-Yates shuffle).
  foreach(i RANGE ${last} 1)
    # Roll j = a random number from 1 to i.
    math(EXPR min "100000000 % ${i}")
    while(forever)
      string(RANDOM LENGTH 8 ALPHABET 0123456789 j)
      if(NOT j LESS min)        # Prevent modulo bias when j < min.
        break()                 # Break loop when j >= min.
      endif()
    endwhile()
    math(EXPR j "${j} % ${i} + 1")

    # Swap ARGV${i} with ARGV${j}.
    set(t ${ARGV${i}})
    set(ARGV${i} ${ARGV${j}})
    set(ARGV${j} ${t})
  endforeach(i)

  # Convert array to list.
  set(answer)
  foreach(i RANGE 1 ${last})
    list(APPEND answer ${ARGV${i}})
  endforeach(i)
  set("${var}" ${answer} PARENT_SCOPE)
endfunction(shuffle)


       IDENTIFICATION DIVISION.
       PROGRAM-ID. knuth-shuffle.

       DATA DIVISION.
       LOCAL-STORAGE SECTION.
       01  i                       PIC 9(8).
       01  j                       PIC 9(8).

       01  temp                    PIC 9(8).

       LINKAGE SECTION.
       78  Table-Len               VALUE 10.
       01  ttable-area.
           03  ttable              PIC 9(8) OCCURS Table-Len TIMES.

       PROCEDURE DIVISION USING ttable-area.
           MOVE FUNCTION RANDOM(FUNCTION CURRENT-DATE (11:6)) TO i

           PERFORM VARYING i FROM Table-Len BY -1 UNTIL i = 0
               COMPUTE j =
                   FUNCTION MOD(FUNCTION RANDOM * 10000, Table-Len) + 1

               MOVE ttable (i) TO temp
               MOVE ttable (j) TO ttable (i)
               MOVE temp TO ttable (j)
           END-PERFORM

           GOBACK
           .


(defun nshuffle (sequence)
  (loop for i from (length sequence) downto 2
        do (rotatef (elt sequence (random i))
                    (elt sequence (1- i))))
  sequence)


def knuthShuffle(items : Array)
    i = items.size-1
    while i > 1
        j = Random.rand(0..i)
        items.swap(i, j)

        i -= 1
    end
end


void main() {
    import std.stdio, std.random;

    auto a = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    a.randomShuffle;
    a.writeln;
}


procedure KnuthShuffle(a : array of Integer);
var
   i, j, tmp : Integer;
begin
   for i:=a.High downto 1 do begin
      j:=RandomInt(a.Length);
      tmp:=a[i]; a[i]:=a[j]; a[j]:=tmp;
   end;
end;


def shuffle(array, random) {
    for bound in (2..(array.size())).descending() {
        def i := random.nextInt(bound)
        def swapTo := bound - 1
        def t := array[swapTo]
        array[swapTo] := array[i]
        array[i] := t
    }
}


func shuffle . a[] .
  for i = len a[] downto 2
    r = random i
    swap a[r] a[i - 1]
  .
.
arr[] = [ 1 2 3 ]
call shuffle arr[]
print arr[]


Remark- The native '''shuffle''' function implementation  in EchoLisp has been replaced by this one.
 Thx Rosetta Code.
(lib 'list) ;; for list-permute

;; use "inside-out" algorithm, no swapping needed.
;; returns a random permutation vector of [0 .. n-1]
(define (rpv n (j))
(define v (make-vector n))
	(for [(i n)]
		(set! j (random (1+ i)))
		(when (!= i j) (vector-set! v i [v j]))
		(vector-set! v j i))
	v)

;; apply to any kind of list
(define (k-shuffle list)
	(list-permute list (vector->list (rpv (length list)))))

;; out
(k-shuffle (iota 17))
    → (16 7 11 10 0 9 15 12 13 8 4 2 14 3 6 5 1)

(k-shuffle
'(adrien 🎸 alexandre 🚂  antoine  🍼 ben 📚   georges 📷   julie 🎥 marine 🐼 nathalie 🍕 ))
    → (marine alexandre 🎥 julie 🎸 ben 🍼 nathalie 📚 georges 🚂 antoine adrien 🐼 📷 🍕)

(shuffle ;; native
'(adrien 🎸 alexandre 🚂 antoine 🍼 ben 📚 georges 📷 julie 🎥 marine 🐼 nathalie 🍕 ))
    → (antoine 🎥 🚂 marine adrien nathalie 🍼 🍕 ben 🐼 julie 📷 📚 🎸 alexandre georges)


import "prelude.eg"
import "random.ego"

using System
using List
using Math

def swap =
    [ I J XX -> insert I (nth J XX) (insert J (nth I XX) XX) ]

def shuffle =
    [ XX ->
        let INDICES = reverse (fromto 0 ((length XX) - 1)) in
        let SWAPS = map [ I -> I (between 0 I) ] INDICES in
            foldr [I J -> swap I J] XX SWAPS ]

def main = shuffle (fromto 1 9)


class
	APPLICATION

create
	make

feature {NONE} -- Initialization

	make
		do
			test := <<1, 2>>
			io.put_string ("Initial: ")
			across
				test as t
			loop
				io.put_string (t.item.out + " ")
			end
			test := shuffle (test)
			io.new_line
			io.put_string ("Shuffled: ")
			across
				test as t
			loop
				io.put_string (t.item.out + " ")
			end
		end

	test: ARRAY [INTEGER]

	shuffle (ar: ARRAY [INTEGER]): ARRAY [INTEGER]
			-- Array containing the same elements as 'ar' in a shuffled order.
		require
			more_than_one_element: ar.count > 1
		local
			count, j, ith: INTEGER
			random: V_RANDOM
		do
			create random
			create Result.make_empty
			Result.deep_copy (ar)
			count := ar.count
			across
				1 |..| count as c
			loop
				j := random.bounded_item (c.item, count)
				ith := Result [c.item]
				Result [c.item] := Result [j]
				Result [j] := ith
				random.forth
			end
		ensure
			same_elements: across ar as a all Result.has (a.item) end
		end

end


import system'routines;
import extensions;

const int MAX = 10;

extension randomOp
{
    randomize()
    {
        var max := self.Length;

        for(int i := 0, i < max, i += 1)
        {
            var j := randomGenerator.eval(i,max);

            self.exchange(i,j)
        };

        ^ self
    }
}

public program()
{
    var a := Array.allocate:MAX.populate:(i => i );

    console.printLine(a.randomize())
}


defmodule Knuth do
  def shuffle( inputs ) do
    n = length( inputs )
    {[], acc} = Enum.reduce( n..1, {inputs, []}, &random_move/2 )
    acc
  end

  defp random_move( n, {inputs, acc} ) do
    item = Enum.at( inputs, :rand.uniform(n)-1 )
    {List.delete( inputs, item ), [item | acc]}
  end
end

seq = Enum.to_list( 0..19 )
IO.inspect Knuth.shuffle( seq )

seq = [1,2,3]
Enum.reduce(1..100000, Map.new, fn _,acc ->
  k = Knuth.shuffle(seq)
  Map.update(acc, k, 1, &(&1+1))
end)
|> Enum.each(fn {k,v} -> IO.inspect {k,v} end)


-module( knuth_shuffle ).

-export( [list/1] ).

list( Inputs ) ->
	N = erlang:length( Inputs ),
	{[], Acc} = lists:foldl( fun random_move/2, {Inputs, []}, lists:reverse(lists:seq(1, N)) ),
	Acc.

random_move( N, {Inputs, Acc} ) ->
	Item = lists:nth( random:uniform(N), Inputs ),
	{lists:delete(Item, Inputs), [Item | Acc]}.


PROGRAM KNUTH_SHUFFLE

CONST CARDS%=52

DIM PACK%[CARDS%]

BEGIN
   RANDOMIZE(TIMER)
   FOR I%=1 TO CARDS% DO
      PACK%[I%]=I%
   END FOR
   FOR N%=CARDS% TO 2 STEP -1 DO
      SWAP(PACK%[N%],PACK%[1+INT(N%*RND(1))])
   END FOR
   FOR I%=1 TO CARDS% DO
      PRINT(PACK%[I%];)
   END FOR
   PRINT
END PROGRAM