&sectionHeader('Unit Tests (50 points)');
$subtotal = 0;
@SOURCE = ();
@LINK = ();
$subtotal = &runTest('001', 'pointset_create empty set');
$subtotal += &runTest('002', 'pointset_add to empty set');
$subtotal += &runTest('003', 'pointset_contains for one-item set');
$subtotal += &runTest('004', 'pointset_add multiple times');
$subtotal += &runTest('005', 'pointset_size after adds');
$subtotal += &runTest('006', 'pointset_contains for larger set');
$subtotal += &runTest('007', 'pointset_for_each empty set');
$subtotal += &runTest('008', 'pointset_for_each for non-empty set');
$subtotal += &runTest('009', 'pointset_nearest_neighbor on empty set');
$subtotal += &runTest('010', 'pointset_nearest_neighbor for point in set');
$subtotal += &runTest('011', 'pointset_nearest_neighbor for point not in set #1');
$subtotal += &runTest('012', 'pointset_nearest_neighbor for point not in set #2');
$subtotal += &runTest('013', 'pointset_create non-empty');
$subtotal += &runTest('014', 'pointset_nearest_neighbor after pointset_create');
$subtotal += &runTest('015', 'pointset_nearest_neighbor random points');
$subtotal = $subtotal * 50 / 15;
my $unit = $subtotal;
$total += floor($subtotal);
&sectionResults('Unit Tests (50 points)', $subtotal, 15, $checkpoint );
$testCount += 15;

&sectionHeader('Running time (30 points; no credit for do-nothing solutions)');
$subtotal = 0;
@SOURCE = ();
@LINK = ();
$subtotal = &runTest('016', 'pointset_add random points expected time');
$subtotal += &runTest('017', 'pointset_create random points expected time');
$subtotal += &runTest('018', 'pointset_nearest_neighbor random points relaxed expected time');
$subtotal = $subtotal * 30 / 3;
$subtotal = ($unit < 15) ? 0 : $subtotal;
$total += floor($subtotal);
&sectionResults('Running time (30 points; no credit for do-nothing solutions)', $subtotal, 3, $checkpoint );
$testCount += 3;

&sectionHeader('Valgrind (20 points)');
$subtotal = 0;
@SOURCE = ();
@LINK = ();
$subtotal = &runTest('019', 'pointset_create empty set');
$subtotal += &runTest('020', 'pointset_add to empty set');
$subtotal += &runTest('021', 'pointset_add multiple times');
$subtotal += &runTest('022', 'pointset_contains for larger set');
$subtotal += &runTest('023', 'pointset_for_each empty set');
$subtotal += &runTest('024', 'pointset_for_each for non-empty set');
$subtotal += &runTest('025', 'pointset_nearest_neighbor on empty set');
$subtotal += &runTest('026', 'pointset_nearest_neighbor for point in set');
$subtotal += &runTest('027', 'pointset_nearest_neighbor for point not in set #1');
$subtotal += &runTest('028', 'pointset_create non-empty');
$subtotal += &runTest('029', 'pointset_nearest_neighbor after pointset_create');
$subtotal += &runTest('030', 'pointset_nearest_neighbor random points');
$subtotal = $subtotal * 20 / 12;
$subtotal = ($unit < 15) ? 0 : $subtotal;
$total += floor($subtotal);
&sectionResults('Valgrind (20 points)', $subtotal, 12, $checkpoint );
$testCount += 12;

&sectionHeader('Additional tests');
$subtotal = 0;
@SOURCE = ();
@LINK = ();
$subtotal = &runTest('031', 'pointset_add and pointset_destroy do not overflow stack');
$checkpoint = $total;
$total = 0;
$testCount = 0;
$total += floor($subtotal);
&sectionResults('Additional tests', $subtotal, 1, $checkpoint );
$testCount += 1;

&sectionHeader('k nearest neighbors');
$subtotal = 0;
@SOURCE = ();
@LINK = ();
$subtotal = &runTest('032', 'pointset_k_nearest example');
$subtotal += &runTest('033', 'pointset_k_nearest random points');
$subtotal += &runTest('034', 'pointset_k_nearest example w/ valgrind');
$subtotal += &runTest('035', 'pointset_k_nearest random points w/ valgrind');
$subtotal += &runTest('036', 'pointset_k_nearest random points expected time');
$total += floor($subtotal);
&sectionResults('k nearest neighbors', $subtotal, 5, $checkpoint );
$testCount += 5;

