SEND + MORE = MONEY: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|Phix}}: minor tidy)
(21 intermediate revisions by 11 users not shown)
Line 91: Line 91:
next e
next e
next s</syntaxhighlight>
next s</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>

==={{header|Gambas}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="gambas">Public Sub Main()

Dim m, s, e, n, d, o, r, y As Byte
m = 1
For s = 8 To 9
For e = 0 To 9
If e <> m And e <> s Then
For n = 0 To 9
If n <> m And n <> s And n <> e Then
For d = 0 To 9
If d <> m And d <> s And d <> e And d <> n Then
For o = 0 To 9
If o <> m And o <> s And o <> e And o <> n And o <> d Then
For r = 0 To 9
If r <> m And r <> s And r <> e And r <> n And r <> d And r <> o Then
For y = 0 To 9
If y <> m And y <> s And y <> e And y <> n And y <> d And y <> o Then
If ((1000*(s+m)) + (100*(e+o)) + (10*(n+r)) + (d+e)) = ((10000* m) + (1000*o) + (100*n) + (10*e) + y) Then
Print s & e & n & d & " + " & m & o & r & e & " = " & m & o & n & e & y
End If
End If
Next
End If
Next
End If
Next
End If
Next
End If
Next
End If
Next
Next

End</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>

==={{header|Run BASIC}}===
{{works with|Just BASIC}}
{{works with|Liberty BASIC}}
<syntaxhighlight lang="lb"></syntaxhighlight>

==={{header|PureBasic}}===
<syntaxhighlight lang="PureBasic">OpenConsole()
m.i = 1
For s.i = 8 To 9
For e.i = 0 To 9
If e <> m And e <> s
For n.i = 0 To 9
If n <> m And n <> s And n <> e
For d.i = 0 To 9
If d <> m And d <> s And d <> e And d <> n
For o.i = 0 To 9
If o <> m And o <> s And o <> e And o <> n And o <> d
For r.i = 0 To 9
If r <> m And r <> s And r <> e And r <> n And r <> d And r <> o
For y.i = 0 To 9
If y <> m And y <> s And y <> e And y <> n And y <> d And y <> o
If ((1000*(s+m))+(100*(e+o))+(10*(n+r))+(d+e)) = ((10000*m)+(1000*o)+(100*n)+(10*e)+y)
PrintN(Str(s)+Str(e)+Str(n)+Str(d)+" + "+Str(m)+Str(o)+Str(r)+Str(e)+" = "+Str(m)+Str(o)+Str(n)+Str(e)+Str(y))
EndIf
EndIf
Next y
EndIf
Next r
EndIf
Next o
EndIf
Next d
EndIf
Next n
EndIf
Next e
Next s
CloseConsole()</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>

==={{header|True BASIC}}===
{{works with|QBasic|1.1}}
<syntaxhighlight lang="qbasic">LET m = 1
FOR s = 8 TO 9
FOR e = 0 TO 9
IF e <> m AND e <> s THEN
FOR n = 0 TO 9
IF n <> m AND n <> s AND n <> e THEN
FOR d = 0 TO 9
IF d <> m AND d <> s AND d <> e AND d <> n THEN
FOR o = 0 TO 9
IF o <> m AND o <> s AND o <> e AND o <> n AND o <> d THEN
FOR r = 0 TO 9
IF r <> m AND r <> s AND r <> e AND r <> n AND r <> d AND r <> o THEN
FOR y = 0 TO 9
IF y <> m AND y <> s AND y <> e AND y <> n AND y <> d AND y <> o THEN
IF ((1000*(s+m))+(100*(e+o))+(10*(n+r))+(d+e)) = ((10000*m)+(1000*o)+(100*n)+(10*e)+y) THEN
PRINT STR$(s); STR$(e); STR$(n); STR$(d); " + ";
PRINT STR$(m); STR$(o); STR$(r); STR$(e); " = ";
PRINT STR$(m); STR$(o); STR$(n); STR$(e); STR$(y)
END IF
END IF
NEXT y
END IF
NEXT r
END IF
NEXT o
END IF
NEXT d
END IF
NEXT n
END IF
NEXT e
NEXT s
END</syntaxhighlight>
{{out}}
{{out}}
<pre>Same as FreeBASIC entry.</pre>
<pre>Same as FreeBASIC entry.</pre>
Line 127: Line 247:
{{out}}
{{out}}
<pre>Same as FreeBASIC entry.</pre>
<pre>Same as FreeBASIC entry.</pre>

=={{header|C}}==
{{trans|Julia}}
<syntaxhighlight lang="c">#include <stdio.h>

int main() {
int m = 1, s, e, n, d, o, r, y, sum1, sum2;
const char *f = "%d%d%d%d + %d%d%d%d = %d%d%d%d%d\n";
for (s = 8; s < 10; ++s) {
for (e = 0; e < 10; ++e) {
if (e == m || e == s) continue;
for (n = 0; n < 10; ++n) {
if (n == m || n == s || n == e) continue;
for (d = 0; d < 10; ++d) {
if (d == m || d == s || d == e || d == n) continue;
for (o = 0; o < 10; ++o) {
if (o == m || o == s || o == e || o == n || o == d) continue;
for (r = 0; r < 10; ++r) {
if (r == m || r == s || r == e || r == n || r == d || r == o) continue;
for (y = 0; y < 10; ++y) {
if (y == m || y == s || y == e || y == n || y == d || y == o) continue;
sum1 = 1000*s + 100*e + 10*n + d + 1000*m + 100*o + 10*r + e;
sum2 = 10000*m + 1000*o + 100*n + 10*e + y;
if (sum1 == sum2) {
printf(f, s, e, n, d, m, o, r, e, m, o, n, e, y);
}
}
}
}
}
}
}
}
return 0;
}</syntaxhighlight>

{{out}}
<pre>
9567 + 1085 = 10652
</pre>


=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
Line 246: Line 406:


Took 1.149804ms.
Took 1.149804ms.
</pre>

=={{header|J}}==
'''Tacit Solution'''
<syntaxhighlight lang="j">SEND=. 10 #. 0 1 2 3&{
MORE=. 10 #. 4 5 6 1&{
MONEY=. 10 #. 4 5 2 1 7&{
M=. 4&{
entry=. 0&{::
try=. 1&{::
sample=. (10 ?~ 8:) ; 1 + try NB. counting tries to avoid a premature convergence
good=. (not=. -.) (o=.@:) (0 = M) (and=. *.) (SEND + MORE) = MONEY
answer=. (": o SEND , ' + ' , ": o MORE , ' = ' , ": o MONEY) o entry
tries=. ', random tries ' , ": o try
while=. ^: (^:_)
solve=. (answer , tries) o (sample while (not o good o entry)) o ( 0 ;~ i.) o 8: f.</syntaxhighlight>

Example use:
<syntaxhighlight lang="j"> solve ''
9567 + 1085 = 10652, random tries 248241
solve ''
9567 + 1085 = 10652, random tries 246504
solve ''
9567 + 1085 = 10652, random tries 3291556</syntaxhighlight>

The code is tacit and fixed (in other words, it is point-free):
<syntaxhighlight lang="j"> _80 [\ (5!:5)<'solve'
((":@:(10 (#.) 0 1 2 3&({ )) , ' + ' , ":@:(10 (#.) 4 5 6 1&({ )) , ' = ' , ":@:
(10 (#.) 4 5 2 1 7&({ )))@:(0&({::)) , ', random tries ' , ":@:(1&({::)))@:(((10
?~ 8:) ; 1 + 1&({::))^:(-.@:(-.@:(0 = 4&({ )) *. ((10 (#.) 0 1 2 3&({ )) + 10 (
#.) 4 5 6 1&({ )) = 10 (#.) 4 5 2 1 7&({ ))@:(0&({::)))^:_)@:(0 ;~ i.)@:8:</syntaxhighlight>

=={{header|jq}}==
{{works with|jq}}
'''Works with gojq, the Go implementation of jq, and with fq'''

Straight out of the [https://en.wikipedia.org/wiki/Jq_(programming_language) wikipedia] page, except for {} instead of [] in the last line of the def:
<syntaxhighlight lang=jq>
def send_more_money:
def choose(m;n;used): ([range(m;n+1)] - used)[];
def num(a;b;c;d): 1000*a + 100*b + 10*c + d;
def num(a;b;c;d;e): 10*num(a;b;c;d) + e;
first(
1 as $m
| 0 as $o
| choose(8;9;[]) as $s
| choose(2;9;[$s]) as $e
| choose(2;9;[$s,$e]) as $n
| choose(2;9;[$s,$e,$n]) as $d
| choose(2;9;[$s,$e,$n,$d]) as $r
| choose(2;9;[$s,$e,$n,$d,$r]) as $y
| select(num($s;$e;$n;$d) + num($m;$o;$r;$e) == num($m;$o;$n;$e;$y))
| {$s,$e,$n,$d,$m,$o,$r,$e,$m,$o,$n,$e,$y} );

send_more_money
</syntaxhighlight>
{{output}}
<pre>
{"s":9,"e":5,"n":6,"d":7,"m":1,"o":0,"r":8,"y":2}
</pre>
</pre>


Line 283: Line 510:
end
end
</syntaxhighlight>{{out}} 9567 + 1085 == 10652
</syntaxhighlight>{{out}} 9567 + 1085 == 10652

=={{header|Nim}}==
{{trans|Julia}}
<syntaxhighlight lang="Nim">import std/strformat

let m = 1
for s in 8..9:
for e in 0..9:
if e in [m, s]: continue
for n in 0..9:
if n in [m, s, e]: continue
for d in 0..9:
if d in [m, s, e, n]: continue
for o in 0..9:
if o in [m, s, e, n, d]: continue
for r in 0..9:
if r in [m, s, e, n, d, o]: continue
for y in 0..9:
if y in [m, s, e, n, d, o]: continue
if 1000 * s + 100 * e + 10 * n + d + 1000 * m + 100 * o + 10 * r + e ==
10000 * m + 1000 * o + 100 * n + 10 * e + y:
echo &"{s}{e}{n}{d} + {m}{o}{r}{e} = {m}{o}{n}{e}{y}"
</syntaxhighlight>

{{out}}
<pre>9567 + 1085 = 10652
</pre>

=={{header|Pascal}}==
=={{header|Pascal}}==
==={{header|Free Pascal}}===
==={{header|Free Pascal}}===
Line 288: Line 543:
<syntaxhighlight lang="pascal">
<syntaxhighlight lang="pascal">
program SymbolToDigit;
program SymbolToDigit;
{$IFDEF FPC}{$MODE DELPHI}{$Optimization ON,All}{$ENDIF}
{$IFDEF Windows}{$APPTYPE CONSOLE}{$ENDIF}
uses
uses
sysutils;// TDatetime
sysutils;// TDatetime
const
const
nmax = 9;
nmax = 9;
maxLen = 5;
maxLen = 7;

maxIDx = 41;
type
type
tFreeDgt = array[0..nmax+1] of Int32;
tFreeDgt = array[0..nmax+1] of Int32;
tSymbWord = String[maxLen];
tSymbWord = String[maxLen];
tDgtWord = record
tDgtWord = record
DW_DgtsIdx: array[1..maxLen] of UInt8;
DW_DgtsIdx: array[1..maxLen] of UInt8;
DW_maxIdx: Uint8;
DW_maxIdx: Uint8;
end;
end;
tDgtFront = record
DW_DgtsIdx: array[1..nmax+1] of UInt8;
DW_maxIdx: Uint8;
end;
tInUse = set of 0..nmax+1;
const
const
{
// cSumWords : array[0..maxIDx] of tSymbWord =('SEND','MORE','MONEY');
maxIDx = 2;
cSumWords : array[0..maxIDx] of tSymbWord =('SEND','MORE','MONEY');
}
{
maxIDx = 4;
cSumWords : array[0..maxIDx] of tSymbWord =('ABRA','CADABRA','ABRA','CADABRA','HOUDINI');
}


//MANYOTHERS=M2A7N6Y4O1T9H5E0R8S3
//MANYOTHERS=M2A7N6Y4O1T9H5E0R8S3
maxIDx = 41;
//{
cSumWords : array[0..maxIDx] of tSymbWord =(
cSumWords : array[0..maxIDx] of tSymbWord =(
'SO','MANY','MORE','MEN','SEEM','TO','SAY','THAT',
'SO','MANY','MORE','MEN','SEEM','TO','SAY','THAT',
Line 313: Line 584:
'MOON','AS','HE','HAS','AT','THE','OTHER','TEN',
'MOON','AS','HE','HAS','AT','THE','OTHER','TEN',
'TESTS');
'TESTS');

//}
var
var
{$ALIGN 32}
{$ALIGN 32}
DigitSample : tFreeDgt;
DigitSample,
DigitSampleSolution : tFreeDgt;
SymbInUse : array[0..10] of char;
SymbInUse : array[0..10] of char;
DgtToSymb : array[0..10] of UInt8;
Words :array[0..maxIDx] of tSymbWord;
Words :array[0..maxIDx] of tSymbWord;
DgtWords : array[0..maxIDx] of tDgtWord;
DgtWords : array[0..maxIDx] of tDgtWord;
DgtFrontWords :tDgtFront;
SymbInUseCount,gblCount : Uint32;
SymbInUseCount,gblCount : Uint32;
fullStop: boolean;
fullStop: boolean;
ch : char;
ch : char;

procedure OneSol(idx:int32;const DS:tFreeDgt);
var
i,symbolIdx : Int32;
begin
For i := maxlen downto 1 do
begin
symbolIdx := DgtWords[idx].DW_DgtsIdx[i];
if symbolIdx = 0 then
write(' ')
else
write(DS[symbolIdx]);
end;
writeln(cSumWords[idx]:maxLen+2);
end;


procedure RevString(var s:tSymbWord);
procedure RevString(var s:tSymbWord);
Line 342: Line 629:
//CHR(ORD('A')-1) = '@' is placeholder for no Symbol
//CHR(ORD('A')-1) = '@' is placeholder for no Symbol
SymbToIdx : array['@'..'Z'] of byte;
SymbToIdx : array['@'..'Z'] of byte;
FrontSymbols :tInUse;
i,j : Int32;
i,j : Int32;
Begin
Begin
Line 354: Line 642:
//position of highest symbol
//position of highest symbol
DgtWords[i].DW_maxIdx := j;
DgtWords[i].DW_maxIdx := j;
while j < maxLen do
// extend by '@' aka zero
begin
inc(j);
Words[i] := Low(SymbToIdx)+Words[i];
end;
RevString(Words[i]);
RevString(Words[i]);
setlength(Words[i],maxlen);
For j := j+1 to maxLen do
Words[i][j] := Low(SymbToIdx);
end;
end;
// find all symbols


for j := 1 to High(tSymbWord) do
for j := 1 to High(tSymbWord) do
Begin
Begin
For i := 0 to maxIDx do
For i := 0 to maxIdx do
begin
begin
ch := Words[i][j];
ch := Words[i][j];
Line 376: Line 662:
end;
end;
end;
end;
dec(SymbInUseCount);

For i := 0 to maxIDx do
begin
for j := 1 to maxlen do
DgtWords[i].DW_DgtsIdx[j]:= SymbToIdx[Words[i][j]];
end;
For i := 1 to SymbInUseCount do
For i := 1 to SymbInUseCount do
write(SymbInUse[i]);
write(SymbInUse[i]);
writeln(SymbInUseCount-1:4,' symbols');
writeln(SymbInUseCount:4,' symbols');

end;
//get index for every symbol in word
For i := 0 to maxIdx do
with DgtWords[i] do
for j := 1 to High(tSymbWord) do
DW_DgtsIdx[j]:= SymbToIdx[Words[i][j]];
//find all first symbols
FrontSymbols := [];
For i := 0 to maxIDx do
with DgtWords[i] do
include(FrontSymbols,DW_DgtsIdx[DW_maxIdx]);


j := 1;
procedure OneSol(idx:int32);
For i := 0 to nmax+1 do
var
if i in FrontSymbols then
i,symbolIdx : Int32;
Begin
begin
DgtFrontWords.DW_DgtsIdx[j] := i;
For i := maxlen downto 1 do
inc(j);
begin
end;
symbolIdx := DgtWords[idx].DW_DgtsIdx[i];
DgtFrontWords.DW_maxIdx := j-1;
if symbolIdx = 0 then
write(' ')
else
write(DigitSample[symbolIdx]);
end;
writeln(cSumWords[idx]:maxLen+2);
end;
end;


Line 405: Line 692:
var
var
col,row,
col,row,
sum,carrySum,carry : NativeUInt;
sum,carry : NativeUInt;
begin
begin
// No zero as first symbol
// check for zero in first symbols of words
with DgtFrontWords do
For row := maxIdx downto 0 do
with DgtWords[row] do
For col := DW_maxIdx downto 1 do
begin
if DS[DW_DgtsIdx[DW_maxidx]] = 0 then
if DS[DW_DgtsIdx[col]] = 0 then
EXIT(false);
EXIT(false);
end;

carry := 0;
carry := 0;
carrySum := 0;
For col := 1 to maxLen do
For col := 1 to maxLen do
Begin
Begin
sum := carrysum MOD 10;
sum := carry;
carrysum := carrysum DIV 10;
carry := 0;
carry :=0;
// add one column
For row := maxIdx-1 downto 0 do
For row := maxIdx-1 downto 0 do
Begin
sum := sum+DS[DgtWords[row].DW_DgtsIdx[col]];
sum := sum+DS[DgtWords[row].DW_DgtsIdx[col]];
if sum > 9 then
begin
if sum > 9 then
begin
carry := sum DIV 10;
sum := sum - 10 * carry;
carry := sum DIV 10;
inc(CarrySum,Carry);
sum := sum - 10 * carry;
end;
end;
end;
//digit of sum
//digit of sum
if sum <> DS[DgtWords[maxIDx].DW_DgtsIdx[col]] then
if sum <> DS[DgtWords[maxIDx].DW_DgtsIdx[col]] then
EXIT(false);
EXIT(false);
end;
end;
if carrysum <>0 then
If Carry = 0 then
DigitSampleSolution := DS;
EXIT(false);
For row := 0 to High(DgtWords)do
OneSol(row);
EXIT(true);
EXIT(true);
end;
end;
Line 445: Line 729:
i,Col : nativeInt;
i,Col : nativeInt;
begin
begin
if fullStop then
if fullStop then EXIT;
EXIT;
IF row <= 10 then
IF row <= 10 then
begin
begin
Line 468: Line 751:
end
end
end;
end;

var
var
T1,T0: TDateTime;
T1,T0: TDateTime;
i : Uint32;
i,j : Uint32;


begin
begin
Line 483: Line 767:
NextPermute(1,DigitSample);
NextPermute(1,DigitSample);
t1:= time;
t1:= time;
IF maxIDx < 10 then
For i := 0 to High(DgtWords)do
OneSol(i,DigitSampleSolution);
writeln;
For i := 1 to SymbInUseCount do
begin
j := DigitSampleSolution[i];
write(SymbInUse[i],'=',j,' ');
end;
writeln;
writeln;
WriteLn(gblCount,' checks ',FormatDateTime(' NN:SS.ZZZ',T1-t0),' secs');
WriteLn(gblCount,' checks ',FormatDateTime(' NN:SS.ZZZ',T1-t0),' secs');
end.</syntaxhighlight>
end.
</syntaxhighlight>
{{out|@TIO.RUN}}
{{out|@TIO.RUN}}
<pre>
<pre>
8 symbols
DEYNROSM 8 symbols
9567 SEND
9567 SEND
1085 MORE
1085 MORE
10652 MONEY
10652 MONEY


D=7 E=5 Y=2 N=6 R=8 O=0 S=9 M=1
2704147 checks 00:00.090 secs
2704147 checks 00:00.043 secs
OYENMTSRAH
//shorthened 'SO','MANY','MORE','MEN','SEEM','TO','SAY',
10 symbols
OYENMTSRAH 10 symbols
31 SO
2764 MANY
2180 MORE
206 MEN
3002 SEEM
91 TO
374 SAY
9579 THAT
9504 THEY
274 MAY
3116 SOON
984 TRY
91 TO
3974 STAY
79 AT
5120 HOME
31 SO
73 AS
91 TO
300 SEE
18 OR
5078 HEAR
950 THE
3720 SAME
160 ONE
276 MAN
984 TRY
91 TO
2009 MEET
950 THE
9072 TEAM
16 ON
950 THE
2116 MOON
73 AS
50 HE
573 HAS
79 AT
950 THE
19508 OTHER
906 TEN
90393 TESTS


O=1 Y=4 E=0 N=6 M=2 T=9 S=3 R=8 A=7 H=5
496179 checks 00:00.061 secs
496179 checks 00:00.013 secs</pre>
</pre>

=={{header|Perl}}==
{{trans|Raku}}
=== Exhaustive ===
<syntaxhighlight lang="perl" line>use v5.36;
use enum <D E M N O R S Y>;
use Algorithm::Combinatorics <combinations permutations>;

sub solve {
for my $p (map { permutations $_ } combinations [0..9], 8) {
return $p if @$p[M] > 0 and join('',@$p[S,E,N,D])+join('',@$p[M,O,R,E]) == join('',@$p[M,O,N,E,Y]);
}
}

printf "SEND + MORE == MONEY\n%d + %d == %d", join('',@$_[S,E,N,D]), join('',@$_[M,O,R,E]), join '',@$_[M,O,N,E,Y]) for solve();</syntaxhighlight>
{{out}}
<pre>SEND + MORE == MONEY
9567 + 1085 == 10652</pre>
=== Fine-tuned ===
<syntaxhighlight lang="perl" line>use v5.36;

my $s = 7;
while (++$s <= 9) {
my $e = -1;
while (++$e <= 9) {
next if $e == $s;
my $n = -1;
while (++$n <= 9) {
next if grep { $n == $_ } $s,$e;
my $d = -1;
while (++$d <= 9) {
next if grep { $d == $_ } $s,$e,$n;
my $send = $s*10**3 + $e*10**2 + $n*10 + $d;
my ($m, $o) = (1, -1);
while (++$o <= 9) {
next if grep { $o == $_ } $s,$e,$n,$d,$m;
my $r = -1;
while (++$r <= 9) {
next if grep { $r == $_ } $s,$e,$n,$d,$m,$o;
my $more = $m*10**3 + $o*10**2 + $r*10 + $e;
my $y = -1;
while (++$y <= 9) {
next if grep { $y == $_ } $s,$e,$n,$d,$m,$o,$r;
my $money = $m*10**4 + $o*10**3 + $n*10**2 + $e*10 + $y;
next unless $send + $more == $money;
say "SEND + MORE == MONEY\n$send + $more == $money";
}
}
}
}
}
}
}

</syntaxhighlight>
{{out}}
<pre>SEND + MORE == MONEY
9567 + 1085 == 10652</pre>


=={{header|Phix}}==
=={{header|Phix}}==
<!--(phixonline)-->
Mighta gota bit carried away here...
<!--<syntaxhighlight lang="phix">(phixonline)-->
<syntaxhighlight lang="phix">
atom t0 = time()
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
constant mp = new_dict() -- keys 'A'..'Z', values 0..9
<span style="color: #004080;">sequence</span> <span style="color: #000000;">answer</span>
sequence front, -- 1 if wordstart, else 0, for (0|1)..9
<span style="color: #008080;">procedure</span> <span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">sums</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solve_order</span><span style="color: #0000FF;">,</span><span style="color: #000000;">firsts</span><span style="color: #0000FF;">,</span><span style="color: #000000;">correct_to</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">,</span><span style="color: #000000;">avail</span><span style="color: #0000FF;">,</span><span style="color: #000000;">done</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
multh, -- multiplier hash, see below
<span style="color: #000000;">done</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
used
<span style="color: #004080;">integer</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">solve_order</span><span style="color: #0000FF;">[</span><span style="color: #000000;">done</span><span style="color: #0000FF;">]</span>

<span style="color: #008080;">for</span> <span style="color: #000000;">ad</span><span style="color: #0000FF;">=</span><span style="color: #000000;">firsts</span><span style="color: #0000FF;">[</span><span style="color: #000000;">done</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
-- mp ends up holding the (first) acceptable solution.
<span style="color: #004080;">integer</span> <span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ad</span><span style="color: #0000FF;">)</span>
-- Letters which start any word cannot be 0 (in the rules).
<span style="color: #008080;">if</span> <span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">avail</span><span style="color: #0000FF;">,</span><span style="color: #000000;">m</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
-- In SEND+MORE=MONEY, 'E' is 100 + 1 - 10 = 91 from the
<span style="color: #000000;">answer</span><span style="color: #0000FF;">[</span><span style="color: #000000;">d</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ad</span>
-- three places E occurs in the puzzle, stored in multh.
<span style="color: #004080;">integer</span> <span style="color: #000000;">ct</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">correct_to</span><span style="color: #0000FF;">[</span><span style="color: #000000;">done</span><span style="color: #0000FF;">]</span>
-- Hence sum(letter_values*multh)==0 means it is solved.
<span style="color: #008080;">if</span> <span style="color: #000000;">ct</span> <span style="color: #008080;">then</span>
-- Obviously used stops us using digits more than once.
<span style="color: #004080;">integer</span> <span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">bOK</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>

<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">ct</span> <span style="color: #008080;">do</span>
function solve_rec(string uniq, int i, atom s)
<span style="color: #000000;">carry</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">answer</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sums</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]))</span>
-- Aside: integer s is fine on 64-bit, but reaches
<span style="color: #008080;">if</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">carry</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">answer</span><span style="color: #0000FF;">[</span><span style="color: #000000;">sums</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]]</span> <span style="color: #008080;">then</span>
-- a high of 13,304,757,742 & crashes on 32-bit.
<span style="color: #000000;">bOK</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
if i > length(uniq) then return s==0 end if
<span style="color: #008080;">exit</span>
integer chdx = uniq[i]-'A'+1
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
for v=front[chdx] to 9 do
<span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">carry</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
if not used[v+1] then
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
used[v+1] = true
<span style="color: #008080;">if</span> <span style="color: #000000;">bOK</span> <span style="color: #008080;">then</span>
if solve_rec(uniq,i+1,s+v*multh[chdx]) then
<span style="color: #008080;">if</span> <span style="color: #000000;">ct</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sums</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
setd(uniq[i],v,mp)
<span style="color: #008080;">if</span> <span style="color: #000000;">carry</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
return true
<span style="color: #0000FF;">?</span><span style="color: #000000;">answer</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">else</span>
used[v+1] = false
end if
<span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sums</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solve_order</span><span style="color: #0000FF;">,</span><span style="color: #000000;">firsts</span><span style="color: #0000FF;">,</span><span style="color: #000000;">correct_to</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,</span><span style="color: #000000;">avail</span><span style="color: #0000FF;">-</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #000000;">done</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return false
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">else</span>

<span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sums</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solve_order</span><span style="color: #0000FF;">,</span><span style="color: #000000;">firsts</span><span style="color: #0000FF;">,</span><span style="color: #000000;">correct_to</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,</span><span style="color: #000000;">avail</span><span style="color: #0000FF;">-</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #000000;">done</span><span style="color: #0000FF;">)</span>
function solve(string puzzle)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
destroy_dict(mp,true) -- empty, but keep
<span style="color: #000000;">answer</span><span style="color: #0000FF;">[</span><span style="color: #000000;">d</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span>
used = repeat(false,10) -- nb [1..10] for 0..9
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
multh = repeat(0,26) -- see above
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
front = repeat(0,26) -- 1 if 1st in any word
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
string uniq = ""
sequence words = split_any(puzzle," +=\n")
<span style="color: #008080;">procedure</span> <span style="color: #000000;">cryptarithm</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
for iw,word in words do
<span style="color: #004080;">integer</span> <span style="color: #000000;">eq</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'='</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
front[word[1]-'A'+1] = 1
<span style="color: #004080;">sequence</span> <span style="color: #000000;">ans</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">eq</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$]),</span>
integer l = length(word),
<span style="color: #000000;">words</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">eq</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #008000;">'+'</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">trim</span><span style="color: #0000FF;">),</span>
m = iff(iw=length(words)?-1:+1)
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">unique</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)&</span><span style="color: #000000;">ans</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"STABLE"</span><span style="color: #0000FF;">),</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)</span>
for i,ch in word do
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span>
multh[ch-'A'+1] += m*power(10,l-i)
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">w</span> <span style="color: #008080;">in</span> <span style="color: #000000;">words</span> <span style="color: #008080;">do</span>
if not find(ch,uniq) then
<span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">}})</span>
uniq &= ch
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end if
<span style="color: #000000;">ans</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">ans</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">}})</span>
end for
<span style="color: #004080;">sequence</span> <span style="color: #000000;">sums</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span>
end for
<span style="color: #000000;">solve_order</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
if not solve_rec(uniq,1,0) then
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ans</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
return "no solution"
<span style="color: #004080;">sequence</span> <span style="color: #000000;">set</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
end if
<span style="color: #008080;">for</span> <span style="color: #000000;">w</span> <span style="color: #008080;">in</span> <span style="color: #000000;">words</span> <span style="color: #008080;">do</span>
for i,ch in puzzle do
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">w</span><span style="color: #0000FF;">)>=</span><span style="color: #000000;">i</span> <span style="color: #008080;">then</span>
if ch>='A' and ch<='Z' then
<span style="color: #004080;">integer</span> <span style="color: #000000;">wi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">w</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
puzzle[i] = getd(ch,mp)+'0'
<span style="color: #000000;">set</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">wi</span>
end if
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">wi</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solve_order</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
end for
<span style="color: #000000;">solve_order</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">wi</span>
return puzzle
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
constant tests = {
<span style="color: #004080;">integer</span> <span style="color: #000000;">ai</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ans</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
"SEND + MORE == MONEY",
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ai</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solve_order</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
"I + BB == ILL",
<span style="color: #000000;">solve_order</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">ai</span>
"A == B",
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
"ACA + DD == BD",
<span style="color: #000000;">sums</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sums</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">set</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ai</span><span style="color: #0000FF;">})</span>
"A + A + A + A + A + A + A + A + A + A + A + B == BCC",
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
"AS + A == MOM",
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solve_order</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">l</span><span style="color: #0000FF;">)</span>
"NO + NO + TOO == LATE",
<span style="color: #004080;">sequence</span> <span style="color: #000000;">firsts</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">),</span>
"HE + SEES + THE == LIGHT",
<span style="color: #000000;">correct_to</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">)</span>
"AND + A + STRONG + OFFENSE + AS + A + GOOD == DEFENSE",
<span style="color: #008080;">for</span> <span style="color: #000000;">f</span> <span style="color: #008080;">in</span> <span style="color: #7060A8;">unique</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">extract</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">words</span><span style="color: #0000FF;">,{{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}}}),{})&</span><span style="color: #000000;">ans</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">do</span>
"SIX + SEVEN + SEVEN = TWENTY",
<span style="color: #000000;">firsts</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solve_order</span><span style="color: #0000FF;">)]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
"THIS+A+FIRE+THEREFORE+FOR+ALL+HISTORIES+I+TELL+A+TALE+THAT+"&
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
"FALSIFIES+ITS+TITLE+TIS+A+LIE+THE+TALE+OF+THE+LAST+FIRE+"&
<span style="color: #004080;">integer</span> <span style="color: #000000;">mm</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
"HORSES+LATE+AFTER+THE+FIRST+FATHERS+FORESEE+THE+HORRORS+THE+"&
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fs</span> <span style="color: #008080;">in</span> <span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sums</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">flatten</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
"LAST+FREE+TROLL+TERRIFIES+THE+HORSES+OF+FIRE+THE+TROLL+RESTS+"&
<span style="color: #004080;">integer</span> <span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">fs</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">solve_order</span><span style="color: #0000FF;">}}))</span>
"AT+THE+HOLE+OF+LOSSES+IT+IS+THERE+THAT+SHE+STORES+ROLES+OF+"&
<span style="color: #000000;">mm</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mm</span><span style="color: #0000FF;">)</span>
"LEATHERS+AFTER+SHE+SATISFIES+HER+HATE+OFF+THOSE+FEARS+A+TASTE+"&
<span style="color: #000000;">correct_to</span><span style="color: #0000FF;">[</span><span style="color: #000000;">mm</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
"RISES+AS+SHE+HEARS+THE+LEAST+FAR+HORSE+THOSE+FAST+HORSES+THAT+"&
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
"FIRST+HEAR+THE+TROLL+FLEE+OFF+TO+THE+FOREST+THE+HORSES+THAT+"&
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #000000;">correct_to</span><span style="color: #0000FF;">[$]=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sums</span><span style="color: #0000FF;">))</span>
"ALERTS+RAISE+THE+STARES+OF+THE+OTHERS+AS+THE+TROLL+ASSAILS+AT+"&
<span style="color: #000000;">answer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">)</span>
"THE+TOTAL+SHIFT+HER+TEETH+TEAR+HOOF+OFF+TORSO+AS+THE+LAST+HORSE"&
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s - %s is "</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">})</span>
"+FORFEITS+ITS+LIFE+THE+FIRST+FATHERS+HEAR+OF+THE+HORRORS+THEIR+"&
<span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sums</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solve_order</span><span style="color: #0000FF;">,</span><span style="color: #000000;">firsts</span><span style="color: #0000FF;">,</span><span style="color: #000000;">correct_to</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0b1_111_111_111</span><span style="color: #0000FF;">)</span>
"FEARS+THAT+THE+FIRES+FOR+THEIR+FEASTS+ARREST+AS+THE+FIRST+FATHERS"&
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
"+RESETTLE+THE+LAST+OF+THE+FIRE+HORSES+THE+LAST+TROLL+HARASSES+"&
"THE+FOREST+HEART+FREE+AT+LAST+OF+THE+LAST+TROLL+ALL+OFFER+THEIR+"&
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span>
"FIRE+HEAT+TO+THE+ASSISTERS+FAR+OFF+THE+TROLL+FASTS+ITS+LIFE+"&
<span style="color: #008000;">`SEND+MORE=MONEY`</span><span style="color: #0000FF;">,</span>
"SHORTER+AS+STARS+RISE+THE+HORSES+REST+SAFE+AFTER+ALL+SHARE+HOT+"&
<span style="color: #008000;">`TO+GO=OUT`</span><span style="color: #0000FF;">,</span>
"FISH+AS+THEIR+AFFILIATES+TAILOR+A+ROOFS+FOR+THEIR+SAFE == FORTRESSES",
<span style="color: #008000;">`SEND + A + TAD + MORE = MONEY`</span><span style="color: #0000FF;">,</span>
"TO + GO = OUT",
<span style="color: #008000;">`ABRA + CADABRA + ABRA + CADABRA = HOUDINI`</span><span style="color: #0000FF;">,</span>
"SEND + A + TAD + MORE = MONEY",
<span style="color: #008000;">`I + GUESS + THE + TRUTH = HURTS`</span><span style="color: #0000FF;">,</span>
"ABRA + CADABRA + ABRA + CADABRA = HOUDINI",
<span style="color: #008000;">`THATS + THE + THEORY = ANYWAY`</span><span style="color: #0000FF;">,</span>
"I + GUESS + THE + TRUTH = HURTS",
<span style="color: #000080;font-style:italic;">-- tad slow, 5.8s vs 0.2s for all above:</span>
"THATS + THE + THEORY = ANYWAY",
<span style="color: #008000;">`SO+MANY+MORE+MEN+SEEM+TO+SAY+THAT+
`SO + MANY + MORE + MEN + SEEM + TO + SAY + THAT +
THEY+MAY+SOON+TRY+TO+STAY+AT+HOME+
THEY + MAY + SOON + TRY + TO + STAY + AT + HOME +
SO+AS+TO+SEE+OR+HEAR+THE+SAME+ONE+
MAN+TRY+TO+MEET+THE+TEAM+ON+THE+
SO + AS + TO + SEE + OR + HEAR + THE + SAME + ONE +
MAN + TRY + TO + MEET + THE + TEAM + ON + THE +
MOON+AS+HE+HAS+AT+THE+OTHER+TEN
MOON + AS + HE + HAS + AT + THE + OTHER + TEN =TESTS`,
=TESTS`</span><span style="color: #0000FF;">}</span>
}
<span style="color: #7060A8;">papply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cryptarithm</span><span style="color: #0000FF;">)</span>

<!--</syntaxhighlight>-->
for t in tests do
printf(1,"%s\n%s\n\n",{shorten(t,""),shorten(solve(t),"")})
end for
?elapsed(time()-t0)
</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
SEND+MORE=MONEY - SENDMORY is {9,5,6,7,1,0,8,2}
SEND + MORE == MONEY
9567 + 1085 == 10652
TO+GO=OUT - TOGU is {2,1,8,0}

SEND + A + TAD + MORE = MONEY - SENDATMORY is {9,2,8,3,7,4,1,0,6,5}
I + BB == ILL
ABRA + CADABRA + ABRA + CADABRA = HOUDINI - ABRCDHOUIN is {7,4,5,1,9,3,6,0,8,2}
1 + 99 == 100
I + GUESS + THE + TRUTH = HURTS - IGUESTHR is {5,2,6,8,1,4,7,9}

THATS + THE + THEORY = ANYWAY - THASEORYNW is {8,6,9,7,3,2,4,1,5,0}
A == B
SO+MANY+MORE+MEN+SEEM+TO+SAY+THAT+
no solution
THEY+MAY+SOON+TRY+TO+STAY+AT+HOME+

SO+AS+TO+SEE+OR+HEAR+THE+SAME+ONE+
ACA + DD == BD
MAN+TRY+TO+MEET+THE+TEAM+ON+THE+
no solution
MOON+AS+HE+HAS+AT+THE+OTHER+TEN

=TESTS - SOMANYRETH is {3,1,2,7,6,4,8,0,9,5}
A + A + A + A + A + ...A + A + A + B == BCC
9 + 9 + 9 + 9 + 9 + ...9 + 9 + 9 + 1 == 100

AS + A == MOM
92 + 9 == 101

NO + NO + TOO == LATE
74 + 74 + 944 == 1092

HE + SEES + THE == LIGHT
54 + 9449 + 754 == 10257

AND + A + STRONG + O... A + GOOD == DEFENSE
503 + 5 + 691208 + 2... 5 + 8223 == 3474064

SIX + SEVEN + SEVEN = TWENTY
650 + 68782 + 68782 = 138214

THIS+A+FIRE+THEREFOR...R+SAFE == FORTRESSES
9874+1+5730+98030563...3+4150 == 5639304404

TO + GO = OUT
21 + 81 = 102

SEND + A + TAD + MORE = MONEY
9283 + 7 + 473 + 1062 = 10825

ABRA + CADABRA + ABRA + CADABRA = HOUDINI
7457 + 1797457 + 7457 + 1797457 = 3609828

I + GUESS + THE + TRUTH = HURTS
5 + 26811 + 478 + 49647 = 76941

THATS + THE + THEORY = ANYWAY
86987 + 863 + 863241 = 951091

SO + MANY + MORE + M...+ OTHER + TEN =TESTS
31 + 2764 + 2180 + 2...+ 19508 + 906 =90393

"4.8s"
</pre>
</pre>


Line 687: Line 1,041:
+ 1085
+ 1085
= 10652
= 10652
</pre>

=={{header|Python}}==
{{trans|Nim}}
<syntaxhighlight lang="python3">
# SEND + MORE = MONEY by xing216
m = 1
for s in range(8,10):
for e in range(10):
if e in [m, s]: continue
for n in range(10):
if n in [m, s, e]: continue
for d in range(10):
if d in [m, s, e, n]: continue
for o in range(10):
if o in [m, s, e, n, d]: continue
for r in range(10):
if r in [m, s, e, n, d, o]: continue
for y in range(10):
if y in [m, s, e, n, d, o]: continue
if 1000 * s + 100 * e + 10 * n + d + 1000 * m + 100 * o + 10 * r + e == \
10000 * m + 1000 * o + 100 * n + 10 * e + y:
print(f"{s}{e}{n}{d} + {m}{o}{r}{e} = {m}{o}{n}{e}{y}")
</syntaxhighlight>
{{out}}
<pre>
9567 + 1085 = 10652
</pre>
</pre>


Line 720: Line 1,101:
=== Fast ===
=== Fast ===
Alternately, a version written in 2015 by [http://strangelyconsistent.org/blog/send-more-money-in-perl6 Carl Mäsak]. Not very concise but quite speedy. Applying the observation that M must be 1 and S must be either 8 or 9 gets the runtime under a tenth of a second.
Alternately, a version written in 2015 by [http://strangelyconsistent.org/blog/send-more-money-in-perl6 Carl Mäsak]. Not very concise but quite speedy. Applying the observation that M must be 1 and S must be either 8 or 9 gets the runtime under a tenth of a second.
<syntaxhighlight lang="raku" line>my int $s = 7;
<syntaxhighlight lang="raku" line>my $s = 7;
while ++$s <= 9 {
while ++$s 9 {
next if $s == 0;
my $e = -1;
while ++$e ≤ 9 {

my int $e = -1;
while ++$e <= 9 {
next if $e == $s;
next if $e == $s;
my $n = -1;
while ++$n ≤ 9 {
next if $n == $s|$e;
my $d = -1;
while ++$d ≤ 9 {
next if $d == $s|$e|$n;


my int $n = -1;
my $send = $s×10³ + $e×10² + $n×10 + $d;
while ++$n <= 9 {
my ($m, $o) = 1, -1;
next if $n == $s;
while ++$o ≤ 9 {
next if $n == $e;
next if $o == $s|$e|$n|$d|$m;

my int $d = -1;
my $r = -1;
while ++$d <= 9 {
while ++$r 9 {
next if $d == $s;
next if $r == $s|$e|$n|$d|$m|$o;
next if $d == $e;
next if $d == $n;
my $more = $m×10³ + $o×10² + $r×10 + $e;
my $y = -1;

my int $send = $s*1000 + $e*100 + $n*10 + $d;
while ++$y ≤ 9 {
next if $y == $s|$e|$n|$d|$m|$o|$r;

my int $m = 1;

my int $o = -1;
while ++$o <= 9 {
next if $o == $s;
next if $o == $e;
next if $o == $n;
next if $o == $d;
next if $o == $m;

my int $r = -1;
while ++$r <= 9 {
next if $r == $s;
next if $r == $e;
next if $r == $n;
next if $r == $d;
next if $r == $m;
next if $r == $o;

my int $more = $m*1000 + $o*100 + $r*10 + $e;

my int $y = -1;
while ++$y <= 9 {
next if $y == $s;
next if $y == $e;
next if $y == $n;
next if $y == $d;
next if $y == $m;
next if $y == $o;
next if $y == $r;


my int $money =
my $money = $m×10⁴ + $o×10³ + $n×10² + $e×10 + $y;
$m*10000 + $o*1000 + $n*100 + $e*10 + $y;
next unless $send + $more == $money;
next unless $send + $more == $money;
say 'SEND + MORE == MONEY';
say 'SEND + MORE == MONEY' ~ "\n$send + $more == $money";
say "$send + $more == $money";
}
}
}
}
Line 868: Line 1,223:
</pre>
</pre>


=={{header|Ring}}==
===original===
<syntaxhighlight lang="ring">
<syntaxhighlight lang="ring">
// Author: Gal Zsolt 2023-02-08
t1 = clock() // start
see "works..." + nl + nl
see "works..." + nl + nl
aListSend = []
aListSend = []
Line 931: Line 1,286:
next
next
next
next
see "Time: "+ clock() - t1 // end
see "done..." + nl
see "done..." + nl
</syntaxhighlight>
</syntaxhighlight>
Line 939: Line 1,293:
SEND = 9567 MORE = 1085 MONEY = 10652
SEND = 9567 MORE = 1085 MONEY = 10652
done...
done...
</pre>
Time: 31.9 s

=={{header|Ruby}}==
Solving for the string "SEND + 1ORE == 1ONEY" using 'tr' , which translates characters to other characters. The resulting string is brutally evalled.
<syntaxhighlight lang="ruby">str = "SEND + 1ORE == 1ONEY"
digits = [0,2,3,4,5,6,7,8,9] # 1 is absent
uniq_chars = str.delete("^A-Z").chars.uniq.join
res = digits.permutation(uniq_chars.size).detect do |perm|
num_str = str.tr(uniq_chars, perm.join)
next if num_str.match?(/\b0/) #no words can start with 0
eval num_str
end
puts str.tr(uniq_chars, res.join)
</syntaxhighlight>
{{out}}
<pre>9567 + 1085 == 10652
</pre>

=={{header|Vala}}==
{{trans|C}}
<syntaxhighlight lang="vala">void main() {
int m = 1, s, e, n, d, o, r, y, sum1, sum2;
string f = "%d%d%d%d + %d%d%d%d = %d%d%d%d%d\n";
for (s = 8; s < 10; ++s) {
for (e = 0; e < 10; ++e) {
if (e == m || e == s) continue;
for (n = 0; n < 10; ++n) {
if (n == m || n == s || n == e) continue;
for (d = 0; d < 10; ++d) {
if (d == m || d == s || d == e || d == n) continue;
for (o = 0; o < 10; ++o) {
if (o == m || o == s || o == e || o == n || o == d) continue;
for (r = 0; r < 10; ++r) {
if (r == m || r == s || r == e || r == n || r == d || r == o) continue;
for (y = 0; y < 10; ++y) {
if (y == m || y == s || y == e || y == n || y == d || y == o) continue;
sum1 = 1000*s + 100*e + 10*n + d + 1000*m + 100*o + 10*r + e;
sum2 = 10000*m + 1000*o + 100*n + 10*e + y;
if (sum1 == sum2) {
print(f, s, e, n, d, m, o, r, e, m, o, n, e, y);
}
}
}
}
}
}
}
}
}</syntaxhighlight>

{{out}}
<pre>
9567 + 1085 = 10652
</pre>
</pre>


=={{header|Wren}}==
=={{header|Wren}}==
Clearly M = 1 and S must be 8 or 9. Brute force can be used to solve for the other letters.
Clearly M = 1 and S must be 8 or 9. Brute force can be used to solve for the other letters.
<syntaxhighlight lang="ecmascript">var start = System.clock
<syntaxhighlight lang="wren">var start = System.clock
var sends = []
var sends = []
var ors = []
var ors = []

Revision as of 07:19, 10 May 2024

SEND + MORE = MONEY is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Write a program in your language to solve SEND + MORE = MONEY: A Great Puzzle.

ALGOL 68

Translation of: Julia

This task can be solved without using seven nested loops but then again, it can be solved with them - so why not?.
Uses the observations of the Julia sample (unsuprisingly as this is a translation of the Julia sample).

BEGIN # solve the SEND+MORE=MONEY puzzle - translation of the Julia sample #
  INT m = 1;
  OP C = ( INT n )CHAR: REPR ( ABS "0" + n ); # convert integer to a digit #
  FOR s FROM 8 TO 9 DO
    FOR e FROM 0 TO 9 DO
      IF e /= m AND e/= s THEN
        FOR n FROM 0 TO 9 DO
          IF n /= m AND n /= s AND n /= e THEN
            FOR d FROM 0 TO 9 DO
              IF d /= m AND d /= s AND d /= e AND d /= n THEN
                FOR o FROM 0 TO 9 DO
                  IF o /= m AND o /= s AND o /= e AND o /= n AND o /= d THEN
                    FOR r FROM 0 TO 9 DO
                      IF r /= m AND r /= s AND r /= e AND r /= n AND r /= d AND r /= o THEN
                        FOR y FROM 0 TO 9 DO
                          IF y /= m AND y /= s AND y /= e AND y /= n AND y /= d AND y /= o AND y /= r THEN
                            IF ( 1000 * ( s + m ) ) + ( 100 * ( e + o ) ) + ( 10 * ( n + r ) ) + ( d + e )
                             = ( 10 000 * m ) + ( 1000 * o ) + ( 100 * n ) + ( 10 * e ) + y
                            THEN
                              print( ( C s, C e, C n, C d, " + ", C m, C o, C r, C e, " = ", C m, C o, C n, C e, C y
                                     )
                                   )
                            FI
                          FI
                        OD
                      FI
                    OD
                  FI
                OD
              FI
            OD
          FI
        OD
      FI
    OD
  OD
END
Output:
9567 + 1085 = 10652

BASIC

Rosetta Code problem: https://rosettacode.org/wiki/SEND_%2B_MORE_%3D_MONEY

by Jjuanhdez, 02/2023

BASIC256

Translation of: FreeBASIC
Works with: Run BASIC
Works with: Just BASIC
Works with: Liberty BASIC
m = 1
for s = 8 to 9
  for e = 0 to 9
    if e <> m and e <> s then
      for n = 0 to 9
        if n <> m and n <> s and n <> e then
          for d = 0 to 9
            if d <> m and d <> s and d <> e and d <> n then
              for o = 0 to 9
                if o <> m and o <> s and o <> e and o <> n and o <> d then
                  for r = 0 to 9
                    if r <> m and r <> s and r <> e and r <> n and r <> d and r <> o then
                      for y = 0 to 9
                        if y <> m and y <> s and y <> e and y <> n and y <> d and y <> o then
                          if ((1000*(s+m)) + (100*(e+o)) + (10*(n+r)) + (d+e)) = ((10000* m) + (1000*o) + (100*n) + (10*e) + y) then
                            print s;e;n;d; " + "; m;o;r;e; " = "; m;o;n;e;y
                          end if
                        end if
                      next y
                    end if
                  next r
                end if
              next o
            end if
          next d
        end if
      next n
    end if
  next e
next s
Output:
Same as FreeBASIC entry.

Gambas

Translation of: FreeBASIC
Public Sub Main()

  Dim m, s, e, n, d, o, r, y As Byte
  
  m = 1
  For s = 8 To 9
    For e = 0 To 9
      If e <> m And e <> s Then
        For n = 0 To 9
          If n <> m And n <> s And n <> e Then
            For d = 0 To 9
              If d <> m And d <> s And d <> e And d <> n Then
                For o = 0 To 9
                  If o <> m And o <> s And o <> e And o <> n And o <> d Then
                    For r = 0 To 9
                      If r <> m And r <> s And r <> e And r <> n And r <> d And r <> o Then
                        For y = 0 To 9
                          If y <> m And y <> s And y <> e And y <> n And y <> d And y <> o Then
                            If ((1000*(s+m)) + (100*(e+o)) + (10*(n+r)) + (d+e)) =  ((10000* m) + (1000*o) + (100*n) + (10*e) + y) Then
                              Print s & e & n & d & " + " & m & o & r & e & " = " &  m & o & n & e & y
                            End If
                          End If
                        Next
                      End If
                    Next
                  End If
                Next
              End If
            Next
          End If
        Next
      End If
    Next
  Next

End
Output:
Same as FreeBASIC entry.

Run BASIC

Works with: Just BASIC
Works with: Liberty BASIC

PureBasic

OpenConsole()
m.i = 1
For s.i = 8 To 9
  For e.i = 0 To 9
    If e <> m And e <> s
      For n.i = 0 To 9
        If n <> m And n <> s And n <> e
          For d.i = 0 To 9
            If d <> m And d <> s And d <> e And d <> n
              For o.i = 0 To 9
                If o <> m And o <> s And o <> e And o <> n And o <> d
                  For r.i = 0 To 9
                    If r <> m And r <> s And r <> e And r <> n And r <> d And r <> o
                      For y.i = 0 To 9
                        If y <> m And y <> s And y <> e And y <> n And y <> d And y <> o
                          If ((1000*(s+m))+(100*(e+o))+(10*(n+r))+(d+e)) = ((10000*m)+(1000*o)+(100*n)+(10*e)+y)
                            PrintN(Str(s)+Str(e)+Str(n)+Str(d)+" + "+Str(m)+Str(o)+Str(r)+Str(e)+" = "+Str(m)+Str(o)+Str(n)+Str(e)+Str(y))
                          EndIf
                        EndIf
                      Next y
                    EndIf
                  Next r
                EndIf
              Next o
            EndIf
          Next d
        EndIf
      Next n
    EndIf
  Next e
Next s
CloseConsole()
Output:
Same as FreeBASIC entry.

True BASIC

Works with: QBasic version 1.1
LET m = 1
FOR s = 8 TO 9
    FOR e = 0 TO 9
        IF e <> m AND e <> s THEN
           FOR n = 0 TO 9
               IF n <> m AND n <> s AND n <> e THEN
                  FOR d = 0 TO 9
                      IF d <> m AND d <> s AND d <> e AND d <> n THEN
                         FOR o = 0 TO 9
                             IF o <> m AND o <> s AND o <> e AND o <> n AND o <> d THEN
                                FOR r = 0 TO 9
                                    IF r <> m AND r <> s AND r <> e AND r <> n AND r <> d AND r <> o THEN
                                       FOR y = 0 TO 9
                                           IF y <> m AND y <> s AND y <> e AND y <> n AND y <> d AND y <> o THEN
                                              IF ((1000*(s+m))+(100*(e+o))+(10*(n+r))+(d+e)) = ((10000*m)+(1000*o)+(100*n)+(10*e)+y) THEN
                                                 PRINT STR$(s); STR$(e); STR$(n); STR$(d); " + "; 
                                                 PRINT STR$(m); STR$(o); STR$(r); STR$(e); " = ";
                                                 PRINT STR$(m); STR$(o); STR$(n); STR$(e); STR$(y)
                                              END IF
                                           END IF
                                       NEXT y
                                    END IF
                                NEXT r
                             END IF
                         NEXT o
                      END IF
                  NEXT d
               END IF
           NEXT n
        END IF
    NEXT e
NEXT s
END
Output:
Same as FreeBASIC entry.

Yabasic

Translation of: FreeBASIC
m = 1
for s = 8 to 9
  for e = 0 to 9
    if e <> m and e <> s then
      for n = 0 to 9
        if n <> m and n <> s and n <> e then
          for d = 0 to 9
            if d <> m and d <> s and d <> e and d <> n then
              for o = 0 to 9
                if o <> m and o <> s and o <> e and o <> n and o <> d then
                  for r = 0 to 9
                    if r <> m and r <> s and r <> e and r <> n and r <> d and r <> o then
                      for y = 0 to 9
                        if y <> m and y <> s and y <> e and y <> n and y <> d and y <> o then
                          if ((1000*(s+m)) + (100*(e+o)) + (10*(n+r)) + (d+e)) = ((10000* m) + (1000*o) + (100*n) + (10*e) + y)  ? str$(s), str$(e), str$(n), str$(d), " + ", str$(m), str$(o), str$(r), str$(e), " = ", str$(m), str$(o), str$(n), str$(e), str$(y)
                        fi
                      next y
                    fi
                  next r
                fi
              next o
            fi
          next d
        fi
      next n
    fi
  next e
next s
end
Output:
Same as FreeBASIC entry.

C

Translation of: Julia
#include <stdio.h>

int main() {
  int m = 1, s, e, n, d, o, r, y, sum1, sum2;
  const char *f = "%d%d%d%d + %d%d%d%d = %d%d%d%d%d\n";
  for (s = 8; s < 10; ++s) {
    for (e = 0; e < 10; ++e) {
      if (e == m || e == s) continue;
      for (n = 0; n < 10; ++n) {
        if (n == m || n == s || n == e) continue;
        for (d = 0; d < 10; ++d) {
          if (d == m || d == s || d == e || d == n) continue;
          for (o = 0; o < 10; ++o) {
            if (o == m || o == s || o == e || o == n || o == d) continue;
            for (r = 0; r < 10; ++r) {
              if (r == m || r == s || r == e || r == n || r == d || r == o) continue;
              for (y = 0; y < 10; ++y) {
                if (y == m || y == s || y == e || y == n || y == d || y == o) continue;
                sum1 = 1000*s + 100*e + 10*n + d + 1000*m + 100*o + 10*r + e;
                sum2 = 10000*m + 1000*o + 100*n + 10*e + y;
                if (sum1 == sum2) {
                  printf(f, s, e, n, d, m, o, r, e, m, o, n, e, y);
                }
              }
            }
          }
        }
      }
    }
  }           
  return 0;
}
Output:
9567 + 1085 = 10652

FreeBASIC

Translation of: Julia
Dim As Byte m = 1, s, e, n, d, o, r, y
For s = 8 To 9
    For e = 0 To 9
        If e <> m And e <> s Then
            For n = 0 To 9
                If n <> m And n <> s And n <> e Then
                    For d = 0 To 9
                        If d <> m And d <> s And d <> e And d <> n Then
                            For o = 0 To 9
                                If o <> m And o <> s And o <> e And o <> n And o <> d Then
                                    For r = 0 To 9
                                        If r <> m And r <> s And r <> e And r <> n And r <> d And r <> o Then
                                            For y = 0 To 9
                                                If y <> m And y <> s And y <> e And y <> n And y <> d And y <> o Then
                                                    If ((1000*(s+m)) + (100*(e+o)) + (10*(n+r)) + (d+e)) = _
                                                       ((10000* m) + (1000*o) + (100*n) + (10*e) + y) Then
                                                        Print s & e & n & d & " + " & _
                                                        m & o & r & e & " = " &  m & o & n & e & y
                                                    End If
                                                End If
                                            Next y
                                        End If
                                    Next r
                                End If
                            Next o
                        End If
                    Next d
                End If
            Next n
        End If
    Next e
Next s

Sleep
Output:
9567 + 1085 = 10652

Go

Translation of: Wren
package main

import (
    "fmt"
    "time"
)

func contains(a []int, v int) bool {
    for i := 0; i < len(a); i++ {
        if a[i] == v {
            return true
        }
    }
    return false
}

func main() {
    start := time.Now()
    var sends [][4]int
    var ors [][2]int
    m := 1
    digits := []int{0, 2, 3, 4, 5, 6, 7, 8, 9}
    for s := 8; s <= 9; s++ {
        for _, e := range digits {
            if e == s {
                continue
            }
            for _, n := range digits {
                if n == s || n == e {
                    continue
                }
                for _, d := range digits {
                    if d == s || d == e || d == n {
                        continue
                    }
                    sends = append(sends, [4]int{s, e, n, d})
                }
            }
        }
    }
    for _, o := range digits {
        for _, r := range digits {
            if r != o {
                ors = append(ors, [2]int{o, r})
            }
        }
    }
    fmt.Println("Solution(s):")
    for _, send := range sends {
        SEND := 1000*send[0] + 100*send[1] + 10*send[2] + send[3]
        for _, or := range ors {
            send2 := send[:]
            or2 := or[:]
            if contains(send2, or[0]) || contains(send2, or[1]) {
                continue
            }
            MORE := 1000*m + 100*or[0] + 10*or[1] + send[1]
            for _, y := range digits {
                if contains(send2, y) || contains(or2, y) {
                    continue
                }
                MONEY := 10000*m + 1000*or[0] + 100*send[2] + 10*send[1] + y
                if SEND+MORE == MONEY {
                    fmt.Printf("%d + %d = %d\n", SEND, MORE, MONEY)
                }
            }
        }
    }
    fmt.Printf("\nTook %s.\n", time.Since(start))
}
Output:
Solution(s):
9567 + 1085 = 10652

Took 1.149804ms.

J

Tacit Solution

SEND=.  10 #.   0 1 2 3&{
MORE=.  10 #.   4 5 6 1&{
MONEY=. 10 #. 4 5 2 1 7&{
M=.                   4&{
   
entry=. 0&{::
try=.   1&{::
   
sample=. (10 ?~ 8:) ; 1 + try NB. counting tries to avoid a premature convergence
   
good=. (not=. -.) (o=.@:) (0 = M) (and=. *.) (SEND + MORE) = MONEY
   
answer=. (": o SEND , ' + ' , ": o MORE , ' = ' , ": o MONEY) o entry
tries=.  ', random tries ' , ": o try
   
while=. ^: (^:_)
   
solve=.  (answer , tries) o (sample while (not o good o entry)) o ( 0 ;~ i.) o 8: f.

Example use:

   solve ''
9567 + 1085 = 10652, random tries 248241
   
   solve ''
9567 + 1085 = 10652, random tries 246504
   
   solve ''
9567 + 1085 = 10652, random tries 3291556

The code is tacit and fixed (in other words, it is point-free):

   _80 [\ (5!:5)<'solve'
((":@:(10 (#.) 0 1 2 3&({ )) , ' + ' , ":@:(10 (#.) 4 5 6 1&({ )) , ' = ' , ":@:
(10 (#.) 4 5 2 1 7&({ )))@:(0&({::)) , ', random tries ' , ":@:(1&({::)))@:(((10
 ?~ 8:) ; 1 + 1&({::))^:(-.@:(-.@:(0 = 4&({ )) *. ((10 (#.) 0 1 2 3&({ )) + 10 (
#.) 4 5 6 1&({ )) = 10 (#.) 4 5 2 1 7&({ ))@:(0&({::)))^:_)@:(0 ;~ i.)@:8:

jq

Works with: jq

Works with gojq, the Go implementation of jq, and with fq

Straight out of the wikipedia page, except for {} instead of [] in the last line of the def:

def send_more_money:
    def choose(m;n;used): ([range(m;n+1)] - used)[];
    def num(a;b;c;d): 1000*a + 100*b + 10*c + d;
    def num(a;b;c;d;e): 10*num(a;b;c;d) + e;
    first(
      1 as $m
      | 0 as $o
      | choose(8;9;[]) as $s
      | choose(2;9;[$s]) as $e
      | choose(2;9;[$s,$e]) as $n
      | choose(2;9;[$s,$e,$n]) as $d
      | choose(2;9;[$s,$e,$n,$d]) as $r
      | choose(2;9;[$s,$e,$n,$d,$r]) as $y
      | select(num($s;$e;$n;$d) + num($m;$o;$r;$e) == num($m;$o;$n;$e;$y))
      | {$s,$e,$n,$d,$m,$o,$r,$e,$m,$o,$n,$e,$y} );

send_more_money
Output:
{"s":9,"e":5,"n":6,"d":7,"m":1,"o":0,"r":8,"y":2}

Julia

A hoary old task, solved with pencil before electricity was a thing.

Since the M in Money is the result of carry in base 10 of two single digits it is a 1 (we exclude 0 here though that would work, but then MONEY would be spelled ONEY).

In addition, the S plus 1 then needs to result in a carry, so S is 8 or 9, depending on whether there is a carry into that column. Pencil and paper can continue, but from here the computer is likely quicker.

let
    m = 1
    for s in 8:9
        for e in 0:9
            e in [m, s] && continue
            for n in 0:9
                n in [m, s, e] && continue
                for d in 0:9
                    d in [m, s, e, n] && continue
                    for o in 0:9
                        o in [m, s, e, n, d] && continue
                        for r in 0:9
                            r in [m, s, e, n, d, o] && continue
                            for y in 0:9
                                y in [m, s, e, n, d, o] && continue
                                if 1000s + 100e + 10n + d + 1000m + 100o + 10r + e ==
                                   10000m + 1000o + 100n + 10e + y
                                    println("$s$e$n$d + $m$o$r$e == $m$o$n$e$y")
                                end
                            end
                        end
                    end
                end
            end
        end
    end
end
Output:

9567 + 1085 == 10652

Nim

Translation of: Julia
import std/strformat

let m = 1
for s in 8..9:
  for e in 0..9:
    if e in [m, s]: continue
    for n in 0..9:
      if n in [m, s, e]: continue
      for d in 0..9:
        if d in [m, s, e, n]: continue
        for o in 0..9:
          if o in [m, s, e, n, d]: continue
          for r in 0..9:
            if r in [m, s, e, n, d, o]: continue
            for y in 0..9:
              if y in [m, s, e, n, d, o]: continue
              if 1000 * s + 100 * e + 10 * n + d + 1000 * m + 100 * o + 10 * r + e ==
                 10000 * m + 1000 * o + 100 * n + 10 * e + y:
                echo &"{s}{e}{n}{d} + {m}{o}{r}{e} = {m}{o}{n}{e}{y}"
Output:
9567 + 1085 = 10652

Pascal

Free Pascal

simple brute force. Permutation stolen by nQueens.

program SymbolToDigit;
{$IFDEF FPC}{$MODE DELPHI}{$Optimization ON,All}{$ENDIF}
{$IFDEF Windows}{$APPTYPE CONSOLE}{$ENDIF}
uses
  sysutils;// TDatetime
const
  nmax = 9;
  maxLen = 7;

type
 tFreeDgt = array[0..nmax+1] of Int32;
 tSymbWord = String[maxLen];
  
 tDgtWord =  record
               DW_DgtsIdx: array[1..maxLen] of UInt8;
               DW_maxIdx: Uint8;
             end;
             
 tDgtFront  =  record
                 DW_DgtsIdx: array[1..nmax+1] of UInt8;
                 DW_maxIdx: Uint8;
               end;             
  tInUse = set of 0..nmax+1;           
const
{
  maxIDx = 2;
  cSumWords : array[0..maxIDx] of tSymbWord =('SEND','MORE','MONEY');
}  
{
  maxIDx = 4;  
  cSumWords : array[0..maxIDx]  of tSymbWord =('ABRA','CADABRA','ABRA','CADABRA','HOUDINI');
}

//MANYOTHERS=M2A7N6Y4O1T9H5E0R8S3
  maxIDx = 41;
  cSumWords : array[0..maxIDx] of tSymbWord =(
    'SO','MANY','MORE','MEN','SEEM','TO','SAY','THAT',
    'THEY','MAY','SOON','TRY','TO','STAY','AT','HOME',
    'SO','AS','TO','SEE','OR','HEAR','THE','SAME','ONE',
    'MAN','TRY','TO','MEET','THE','TEAM','ON','THE',
    'MOON','AS','HE','HAS','AT','THE','OTHER','TEN',
    'TESTS');

var
{$ALIGN 32}
  DigitSample,
  DigitSampleSolution : tFreeDgt;
  SymbInUse : array[0..10] of char;
  Words :array[0..maxIDx] of tSymbWord;
  DgtWords : array[0..maxIDx] of tDgtWord;
  DgtFrontWords :tDgtFront;
  SymbInUseCount,gblCount : Uint32;
  fullStop: boolean;
  ch : char;

procedure OneSol(idx:int32;const DS:tFreeDgt);
var
  i,symbolIdx : Int32;
begin
  For i := maxlen downto 1 do
  begin
    symbolIdx :=  DgtWords[idx].DW_DgtsIdx[i];
    if symbolIdx = 0 then
      write(' ')
    else
      write(DS[symbolIdx]);
  end;
  writeln(cSumWords[idx]:maxLen+2);
end;

procedure RevString(var s:tSymbWord);
var
  i,j: NativeInt;
begin
  i := 1;
  j := Length(s);
  while j>i do
  begin
    ch:= s[i];s[i]:= s[j];s[j] := ch;
    inc(i);dec(j);
  end;
end;

procedure GetSymbols;
var
  //CHR(ORD('A')-1) = '@' is placeholder for no Symbol
  SymbToIdx : array['@'..'Z'] of byte;
  FrontSymbols :tInUse;
  i,j : Int32;
Begin
  fillchar(SymbToIdx,SizeOf(SymbToIdx),#255);
  SymbToIdx['@'] := 0;
  SymbInUseCount := 1;//['@'] is always zero

  For i := 0 to maxIDx do
  begin
    Words[i] := cSumWords[i];
    j := length(Words[i]);
    //position of highest symbol
    DgtWords[i].DW_maxIdx := j;
    // extend by '@' aka zero
    RevString(Words[i]);
    setlength(Words[i],maxlen);
    For j := j+1 to maxLen do
      Words[i][j] := Low(SymbToIdx);
  end;
  // find all symbols
  for j := 1 to High(tSymbWord) do
  Begin
    For i := 0 to maxIdx do
    begin
      ch := Words[i][j];
      if SymbToIdx[ch] = 255 then
      begin
        SymbToIdx[ch] := SymbInUseCount;
        SymbInUse[SymbInUseCount] := ch;
        inc(SymbInUseCount);
      end;
    end;
  end;
  dec(SymbInUseCount);
  For i := 1 to SymbInUseCount do
    write(SymbInUse[i]);
  writeln(SymbInUseCount:4,' symbols');

  //get index for every symbol in word
  For i := 0 to maxIdx do
    with DgtWords[i] do
      for j := 1 to High(tSymbWord) do
        DW_DgtsIdx[j]:= SymbToIdx[Words[i][j]];
        
  //find all first symbols
  FrontSymbols := [];
  For i := 0 to maxIDx do
    with DgtWords[i] do
      include(FrontSymbols,DW_DgtsIdx[DW_maxIdx]);

  j := 1;  
  For i := 0 to nmax+1 do
    if i in FrontSymbols then
    Begin
      DgtFrontWords.DW_DgtsIdx[j] := i;
      inc(j);
    end;   
  DgtFrontWords.DW_maxIdx := j-1;
end;

function AddWords(const DS:tFreeDgt):boolean;
var
  col,row,
  sum,carry : NativeUInt;
begin
  // check for zero in first symbols of words
  with DgtFrontWords do
    For col := DW_maxIdx downto 1 do
    begin
      if DS[DW_DgtsIdx[col]] = 0 then 
        EXIT(false);
    end;
    
  carry := 0;
  For col := 1 to maxLen do
  Begin
    sum := carry;
    carry := 0;
    // add one column
    For row := maxIdx-1 downto 0 do
      sum := sum+DS[DgtWords[row].DW_DgtsIdx[col]];
      
    if sum > 9 then
    begin
      carry := sum DIV 10;
      sum := sum - 10 * carry;
    end;  
    //digit of sum
    if sum <> DS[DgtWords[maxIDx].DW_DgtsIdx[col]] then
      EXIT(false);
  end;
  If Carry = 0 then
    DigitSampleSolution := DS; 
  EXIT(true);
end;

procedure NextPermute(Row:nativeInt;var DS:tFreeDgt);
var
  i,Col : nativeInt;
begin
  if fullStop then   EXIT;
  IF row <= 10 then
  begin
    NextPermute(Row+1,DS);
    For i := row+1 to 10 do
    begin
      //swap
      Col := DS[i];
      DS[i] := DS[Row];
      DS[Row] := Col;
        NextPermute(Row+1,DS);
      //Undo swap
      DS[Row] := DS[i];
      DS[i] := Col;
    end
  end
else
  begin
    fullStop :=  AddWords(DS);
    inc(gblCount);
  end
end;

var
  T1,T0: TDateTime;
  i,j : Uint32;

begin
  DigitSample[0] := 0;
  For i := 0 to nmax do
    DigitSample[i+1] := i;
  GetSymbols;

  t0 := time;
  gblCount := 0;
  fullStop := false;
  NextPermute(1,DigitSample);
  t1:= time;
  IF maxIDx < 10 then
    For i := 0 to High(DgtWords)do 
      OneSol(i,DigitSampleSolution);
  writeln;
  For i := 1 to SymbInUseCount do
  begin  
     j := DigitSampleSolution[i];
     write(SymbInUse[i],'=',j,' ');
  end;   
  writeln;
  WriteLn(gblCount,' checks ',FormatDateTime(' NN:SS.ZZZ',T1-t0),' secs');
end.
@TIO.RUN:
DEYNROSM   8 symbols
   9567     SEND
   1085     MORE
  10652    MONEY

D=7 E=5 Y=2 N=6 R=8 O=0 S=9 M=1 
2704147 checks  00:00.043 secs
//shorthened    'SO','MANY','MORE','MEN','SEEM','TO','SAY',
OYENMTSRAH  10 symbols

O=1 Y=4 E=0 N=6 M=2 T=9 S=3 R=8 A=7 H=5 
496179 checks  00:00.013 secs

Perl

Translation of: Raku

Exhaustive

use v5.36;
use enum <D E M N O R S Y>;
use Algorithm::Combinatorics <combinations permutations>;

sub solve {
  for my $p (map { permutations $_ } combinations [0..9], 8) {
    return $p if @$p[M] > 0 and join('',@$p[S,E,N,D])+join('',@$p[M,O,R,E]) == join('',@$p[M,O,N,E,Y]);
  }
}

printf "SEND + MORE == MONEY\n%d + %d == %d", join('',@$_[S,E,N,D]), join('',@$_[M,O,R,E]), join '',@$_[M,O,N,E,Y]) for solve();
Output:
SEND + MORE == MONEY
9567 + 1085 == 10652

Fine-tuned

use v5.36;

my $s = 7;
while (++$s <= 9) {
    my $e = -1;
    while (++$e <= 9) {
        next if $e == $s;
        my $n = -1;
        while (++$n <= 9) {
            next if grep { $n == $_ } $s,$e;
            my $d = -1;
            while (++$d <= 9) {
                next if grep { $d == $_ } $s,$e,$n;
                my $send = $s*10**3 + $e*10**2 + $n*10 + $d;
                my ($m, $o) = (1, -1);
                while (++$o <= 9) {
                    next if grep { $o == $_ } $s,$e,$n,$d,$m;
                    my $r = -1;
                    while (++$r <= 9) {
                        next if grep { $r == $_ } $s,$e,$n,$d,$m,$o;
                        my $more = $m*10**3 + $o*10**2 + $r*10 + $e;
                        my $y = -1;
                        while (++$y <= 9) {
                            next if grep { $y == $_ } $s,$e,$n,$d,$m,$o,$r;
                            my $money = $m*10**4 + $o*10**3 + $n*10**2 + $e*10 + $y;
                            next unless $send + $more == $money;
                            say "SEND + MORE == MONEY\n$send + $more == $money";
                        }
                    }
                }
            }
        }
    }
}
Output:
SEND + MORE == MONEY
9567 + 1085 == 10652

Phix

atom t0 = time()
constant mp = new_dict() -- keys 'A'..'Z', values 0..9
sequence front, -- 1 if wordstart, else 0, for (0|1)..9
         multh, -- multiplier hash, see below
         used

-- mp ends up holding the (first) acceptable solution.
-- Letters which start any word cannot be 0 (in the rules).
-- In SEND+MORE=MONEY, 'E' is 100 + 1 - 10 = 91 from the 
-- three places E occurs in the puzzle, stored in multh.
-- Hence sum(letter_values*multh)==0 means it is solved.
-- Obviously used stops us using digits more than once.

function solve_rec(string uniq, int i, atom s)
    -- Aside: integer s is fine on 64-bit, but reaches
    --  a high of 13,304,757,742 & crashes on 32-bit.
    if i > length(uniq) then return s==0 end if
    integer chdx = uniq[i]-'A'+1
    for v=front[chdx] to 9 do
        if not used[v+1] then
            used[v+1] = true
            if solve_rec(uniq,i+1,s+v*multh[chdx]) then 
                setd(uniq[i],v,mp)
                return true
            end if
            used[v+1] = false
        end if
    end for
    return false
end function

function solve(string puzzle)
    destroy_dict(mp,true) -- empty, but keep
    used = repeat(false,10) -- nb [1..10] for 0..9
    multh = repeat(0,26) -- see above
    front = repeat(0,26) -- 1 if 1st in any word
    string uniq = ""
    sequence words = split_any(puzzle," +=\n")
    for iw,word in words do
        front[word[1]-'A'+1] = 1
        integer l = length(word),
                m = iff(iw=length(words)?-1:+1)
        for i,ch in word do
            multh[ch-'A'+1] += m*power(10,l-i)
            if not find(ch,uniq) then
                uniq &= ch
            end if
        end for
    end for
    if not solve_rec(uniq,1,0) then
        return "no solution"
    end if
    for i,ch in puzzle do
        if ch>='A' and ch<='Z' then
            puzzle[i] = getd(ch,mp)+'0'
        end if
    end for
    return puzzle
end function
        
constant tests = {
    "SEND + MORE == MONEY",
    "I + BB == ILL",
    "A == B",
    "ACA + DD == BD",
    "A + A + A + A + A + A + A + A + A + A + A + B == BCC",
    "AS + A == MOM",
    "NO + NO + TOO == LATE",
    "HE + SEES + THE == LIGHT",
    "AND + A + STRONG + OFFENSE + AS + A + GOOD == DEFENSE",
    "SIX + SEVEN + SEVEN = TWENTY",
    "THIS+A+FIRE+THEREFORE+FOR+ALL+HISTORIES+I+TELL+A+TALE+THAT+"&
     "FALSIFIES+ITS+TITLE+TIS+A+LIE+THE+TALE+OF+THE+LAST+FIRE+"&
     "HORSES+LATE+AFTER+THE+FIRST+FATHERS+FORESEE+THE+HORRORS+THE+"&
     "LAST+FREE+TROLL+TERRIFIES+THE+HORSES+OF+FIRE+THE+TROLL+RESTS+"&
     "AT+THE+HOLE+OF+LOSSES+IT+IS+THERE+THAT+SHE+STORES+ROLES+OF+"&
     "LEATHERS+AFTER+SHE+SATISFIES+HER+HATE+OFF+THOSE+FEARS+A+TASTE+"&
     "RISES+AS+SHE+HEARS+THE+LEAST+FAR+HORSE+THOSE+FAST+HORSES+THAT+"&
     "FIRST+HEAR+THE+TROLL+FLEE+OFF+TO+THE+FOREST+THE+HORSES+THAT+"&
     "ALERTS+RAISE+THE+STARES+OF+THE+OTHERS+AS+THE+TROLL+ASSAILS+AT+"&
     "THE+TOTAL+SHIFT+HER+TEETH+TEAR+HOOF+OFF+TORSO+AS+THE+LAST+HORSE"&
     "+FORFEITS+ITS+LIFE+THE+FIRST+FATHERS+HEAR+OF+THE+HORRORS+THEIR+"&
     "FEARS+THAT+THE+FIRES+FOR+THEIR+FEASTS+ARREST+AS+THE+FIRST+FATHERS"&
     "+RESETTLE+THE+LAST+OF+THE+FIRE+HORSES+THE+LAST+TROLL+HARASSES+"&
     "THE+FOREST+HEART+FREE+AT+LAST+OF+THE+LAST+TROLL+ALL+OFFER+THEIR+"&
     "FIRE+HEAT+TO+THE+ASSISTERS+FAR+OFF+THE+TROLL+FASTS+ITS+LIFE+"&
     "SHORTER+AS+STARS+RISE+THE+HORSES+REST+SAFE+AFTER+ALL+SHARE+HOT+"&
     "FISH+AS+THEIR+AFFILIATES+TAILOR+A+ROOFS+FOR+THEIR+SAFE == FORTRESSES",
     "TO + GO = OUT",
     "SEND + A + TAD + MORE = MONEY",
     "ABRA + CADABRA + ABRA + CADABRA = HOUDINI",
     "I + GUESS + THE + TRUTH = HURTS",
     "THATS + THE + THEORY = ANYWAY",
     `SO + MANY + MORE + MEN + SEEM + TO + SAY + THAT +
      THEY + MAY + SOON + TRY + TO + STAY + AT + HOME +
      SO + AS + TO + SEE + OR + HEAR + THE + SAME + ONE +
      MAN + TRY + TO + MEET + THE + TEAM + ON + THE +
      MOON + AS + HE + HAS + AT + THE + OTHER + TEN =TESTS`,
}

for t in tests do
    printf(1,"%s\n%s\n\n",{shorten(t,""),shorten(solve(t),"")})
end for
?elapsed(time()-t0)
Output:
SEND + MORE == MONEY
9567 + 1085 == 10652

I + BB == ILL
1 + 99 == 100

A == B
no solution

ACA + DD == BD
no solution

A + A + A + A + A + ...A + A + A + B == BCC
9 + 9 + 9 + 9 + 9 + ...9 + 9 + 9 + 1 == 100

AS + A == MOM
92 + 9 == 101

NO + NO + TOO == LATE
74 + 74 + 944 == 1092

HE + SEES + THE == LIGHT
54 + 9449 + 754 == 10257

AND + A + STRONG + O... A + GOOD == DEFENSE
503 + 5 + 691208 + 2... 5 + 8223 == 3474064

SIX + SEVEN + SEVEN = TWENTY
650 + 68782 + 68782 = 138214

THIS+A+FIRE+THEREFOR...R+SAFE == FORTRESSES
9874+1+5730+98030563...3+4150 == 5639304404

TO + GO = OUT
21 + 81 = 102

SEND + A + TAD + MORE = MONEY
9283 + 7 + 473 + 1062 = 10825

ABRA + CADABRA + ABRA + CADABRA = HOUDINI
7457 + 1797457 + 7457 + 1797457 = 3609828

I + GUESS + THE + TRUTH = HURTS
5 + 26811 + 478 + 49647 = 76941

THATS + THE + THEORY = ANYWAY
86987 + 863 + 863241 = 951091

SO + MANY + MORE + M...+ OTHER + TEN =TESTS
31 + 2764 + 2180 + 2...+ 19508 + 906 =90393

"4.8s"

Translation of Raku

Quite a bit slower than the above

enum S, E, N, D, M, O, R, Y

function check(sequence p)
    if p[M]!=0 and
       sum(sq_mul(extract(p,{S,E,N,D}),{1000,100,10,1}))+
       sum(sq_mul(extract(p,{M,O,R,E}),{1000,100,10,1}))=
     sum(sq_mul(extract(p,{M,O,N,E,Y}),{10000,1000,100,10,1})) then
        printf(1,"   %d%d%d%d\n",extract(p,{S,E,N,D}))
        printf(1," + %d%d%d%d\n",extract(p,{M,O,R,E}))
        printf(1,"= %d%d%d%d%d\n",extract(p,{M,O,N,E,Y}))
        return false
    end if
    return true -- continue
end function

{} = permutes(tagset(9,0),check,8)
Output:
   9567
 + 1085
= 10652

Python

Translation of: Nim
# SEND + MORE = MONEY by xing216
m = 1
for s in range(8,10):
  for e in range(10):
    if e in [m, s]: continue
    for n in range(10):
      if n in [m, s, e]: continue
      for d in range(10):
        if d in [m, s, e, n]: continue
        for o in range(10):
          if o in [m, s, e, n, d]: continue
          for r in range(10):
            if r in [m, s, e, n, d, o]: continue
            for y in range(10):
              if y in [m, s, e, n, d, o]: continue
              if 1000 * s + 100 * e + 10 * n + d + 1000 * m + 100 * o + 10 * r + e == \
                 10000 * m + 1000 * o + 100 * n + 10 * e + y:
                print(f"{s}{e}{n}{d} + {m}{o}{r}{e} = {m}{o}{n}{e}{y}")
Output:
9567 + 1085 = 10652

Raku

Idiomatic

enum <D E M N O R S Y>;

sub find_solution ( ) {
    for ('0'..'9').combinations(8) -> @c {
        .return with @c.permutations.first: -> @p {
            @p[M] !== 0 and

            @p[  S,E,N,D].join
          + @p[  M,O,R,E].join
         == @p[M,O,N,E,Y].join
        }
    }
}

my @s = find_solution();
say "    {@s[  S,E,N,D].join}";
say " +  {@s[  M,O,R,E].join}";
say "== { @s[M,O,N,E,Y].join}";
Output:
    9567
 +  1085
== 10652

Fast

Alternately, a version written in 2015 by Carl Mäsak. Not very concise but quite speedy. Applying the observation that M must be 1 and S must be either 8 or 9 gets the runtime under a tenth of a second.

my $s = 7;
while ++$s9 {
    my $e = -1;
    while ++$e9 {
        next if $e == $s;
 
        my $n = -1;
        while ++$n9 {
            next if $n == $s|$e;
 
            my $d = -1;
            while ++$d9 {
                next if $d == $s|$e|$n;

                my $send = $s×10³ + $e×10² + $n×10 + $d; 
                my ($m, $o) = 1, -1;
                while ++$o9 {
                    next if $o == $s|$e|$n|$d|$m;
 
                    my $r = -1;
                    while ++$r9 {
                        next if $r == $s|$e|$n|$d|$m|$o;
 
                        my $more = $m×10³ + $o×10² + $r×10 + $e;
                        my $y = -1;
                        while ++$y9 {
                            next if $y == $s|$e|$n|$d|$m|$o|$r;

                            my $money = $m×10 + $o×10³ + $n×10² + $e×10 + $y;
                            next unless $send + $more == $money;
                            say 'SEND + MORE == MONEY' ~ "\n$send + $more == $money";
                        }
                    }
                }
            }
        }
    }
}
printf "%.3f elapsed seconds", now - INIT now;
Output:
SEND + MORE == MONEY
9567 + 1085 == 10652
0.080 elapsed seconds

Ring

// Bert Mariani  2023-02-09 | A Monte Carlo method to solve the encryted message | SEND + MORE = MONEY

t1 = clock()          // 
See "Start Clock: "+ t1 +nl
counter    = 1
aSendory   = [["s","-"],["e","-"],["n","-"],["d","-"],["o","-"],["r","-"],["y","-"]]
aRandom    = List(10)                       // 0-9

for j = 1 to 100000000
	aRandom = GenRandomUniq()            // 5 2 0 8 7 1 6 4 3 9 	
	for i = 1 to 7
	    if aRandom[1] != 1               // m = 1
	       aSendory[i][2] = aRandom[1]
	       del(aRandom,1)                // Shorten list, remove value entry picked
	    else
	       del(aRandom,1)
	       i--
	    ok
	next
        if (TrySolution(aSendory)) break  else  counter++   ok  // True=1 = Solution Found      
next
See "End   Clock.: "+ (clock() - t1) +nl
See "Count cycles: "+ counter +nl

Func GenRandomUniq()
throwLimit = 10                      // 0-9, Ring does 1-10
aList = 1:throwLimit
aOut  = []
while len(aOut) != throwLimit
    nSize = len(aList)	
    if nSize > 0
        nIndex = random(nSize)       // Random pointer into list
        if nIndex = 0  nIndex=1 ok   // Ignore 0, Ring Index at 1-10		
        aOut + (aList[nIndex] -1)    // -1 fix value 0-9, Ring +1 Extract list entry content
        del(aList,nIndex)            // Shorten list, remove value entry picked
    else
        aOut + aList[1]
        aList = []
    ok
end
return aOut

Func TrySolution(aTry)
     s1 = ( aTry[1][2]) * 1000      // send   
     e1 = ( aTry[2][2]) *  100         
     n1 = ( aTry[3][2]) *   10        
     d1 = ( aTry[4][2]) *    1        
     nbr1 = s1 + e1 + n1 + d1
     m1 = 1             * 1000      // more
     o1 = ( aTry[5][2]) *  100
     r1 = ( aTry[6][2]) *   10
     e1 = ( aTry[2][2]) *    1 
     nbr2 = m1 + o1 + r1 + e1
     m1 = 1             * 10000     // money
     o1 = ( aTry[5][2]) *  1000
     n1 = ( aTry[3][2]) *   100
     e1 = ( aTry[2][2]) *    10
     y1 = ( aTry[7][2]) *     1
     nbr3 = m1 + o1 +n1 + e1 + y1
     nbr4 = nbr1 + nbr2
     if (nbr3 = nbr4)
        See "Solved: SEND: "+ nbr1 +" MORE: "+ nbr2 +" MONEY: "+ nbr3 +" Check "+ nbr4 +nl
        return (nbr3 = nbr4 )      // True
     ok  
return False
Output:
// Output
// Start Clock: 32
// Solved: SEND: 9567 MORE: 1085 MONEY: 10652 Check 10652
// End   Clock.: 3792
// Count cycles: 28316

original

// Author: Gal Zsolt 2023-02-08 
see "works..." + nl + nl
aListSend = []
aListMore = []

for s = 0 to 9
    for e1 = 0 to 9
        for n = 0 to 9
            for d = 0 to 9
                bool = s!=e1 and s!=n and s!=d and e1!=n and e1!=d and n!=d
                if bool
                   sendmore = s*1000+e1*100+n*10+d
                   add(aListSend,sendmore)
                   add(aListMore,sendmore)
                ok
            next
        next
    next
next

for ind1 = len(aListSend) to 1 step -1 
    for ind2 = 1 to len(aListMore)
        strSend = string(aListSend[ind1])
        strMore = string(aListMore[ind2])
        m = substr(strMore,1,1)
        o = substr(strMore,2,1)
        r = substr(strMore,3,1)
        e2 = substr(strMore,4,1)
        bool1 = substr(strSend,m)
        bool2 = substr(strSend,o)
        bool3 = substr(strSend,r)
        if substr(strSend,2,1) = substr(strMore,4,1)
            bool4 = 0
        else
            bool4 = 1
        ok
        boolSendMore = bool1 + bool2 + bool3 + bool4
        if boolSendMore < 1
           if substr(strSend,2,1) = substr(strMore,4,1)
              for y = 0 to 9
                  strMoney1 = substr(strMore,1,1) + substr(strMore,2,1) + substr(strSend,3,1)
                  strMoney2 = substr(strMore,4,1) + string(y)
                  strMoney = strMoney1 + strMoney2
                  numMoney = number(strMoney)
                  numSend = number(strSend)
                  numMore = number(strMore)
                  y1 = substr(strMoney,5,1)
                  ySend = substr(strSend,y1)
                  yMore = substr(strMore,y1)
                  yCheck = ySend + yMore
                  r = substr(strMore,3,1)
                  rCheck = substr(strSend,r)
                  if (numSend + numMore = numMoney) and yCheck < 1 and rCheck < 1
                      see "SEND = "+strSend+" MORE = "+strMore+" MONEY = "+strMoney+nl+nl              
                      exit 3
                  ok
             next
           ok
        ok
    next
next
see "done..." + nl
Output:
works...
SEND = 9567 MORE = 1085 MONEY = 10652
done...

Ruby

Solving for the string "SEND + 1ORE == 1ONEY" using 'tr' , which translates characters to other characters. The resulting string is brutally evalled.

str = "SEND + 1ORE == 1ONEY"
digits = [0,2,3,4,5,6,7,8,9] # 1 is absent
uniq_chars = str.delete("^A-Z").chars.uniq.join
res = digits.permutation(uniq_chars.size).detect do |perm|
  num_str = str.tr(uniq_chars, perm.join)
  next if num_str.match?(/\b0/) #no words can start with 0
  eval num_str
end
puts str.tr(uniq_chars, res.join)
Output:
9567 + 1085 == 10652

Vala

Translation of: C
void main() {
  int m = 1, s, e, n, d, o, r, y, sum1, sum2;
  string f = "%d%d%d%d + %d%d%d%d = %d%d%d%d%d\n";
  for (s = 8; s < 10; ++s) {
    for (e = 0; e < 10; ++e) {
      if (e == m || e == s) continue;
      for (n = 0; n < 10; ++n) {
        if (n == m || n == s || n == e) continue;
        for (d = 0; d < 10; ++d) {
          if (d == m || d == s || d == e || d == n) continue;
          for (o = 0; o < 10; ++o) {
            if (o == m || o == s || o == e || o == n || o == d) continue;
            for (r = 0; r < 10; ++r) {
              if (r == m || r == s || r == e || r == n || r == d || r == o) continue;
              for (y = 0; y < 10; ++y) {
                if (y == m || y == s || y == e || y == n || y == d || y == o) continue;
                sum1 = 1000*s + 100*e + 10*n + d + 1000*m + 100*o + 10*r + e;
                sum2 = 10000*m + 1000*o + 100*n + 10*e + y;
                if (sum1 == sum2) {
                  print(f, s, e, n, d, m, o, r, e, m, o, n, e, y);
                }
              }
            }
          }
        }
      }
    }
  }           
}
Output:
9567 + 1085 = 10652

Wren

Clearly M = 1 and S must be 8 or 9. Brute force can be used to solve for the other letters.

var start = System.clock
var sends = []
var ors = []
var m = 1
var digits = (0..9).toList
digits.remove(m)
for (s in 8..9) {
    for (e in digits) {
        if (e == s) continue
        for (n in digits) {
            if (n == s || n == e) continue
            for (d in digits) {
                if (d == s || d == e || d == n) continue
                sends.add([s, e, n, d])
            }
        }
    }
}
for (o in digits) {
    for (r in digits) {
        if (r == o) continue
        ors.add([o, r])
    }
}
System.print("Solution(s):")
for (send in sends) {
    var SEND = 1000 * send[0] + 100 * send[1] + 10 * send[2] + send[3]
    for (or in ors) {
        if (send.contains(or[0]) || send.contains(or[1])) continue
        var MORE = 1000 * m + 100 * or[0] + 10 * or[1] + send[1]
        for (y in digits) {
            if (send.contains(y) || or.contains(y)) continue
            var MONEY = 10000 * m + 1000 * or[0] + 100 * send[2] + 10 * send[1] + y
            if (SEND + MORE == MONEY) {
                System.print("%(SEND) + %(MORE) = %(MONEY)")
            }
        }
    }
}
System.print("\nTook %(System.clock - start) seconds.")
Output:
Solution(s):
9567 + 1085 = 10652

Took 0.051735 seconds.

XPL0

include xpllib; \for Print
def M = 1;
int S, E, N, D, O, R, Y;
begin \ Solve the SEND+MORE=MONEY puzzle - Translation of the Algol 68 sample
  for S:= 8 to 9 do
    for E:= 0 to 9 do
      if E # M and E # S then
        for N:= 0 to 9 do
          if N # M and N # S and N # E then
            for D:= 0 to 9 do
              if D # M and D # S and D # E and D # N then
                for O:= 0 to 9 do
                  if O # M and O # S and O # E and O # N and O # D then
                    for R:= 0 to 9 do
                      if R # M and R # S and R # E and R # N and R # D and R # O then
                        for Y:= 0 to 9 do
                          if Y # M and Y # S and Y # E and Y # N and Y # D and Y # O and Y # R then
                            if 1000*(S+M) + 100*(E+O) + 10*(N+R) + D + E = 10_000*M + 1000*O + 100*N + 10*E + Y then
                              Print("%d%d%d%d + %d%d%d%d = %d%d%d%d%d\n", S, E, N, D, M, O, R, E, M, O, N, E, Y);
end
Output:
9567 + 1085 = 10652