1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
#!/usr/bin/perl
# Test: ./ch-2.pl
use strict;
use warnings;
use feature qw /say/;
use Algorithm::Combinatorics qw(variations);
use List::Util qw(shuffle);
# Store valid words
our %valid_words;
# Tiles metadata
our %tiles_metadata = (
A => { points => 1, amount => 8 },
B => { points => 4, amount => 5 },
C => { points => 5, amount => 4 },
D => { points => 3, amount => 3 },
E => { points => 2, amount => 9 },
F => { points => 3, amount => 3 },
G => { points => 1, amount => 3 },
H => { points => 5, amount => 3 },
I => { points => 1, amount => 5 },
J => { points => 2, amount => 3 },
K => { points => 10, amount => 2 },
L => { points => 2, amount => 3 },
M => { points => 5, amount => 4 },
N => { points => 4, amount => 4 },
O => { points => 5, amount => 3 },
P => { points => 3, amount => 5 },
Q => { points => 10, amount => 2 },
R => { points => 2, amount => 3 },
S => { points => 1, amount => 7 },
T => { points => 5, amount => 5 },
U => { points => 1, amount => 5 },
V => { points => 2, amount => 3 },
W => { points => 3, amount => 5 },
X => { points => 1, amount => 2 },
Y => { points => 2, amount => 5 },
Z => { points => 1, amount => 5 },
);
# Load the dictionary
load_words('/usr/share/dict/words');
# Grab 7 times
my @tiles = get_tiles(7);
say 'Picked tiles: ' . join ', ', @tiles;
# Find the word with the most points
my ($word, $score) = find_best_word(\@tiles);
say 'Best word: ' . $word .
' with score: ' . $score;
# Load the dictionary into memory
sub load_words {
my $filename = shift;
open(my $fh, '<:encoding(UTF-8)', $filename) || die "$@";
while (my $row = <$fh>) {
chomp $row;
$valid_words{uc($row)} = 1;
}
}
# Get tiles
sub get_tiles {
my $no_tiles = shift;
# Generate the set of tiles
my @tileset;
for my $key (keys %tiles_metadata) {
for my $i (1 .. $tiles_metadata{$key}->{amount}) {
push @tileset, $key;
}
}
# Get Seven tiles
my @shuffled_indexes = shuffle(0..$#tileset);
my @my_tiles =
@tileset[
@shuffled_indexes[ 0 .. $no_tiles -1 ]
];
return @my_tiles;
}
# Find the best word
sub find_best_word {
my $tiles_ref = shift;
my $top_score = 0;
my $top_word;
# Generate the possible combinations
for my $i (1..7) {
my $iter = variations($tiles_ref,$i);
# Loop through each variation
while (my $v = $iter->next) {
my $word = join '', @{$v};
if ($valid_words{$word}) {
my $score = calculate_score($v);
# If this is the best word store it
if ($score > $top_score) {
$top_score = $score;
$top_word = $word;
}
}
}
}
return $top_word, $top_score;
}
# Calculate score
sub calculate_score {
my $word_ref = shift;
my $score = 0;
for my $letter (@${word_ref}) {
$score += $tiles_metadata{$letter}->{points};
}
return $score;
}
|