CS140 -- Lab 9

This is a recursion lab. In neopets.com, there is a game called "ShapeShifter." Since the web site is meant for children, there are pictures and a story that go with it, but here is its essence. You start with a 3X3 grid of zeros and ones. Say:

001
101
110

Then you are given some shapes, such as:

1
01
11
10
11
10

Your job is to apply these shapes to the grid, choosing where to apply each shape. When you apply a shape, you will set the values in the grid to the bitwise exclusive or of the grid and the shape. For example, suppose you apply the shape:

1

to the upper left cell in the grid. The values in grid will now become:

101
101
110

Now, suppose you apply the shape:

01
11

to the bottom right corner of the grid. Then the grid becomes:

101
100
101

Finally, now suppose you apply the shape:

10
11
10

to the right side of the grid. The grid will now become:

111
111
111


Now that you know how the game works, your goal will always be to take an initial grid, plus a set of shapes, and to decide where to apply each shape so that at the end, the grid contains all ones.

You are going to do this by writing a recursive program called "shifter." Shifter takes three command line arguments:

shifter row0 row1 row2
Row0, row1 and row2 specify the initial configuration of the grid. They are each three-digit binary numbers.

Then, the user enters the shapes on standard input using the following keys:

A:
1
    
B:
11
    
C:
1
1
    
D:
11
10
    
E:
01
11
F:
111
    
G:
1
1
1
    
H:
10
11
01
    
I:
110
011
    
J:
11
11
K:
111
010
    
L:
10
11
10
    
M:
01
11
01
    
N:
011
111
    
O:
11
11
11

You can enter any number of shapes per line. When standard input is closed, your program should solve the puzzle by finding the correct locations in which to apply each shape so that the final output is all ones. For example:

UNIX> shifter 001 101 110
A E
L
< CNTL-D >
A 0 0
E 1 1
L 0 1
UNIX>
This says to apply A at the upper left-hand corner, E shifting the shape one cell to the right and one down, and L shifting one cell to the right.

If there's no solution, your program should print out "No solution."


I have included a program called play in the lab directory. This takes a grid on its command line, and then lines on standard input that define where to apply shapes. These are of the form
key rowshift columnshift
It then prints out the resulting grid. For example:
UNIX> play 001 101 110
001
101
110

A 0 0
Processing Pattern:
100
000
000

Output
101
101
110

E 1 1
Processing Pattern:
000
001
011

Output
101
100
101

L 0 1
Processing Pattern:
010
011
010

Output
111
111
111

< CNTL-D >
This lets you test your program. It also lets you generate test files (see below under testing).

Error Checking

Make sure that your program receives correct input, both on the command line and as input. If you receive erroneous input, you may have the program print out an error string and exit.

Testing

Also in the lab directory is a program called random_test, which generates random input. If you pipe random_test into play, that gives you a test input that has an answer.

Finally, there is also a shell script test_lab.sh that generates nineteen random inputs using random_test and play, and calls shifter to solve the problem. The programs random_test, play and shifter must all be in the current directory.


UNIX> random_test > rtest.txt
UNIX> cat rtest.txt
M 0 0
C 1 2
C 0 1
G 0 0
A 1 1
UNIX> play 111 111 111 < rtest.txt
111
111
111
Processing Pattern:
010
110
010

Output
101
001
101

Processing Pattern:
000
001
001

Output
101
000
100

Processing Pattern:
010
010
000

Output
111
010
100

Processing Pattern:
100
100
100

Output
011
110
000

Processing Pattern:
000
010
000

Output
011
100
000

UNIX> awk '{ print $1 }' rtest.txt
M
C
C
G
A
UNIX> awk '{ print $1 }' rtest.txt | shifter 011 100 000
M 0 0
C 0 1
C 1 2
G 0 0
A 1 1
UNIX> awk '{ print $1 }' rtest.txt | shifter 011 100 000 | play 011 100 000
011
100
000
Enter key rshift cshift
Processing Pattern:
010
110
010

Output
001
010
010

Processing Pattern:
010
010
000

Output
011
000
010

Processing Pattern:
000
001
001

Output
011
001
011

Processing Pattern:
100
100
100

Output
111
101
111

Processing Pattern:
000
010
000

Output
111
111
111

UNIX> sh test_lab.sh 
Test 1 111 111 111
Test 2 111 111 111
Test 3 111 111 111
Test 4 111 111 111
Test 5 111 111 111
Test 6 111 111 111
Test 7 111 111 111
Test 8 111 111 111
Test 9 111 111 111
Test 10 111 111 111
Test 11 111 111 111
Test 12 111 111 111
Test 13 111 111 111
Test 14 111 111 111
Test 15 111 111 111
Test 16 111 111 111
Test 17 111 111 111
Test 18 111 111 111
Test 19 111 111 111
UNIX> 


Program Structure

I'm going to let you structure this one yourself. The only requirement is that your program must use recursion. Here's how I structured mine (you don't have to do it this way): There are obviously many other ways to structure this program, but that seemed easiest to me.