## Homework Assignment 3

### Empirical Analysis of Board-Coloring Algorithms

#### Top-Level View

Last time, we compared the playing ability of two algorithms for the End Game. This time we compare the time performance of two algorithms for the board-coloring problem, which we encountered in the board reconstruction puzzle to open Session 11.

The Implementation Notes from Homework 2 apply here as well. In particular, in the description below, I refer to lists of integers as specifying the row and column counts. I mean 'list' in a generic sense. You may represent these lists in any way suitable to your language: as an array, a list, a vector, an object, ....

Tasks 4 through 6 ask you to report "the average time it takes" to execute a function. See this short section on timing execution in Python, Java, Ruby, and Racket. For other languages, please ask.

If you are game, there is a chance to earn some extra credit. Don't attempt the extra credit until you have made substantial progress on the basic tasks. I won't spend time grading extra credit if the primary assignment isn't in good shape.

Write the following functions.

1. Write a function greedy(rows,cols) that implements the greedy approach to coloring a board. The input is two lists of size n, containing integers that indicate the number of tokens in the corresponding rows and columns. The output is a board that satisfies the input configuration, or an indication of failure.

Demonstrate that your function works as expected for the six boards used as examples in Session 11.

Example:

```     rows [1 1 2]     output [1 0 0]
cols [1 2 1]            [0 1 0]
[0 1 1]
```

2. Write a function zoomin(rows,cols) that implements the zoom-in approach to coloring a board. This function has the same input/output signature as greedy().

Demonstrate that your function works as expected for the six boards used as examples in Session 11.

Example:

```     rows [1 1 3]     output [0 0 1]
cols [1 1 3]            [0 0 1]
[1 1 1]
```

3. Write a function random_board_config(N) that returns a random board configuration. The input N specifies the size of the board. The output is two lists of size N having these features:
• All list members are integers in the range [0..N].
• The sum of the two lists must be identical.
• The sum must be in the range [N²/4 .. 2N²/3].

Example:

```     N 3              output [1 1 2]
[1 2 1]
```

4. Generate 1000 random board configurations of size 3. Run both greedy() and zoomin() on each. Report:
• the number of configurations for which their is no legal coloring
• the number of configurations for which their is a legal coloring but on which greedy() fails
• the average time it takes greedy() to produce a board as output (successes only)
• the average time it takes greedy() to give up (failures on legal configurations only)
• the average time it takes zoomin() to produce a board as output

5. Repeat Task 4 with 1000 random board configurations of size 10.

6. Repeat Task 4 with 1000 random board configurations of size 100.

Create a readme.txt file that tells me:

• anything I need to know to compile and run your programs,
• what you found to be the hardest part of the assignment,

#### Extra Credit

Implement the brute-force approach to coloring a board.

Include it in your experiments and report its performance data along side those of the greedy and zoom-in approaches.

#### Timing Execution of Code

First, note that the time to execute a single function is often so small that it rounds to zero in a variable. Do not run a function once and save its execution time. Run the function many times (in this assignment, 1000), save the execution time of the for-loop, and then divide by the number of iterations.

Python

```    import time
start_time = time.time()
...
stop_time = time.time()
elapsed_time = stop_time - start_time   # in seconds
```

....... Or, for short expressions:

```    import timeit
timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)
```

Java

```    long startTime = System.currentTimeMillis();
...
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;   # in milliseconds
```

Ruby

```    start_time = Time.now
...
stop_time = Time.now
elapsed_time = stop_time - start_time   # in seconds
```

....... Or, for some real Ruby goodness:

```    def time
start = Time.now
yield
Time.now - start
end

# then reuse with:
time do
...
end
```

Racket

```    (time body ...+)
; returns value of last exp
; prints three times: full time, real time, GC time

(time-apply proc lst)
; returns four values:
;   result of (apply proc lst)
;   the three times from (time ...)
```

If you are interested in using another language, let me know. I can't guarantee help, but I can try.

#### Deliverables

By the due time and date, submit a zipped archive named homework03 containing: