#include /* The sample data file is: http://www.gtoal.com/wordgames/scrabble_solver/abeinnoqruyz.global The frequencies here are bogus, they're faked to look roughly right, as test data for the code below. The fact that they are not legitimate values doesn't affect this code. This is version (A) which does not incorporate the mod suggested by Steven Gordon, to eliminate lower-scoring plays that can be made with the same tiles. Version (B) will include that. This code will be used as a baseline to see how much overhead the modification generates, and by how much the results differ. Here's a test run: ./freq < abeinnoqruyz.global 2110 plays analysed. Total no of draws = 5655643 My opponent's move is unlikely to score above 2, at a 0% confidence level My opponent's move is unlikely to score above 3, at a 10% confidence level My opponent's move is unlikely to score above 7, at a 50% confidence level My opponent's move is unlikely to score above 16, at a 90% confidence level My opponent's move is unlikely to score above 132, at a 100% confidence level The data file contains lines like these (sampled from the start, middle and end of the file): tiles-to-play where how resulting-words score no-of-ways-of-picking-tiles n 11H across in 2 2000 n 7L across nu 2 2000 n 7M across un 2 2000 n A7 down na 2 2000 n A8 down an 2 2000 n D11 down ne 2 2000 n D12 down en 2 2000 n F11 down nu 2 2000 ... brqa F11 down burqa 36 707 niza B4 down nizam 36 1414 bay 8L across bray 36 1590 ez 8M across rez 36 3181 iz 8M across riz 36 3181 azione 3A across azione/etape(7) 37 151 zonure 3A across zonure/etape(7) 37 151 bize 3C across bize/etape(7) 37 707 azy B5 down azym 38 1590 baize 3B across baize/etape(7) 39 265 ... quinoa 1D across quinoa/ag(3) 78 151 bezonin A2 down bezonian 79 12 nounier 3A across nounier/etape(7)/rob(6) 79 12 bonnier 3A across bonnier/etape(7)/rob(6) 83 12 zeriba 1D across zeriba/ag(3) 84 75 annoyer 3A across annoyer/etape(7)/rob(6) 85 12 bronzen 3A across bronzen/etape(7)/nob(6) 101 12 zebrina 1C across zebrina/ag(3) 110 25 baroque 1D across baroque/ug(3)/el(2) 118 12 brunize B1 down brunizem 132 25 */ typedef struct playfm { char place[8]; char pos[4]; char dirn; int score; int freq; int cumfreq; } playfm; void confidence(int percentile, playfm *play, int nextfree, int cumfreq) { int i, target = cumfreq * percentile / 100; for (i = 0; i < nextfree; i++) { if (play[i].cumfreq >= target) { fprintf(stdout, "My opponent's move is unlikely to score above %d," " at a %d%% confidence level "//"(cumfreq%d] = %d)\n" "\n", play[i].score, percentile//, i, play[i].cumfreq ); return; } } fprintf(stdout, "I'm stymied as to what the %d%% confidence level should be!\n", percentile); } int main(int argc, char **argv) { playfm play[10000]; char forms[1024]; int nextfree = 0; int cumfreq = 0; int rc; for (;;) { rc = fscanf(stdin, "%s %s %s %s %d %d", &play[nextfree].place, &play[nextfree].pos, &play[nextfree].dirn, forms, &play[nextfree].score, &play[nextfree].freq ); if (rc != 6) break; cumfreq += play[nextfree].freq; play[nextfree].cumfreq = cumfreq; nextfree += 1; } fprintf(stdout, "%d plays analysed.\n", nextfree); fprintf(stdout, "Total no of draws = %d\n", cumfreq); confidence(0, play, nextfree, cumfreq); confidence(10, play, nextfree, cumfreq); confidence(50, play, nextfree, cumfreq); confidence(90, play, nextfree, cumfreq); confidence(100, play, nextfree, cumfreq); }