### Lab 4 Run Times

Question: At the end of the Lab 4 write-up, there is a table showing how long each gradescript took to run. I am wondering if this is how long it took to run a gradescript (i.e. #81) using "./gradescript 81" or using the actual contents of gradescript 81, meaning "./matrix_enum 5 10 h"?

The majority of time is spent in double_check. Let me explain:

Calling matrix_enum 5 10 will take a long time, because there are (5!) * ( 20! ) / (10! * 10!) = 22,170,720 matrices that it will generate. Each matrix prints 6 lines, so we can double-check that math by running matrix_enum 5 10 and piping it to wc. The answer should be 22,170,720*6 = 133,024,320. As you can see, it takes a minute, 22 seconds.

```UNIX> time sh -c "./matrix_enum 5 10 h | wc"
133024320 110853600 310390080
80.069u 1.828s 1:22.82 98.8%  0+0k 0+0io 0pf+0w
UNIX>
```
The beauty of the double_check program is you don't have to let matrix_enum complete, and in gradescript 81, you are piping matrix_enum to flatten_for_grading, and then only taking the first 5000 lines of output, and piping that to double_check. In doing so, matrix_enum doesn't complete -- it will die after outputting roughly 30000 lines (because each matrix corresponds to six lines of output for matrix_enum, and then one line of output for flatten_for_grading). You will learn the "why's" of this in CS360, but when head exits after reading 5000 lines, it will kill double_check and that will kill matrix_enum.

Let's prove that matrix_enum only has to print 30000 lines for the gradescript to work: Here, I'm going to show you that piping matrix_enum to head -n 30000 and then piping that to "flatten_for_grading | head -n 5000" is the same as what the gradescript does:

```UNIX> ./matrix_enum 5 10 h | head -n 30000 | /home/plank/cs302/Labs/Lab4/flatten_for_grading | head -n 5000 > f1.txt
UNIX> ./matrix_enum 5 10 h | /home/plank/cs302/Labs/Lab4/flatten_for_grading | head -n 5000 > f2.txt
UNIX> diff f1.txt f2.txt
UNIX>
```
Now, let's time the components. First, the first 30,000 lines of matrix_enum should be generated in a blink of an eye:
```UNIX> time sh -c "./matrix_enum 5 10 h | head -n 30000 > /dev/null"
0.020u 0.000s 0:00.02 100.0%  0+0k 0+0io 0pf+0w
UNIX>
```
Piping them through flatten_for_grading is really quick too:
```UNIX> time sh -c "./matrix_enum 5 10 h | /home/plank/cs302/Labs/Lab4/flatten_for_grading | head -n 5000 > /dev/null"
0.068u 0.084s 0:00.15 93.3% 0+0k 0+0io 0pf+0w
UNIX>
```
The program that's taking forever is double_check:
```UNIX> ./matrix_enum 5 10 h | /home/plank/cs302/Labs/Lab4/flatten_for_grading | head -n 5000 > f1.txt
UNIX> time /home/plank/cs302/Labs/Lab4/double_check 5 10 h < f1.txt
11.356u 0.040s 0:11.50 99.0%  0+0k 128+0io 0pf+0w
UNIX>
```
The reason is that double_check generates all possible combinations of 'X' and 'E' from its input, and with 10 E's in each matrix, that's a lot of enumeration.