in reply to Wordfeud racks
I eventually ended up in a completly different direction writing the following code. (and borrowing the nCr function from here 68077 )
use strict; use warnings; sub nCr { my ($n, $r) = @_; my $res = 1; for my $i (1..$r) { $res *= $n--; $res /= $i; } $res; } my %bag = ( "\@" => 2, # blank 'A' => 9, 'B' => 2, 'C' => 2, 'D' => 4, 'E' => 12, 'F' => 2, 'G' => 3, 'H' => 2, 'I' => 9, 'J' => 1, 'K' => 1, 'L' => 4, 'M' => 2, 'N' => 6, 'O' => 8, 'P' => 2, 'Q' => 1, 'R' => 6, 'S' => 4, 'T' => 6, 'U' => 4, 'V' => 2, 'W' => 2, 'X' => 1, 'Y' => 2, 'Z' => 1, ); my $compute_prob = 1; my $racksize = 7; my $total_number_of_tiles; foreach my $char (keys %bag) { $total_number_of_tiles += $bag{$char}; } my @letters = sort keys %bag; my %pos; foreach my $i (0 .. $#letters) { $pos{$letters[$i]} = $i; } my $all_combinations = nCr($total_number_of_tiles, $racksize); my %counter = (1 => '', 2 => '',3 => '',4 => '',5 => '',6 => '',7 => ' +',); foreach my $s1 (@letters) { %counter = ($s1 => 1); foreach my $s2 (@letters[$pos{$s1}..$#letters]) { $counter{$s2}++; if ($counter{$s2} > $bag{$s2}) { $counter{$s2}--; next; } foreach my $s3 (@letters[$pos{$s2}..$#letters]) { $counter{$s3}++; if ($counter{$s3} > $bag{$s3}) { $counter{$s3}--; next; } foreach my $s4 (@letters[$pos{$s3}..$#letters]) { $counter{$s4}++; if ($counter{$s4} > $bag{$s4}) { $counter{$s4}--; next; } foreach my $s5 (@letters[$pos{$s4}..$#letters]) { $counter{$s5}++; if ($counter{$s5} > $bag{$s5}) { $counter{$s5}--; next; } foreach my $s6 (@letters[$pos{$s5}..$#letters]) { $counter{$s6}++; if ($counter{$s6} > $bag{$s6}) { $counter{$s6}--; next; } foreach my $s7 (@letters[$pos{$s6}..$#letters] +) { $counter{$s7}++; if ($counter{$s7} > $bag{$s7}) { $counter{$s7}--; next; } my $rack = join '', $s1,$s2,$s3,$s4,$s5,$s +6,$s7; if ($compute_prob) { my $thiscombo = 1; foreach my $c (keys %counter) { my $in_bag = $bag{$c}; my $in_rack = $counter{$c}; my $res = nCr($in_bag, $in_rack); $thiscombo *= $res; } my $probability = sprintf("%.5g", $thi +scombo/$all_combinations); print "$rack $probability\n"; } else { print "$rack\n"; } $counter{$s7}--; } $counter{$s6}--; } $counter{$s5}--; } $counter{$s4}--; } $counter{$s3}--; } $counter{$s2}--; } $counter{$s1}--; } __END__
Just listing the 3199724 racks takes about 6 seconds on my old laptop running Win7 32 bit. When also computing the probabilities it toke 2 minutes and 46 seconds to complete.
/L
|
|---|