How to resolve the algorithm Langton's ant step by step in the Ruby programming language
How to resolve the algorithm Langton's ant step by step in the Ruby programming language
Table of Contents
Problem Statement
Langton's ant is a cellular automaton that models an ant sitting on a plane of cells, all of which are white initially, the ant facing in one of four directions.
Each cell can either be black or white.
The ant moves according to the color of the cell it is currently sitting in, with the following rules:
This rather simple ruleset leads to an initially chaotic movement pattern, and after about 10000 steps, a cycle appears where the ant moves steadily away from the starting location in a diagonal corridor about 10 cells wide.
Conceptually the ant can then walk infinitely far away.
Start the ant near the center of a 100x100 field of cells, which is about big enough to contain the initial chaotic part of the movement. Follow the movement rules for the ant, terminate when it moves out of the region, and show the cell colors it leaves behind.
The problem has received some analysis; for more details, please take a look at the Wikipedia article (a link is below)..
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Langton's ant step by step in the Ruby programming language
Ant class
The Ant class represents an ant that moves on a 2D plane and changes the color of the cells it visits. It has the following attributes:
@plane
: A Plane object representing the 2D plane where the ant moves.@pos_x
and@pos_y
: The current position of the ant on the plane.@direction
: The current direction the ant is facing.@moves
: The number of moves the ant has made.
The Ant class has the following methods:
initialize
: Initializes the ant with the given size of the plane and the starting position.run
: Runs the ant until it goes out of bounds, and returns the number of moves the ant made.move
: Moves the ant one step in the current direction, changing the color of the cell it visits and updating the direction based on the color of the cell.advance
: Moves the ant one step in the current direction and checks if the ant is still within the bounds of the plane.position
: Returns the current position of the ant.to_s
: Returns a string representation of the plane, with the ant's current position marked.
Plane class
The Plane class represents a 2D plane where the ant moves. It has the following attributes:
@size_x
and@size_y
: The size of the plane in the x and y directions.@cells
: A 2D array representing the cells of the plane, where each cell can be either white or black.
The Plane class has the following methods:
initialize
: Initializes the plane with the given size and sets all cells to white.white?
: Checks if the cell at the given position is white.toggle_colour
: Changes the color of the cell at the given position from white to black or vice versa.check_bounds
: Checks if the given position is within the bounds of the plane.to_s
: Returns a string representation of the plane, with white cells represented by dots and black cells represented by hash marks.
Move class
The Move class is a hash that maps direction names to their corresponding move vectors.
Directions
The directions constant is an array of direction names: [:north, :east, :south, :west].
Right
The Right constant is a hash that maps each direction to the direction to the right of it.
Left
The Left constant is a hash that maps each direction to the direction to the left of it.
Main
The main part of the code creates an instance of the Ant class with a plane size of 100x100 and runs it until it goes out of bounds. It then prints the number of moves the ant made and the ant's final position.
Second version of Ant class
The second version of the Ant class uses a different approach to represent the plane and moves the ant. It has the following attributes:
@plane
: A 2D array representing the plane, where each cell is either true (white) or false (black).@sx
and@sy
: The size of the plane in the x and y directions.@px
and@py
: The current position of the ant on the plane.@direction
: The current direction the ant is facing.@moves
: The number of moves the ant has made.
The second version of the Ant class has the following methods:
initialize
: Initializes the ant with the given size of the plane and the starting position.move
: Moves the ant one step in the current direction, changing the color of the cell it visits and updating the direction based on the color of the cell.to_s
: Returns a string representation of the plane, with the ant's current position marked.
Main (second version)
The main part of the code creates an instance of the second version of the Ant class with a plane size of 100x100 and prints its string representation.
Source code in the ruby programming language
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
class Ant
MOVE = [[1,0], [0,1], [-1,0], [0,-1]] # [0]:east, [1]:south, [2]:west, [3]:north
def initialize(size_x, size_y, pos_x=size_x/2, pos_y=size_y/2)
@plane = Array.new(size_y) {Array.new(size_x, true)} # true -> white, false -> black
@sx, @sy = size_x, size_y
@px, @py = pos_x, pos_y # start position
@direction = 0 # south
@moves = 0
move while (0 <= @px and @px < @sx) and (0 <= @py and @py < @sy)
end
def move
@moves += 1
@direction = (@plane[@py][@px] ? @direction+1 : @direction-1) % 4
@plane[@py][@px] = !@plane[@py][@px]
@px += MOVE[@direction][0]
@py += MOVE[@direction][1]
end
def to_s
["out of bounds after #{@moves} moves: (#@px, #@py)"] +
(0...@sy).map {|y| (0...@sx).map {|x| @plane[y][x] ? "." : "#"}.join}
end
end
puts Ant.new(100, 100).to_s
You may also check:How to resolve the algorithm Padovan sequence step by step in the 11l programming language
You may also check:How to resolve the algorithm Zero to the zero power step by step in the Applesoft BASIC programming language
You may also check:How to resolve the algorithm Polynomial long division step by step in the C programming language
You may also check:How to resolve the algorithm Box the compass step by step in the MUMPS programming language
You may also check:How to resolve the algorithm FASTA format step by step in the jq programming language