15110 Spring 2013 [Kaynar/Gunawardena]

Lab 9 - Thursday, March 28, 2013

CA activities

  1. Show how to download the starting code lab9.rb and store this in the student's account.
  2. Demonstrate the display function using a fixed array
  3. Review the function rand(n) to generate random integers

Deliverables

  1. lab9.rb (initialize1, initialize2, apply_rule)
  2. ruleX.rb (challenge)
  3. arbitrary_rule.rb (challenge)

Overview

You may work on this lab with another student if you wish. If you do, put a comment in the program code that includes both of your names, and both of you should submit the code.

In lecture, we learned about one-dimensional cellular automata (see Unit9C) that displayed various interesting results (some patterns, some random). In this lab, you will write some simple Ruby functions to generate pictures like you saw in class for a one-dimensional cellular automaton.

Download the starting code lab9.rb and store this in your account in a private area.

Activities

A cellular automaton will be represented in Ruby as an array of 1's and 0's. Every position that has a 1 represents a black cell and a 0 represents a white cell.

  1. The code contains a function called display that displays the current state of the automaton, using asterisks (*) for black and spaces for white. Read through this function and make sure you know how it works. Test it in irb to make you understand its function.

    Sample usage:

    >> load "lab9.rb"
    => true
    >> automaton = [0, 1, 1, 0, 1, 0, 1, 1, 1]
    => [0, 1, 1, 0, 1, 0, 1, 1, 1]
    >> display(automaton)
     ** * ***
    => nil
    

  2. Write a function initialize1(n) that creates an array of size n representing an automaton with n cells. Your function should set all of the cells to white (0) except for the middle cell which should be black (1). If there are an even number of cells, you can decide where the middle is.

    HINTS:

    Test your function by running it in irb.

    Sample usage:

    >> load "lab9.rb"
    => true
    >> automaton = initialize1(9)
    => [0, 0, 0, 0, 1, 0, 0, 0, 0]
    >> display(automaton)
        *    
    => nil
    

  3. Write a function initialize2(n) that creates an array of size n representing an automaton with n cells. Your function should set each cell to a random color of black (1) or white (0). (Each is set randomly.)

    HINTS:

    Test your function by running it in irb.

    Sample usage (your results will likely vary since we're dealing with random number generation):

    >> load "lab9.rb"
    => true
    >> automaton = initialize2(9)
    => [0, 1, 1, 0, 1, 0, 1, 1, 1]
    >> display(automaton)
     ** * ***
    => nil
    

  4. We are now going to write a function that implements Rule 18 as shown in lecture. Recall that Rule 18 can be represented visually as follows:

    Write a function apply_rule(automaton) that requires an array automaton representing a cellular automaton and returns a new array representing the new state of the automaton after Rule 18 is applied.

    Follow this algorithm to apply Rule 18:

    1. Create a new array called new_automaton that has the same length as the array automaton.
    2. For each index i of the array automaton do the following:
      1. Set middle equal the value of automaton at index i.
      2. If i is not 0, then set left equal to the value of automaton at index i-1. Otherwise, set left equal to 0.
      3. If i is not the last valid index of automaton, then set right equal to the value of automaton at index i+1. Otherwise, set right equal to 0.
      4. If left = 1 and middle = 1 and right = 1, then set position i in new_automaton to 0.
      5. If left = 1 and middle = 1 and right = 0, then set position i in new_automaton to 0.
      6. If left = 1 and middle = 0 and right = 1, then set position i in new_automaton to 0.
      7. If left = 1 and middle = 0 and right = 0, then set position i in new_automaton to 1.
      8. If left = 0 and middle = 1 and right = 1, then set position i in new_automaton to 0.
      9. If left = 0 and middle = 1 and right = 0, then set position i in new_automaton to 0.
      10. If left = 0 and middle = 0 and right = 1, then set position i in new_automaton to 1.
      11. If left = 0 and middle = 0 and right = 0, then set position i in new_automaton to 0.
    3. Return new_automaton as the final result.

    Note steps D-K implement "Rule 18". If you read down the bits along the end of the 8 steps, you get 00010010 which is 18 in binary.

    Test your function in irb to make sure it works correctly.

    Sample usage:

    >> load "lab9.rb"
    => true
    >> automaton = initialize1(9)
    => [0, 0, 0, 0, 1, 0, 0, 0, 0]
    >> display(automaton)
        *    
    => nil
    >> automaton = apply_rule(automaton)
    => [0, 0, 0, 1, 0, 1, 0, 0, 0]
    >> display(automaton)
       * *   
    => nil
    

  5. We have supplied two functions, run1() and run2(), that allow you to apply Rule 18 to a automaton with a single black cell in the middle and a random set of black and white cells, respectively. Run each to see what patterns emerge for Rule 18 on each initial automaton with 80 cells.

Challenge:

  1. Pick a different rule, like Rule 30. Copy lab9.rb to ruleX.rb where X is the number of the rule you chose. Modify the apply_rule function so it applies this rule.

  2. Copy lab9.rb to arbitrary_rule.rb. Modify the apply_rule function so it takes another parameter, rule_num, which represents the rule number and create a modified run function that will apply an appropriate parameter to apply_rule. The function should be able to perform steps D-K in the given algorithm for ANY valid rule number between 0 and 255.