-
Notifications
You must be signed in to change notification settings - Fork 11
/
cryptarithm-gen.raku
65 lines (52 loc) · 1.81 KB
/
cryptarithm-gen.raku
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
#!/usr/bin/env raku
sub cryptarithm-gen (@nums, @words) {
my Set $words = @words.Set;
my @digits = @nums.map({ .comb.Slip }).unique;
my sub gen (%letter-from-digit) {
return if @nums.first({
.comb.map({ %letter-from-digit{$_} }).Array.&{
.all && .join() ∉ $words
}});
my $d = @digits.first({ %letter-from-digit{$_}:!exists });
my @solutions;
unless $d.defined {
@solutions.push( %letter-from-digit );
return @solutions;
}
for (("A".."Z") (-) %letter-from-digit.values).keys.sort -> $c {
my @s = gen(%( %letter-from-digit, $d => $c ));
@solutions.append(@s) if @s.elems > 0;
}
return @solutions.grep(&defined);
}
gen(%());
}
sub print-solution (@nums, %letter-from-digit) {
say "\t" ~ @nums.map({ $_ ~ " = " ~ .comb.map({ %letter-from-digit{$_} }).join }).join(", ");
}
sub gen-cryptarithm-then-print ($expr, @words) {
my @nums = $expr.comb(/<[0..9]>+/);
my @solutions = cryptarithm-gen(@nums, @words);
if @solutions.any {
say "# Cryptarithm for: $expr";
for @solutions -> $s {
print-solution(@nums, $s);
}
} else {
say "# Cryptarithm for: $expr\n Not found.";
}
}
sub MAIN (Bool :$primes = False, Str :$expr = "") {
my @words = "/usr/share/dict/words".IO.lines.map(&uc).grep({ .chars < 11 || .comb.unique.elems < 11 });
if $primes {
my @primes =(1000..99999).grep(&is-prime);
for @primes.combinations(2) -> ($n1, $n2) {
my $n = $n1 + $n2;
gen-cryptarithm-then-print("$n1 + $n2 = $n", @words);
}
} elsif $expr ne "" {
gen-cryptarithm-then-print($expr, @words);
} else {
say "What do you want me to do ?";
}
}