#!/usr/bin/perl

# Greedy brute force solution to the Golf Foursomes Problem
# 11 Apr 2003 by Aneel Nazareth
# http://eye-of-newt.com/nazareth/golf.html

sub pick_best {
    my $playing = shift;
    my $candidates = shift;

    #warn "$playing $candidates\n";
    my %score;
    
    foreach $c (@$candidates) {
	foreach $p (@$playing) {
	    if ($played->[$c]->[$p]) {
		$score{$c}++;
	    }
	}
    }
    
    my $min = $score{$candidates->[0]};
    my $best = $candidates->[0];
    foreach $c (@$candidates) {
	if ($score{$c} < $min) {
	    $min = $score{$c};
	    $best = $c;
	}
    }
    #warn "best match is $best with score of $min\n";
    
    foreach $p (@$playing) {
	$played->[$p]->[$best]++;
	$played->[$best]->[$p]++;
	$played_round->[$p]->[$best]++;
	$played_round->[$best]->[$p]++;
    }
    return $best;
}


sub round {
    my %players;
    $played_round = [];
    
    print "New Round\n";
    
    for (my $i=0; $i<16; $i++) {
	$players{$i} = 1;
    }
    
    for (my $i=0; $i<4; $i++) {
	my @group;
	for (my $j=0; $j<4; $j++) {
	    my @players = sort {$a <=> $b} keys %players;
	    my $best = pick_best(\@group,\@players);
	    push(@group, $best);
	    delete $players{$best};
	}
	print "group $i: ";
	foreach (@group) {
	    printf("%2d ", $_);
	}
	print "\n";
    }
    
    print "\n";
    for (my $i=0; $i<16; $i++) {
	printf("%2d played this round: ", $i);
	for (my $j=0; $j<16; $j++) {
	    if ($played_round->[$i]->[$j]) {
		printf("%2d ", $j);
	    } else {
		print '   ';
	    }
	}
	print "\n";
    }
    
    print "\n";
    for (my $i=0; $i<16; $i++) {
	printf("%2d has played: ", $i);
	for (my $j=0; $j<16; $j++) {
	    if ($played->[$i]->[$j]) {
		printf("%2d ", $j);
     } else {
	 print '   ';
     }
	}
	print "\n";
    }
    
    print "\n";
}

round();
round();
round();
round();
round();

