How to resolve the algorithm Langton's ant step by step in the Ruby programming language

Published on 12 May 2024 09:40 PM

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