# 15110 Fall 2011 [Cortina/von Ronne]

## Lab 10 - Cellular Automata

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

### Instructions

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 "lab10.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:

• To create a new array, use Array.new.
• Use a loop to set all of the cells to 0 first. Then afterwards, set the middle cell to 1.

Test your function by running it in irb.

Sample usage:

```>> load "lab10.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:

• To create a new array, use Array.new.
• Use a loop to set each of the cells to 0 or 1, randomly.
• Think about using the rand function to generate a random number between 0 and 1, inclusive.

Test your function by running it in irb.

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

```>> load "lab10.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 "lab10.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.

Exploring Further:

1. Modify the apply_rule function so it applies a different rule, like Rule 30.

2. Modify the apply_rule function so it takes another parameter, rule_num, which represents the rule number. The function should be able to perform steps D-K in the given algorithm for ANY valid rule number between 0 and 255.