SEND + MORE = MONEY
Write a program in your language to solve SEND + MORE = MONEY: A Great Puzzle.
ALGOL 68
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
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.
Yabasic
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.
FreeBASIC
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
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.
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
Pascal
Free Pascal
simple brute force. Permutation stolen by nQueens.
program SymbolToDigit;
uses
sysutils;// TDatetime
const
nmax = 9;
maxLen = 5;
maxIDx = 41;
type
tFreeDgt = array[0..nmax+1] of Int32;
tSymbWord = String[maxLen];
tDgtWord = record
DW_DgtsIdx: array[1..maxLen] of UInt8;
DW_maxIdx: Uint8;
end;
const
// cSumWords : array[0..maxIDx] of tSymbWord =('SEND','MORE','MONEY');
//MANYOTHERS=M2A7N6Y4O1T9H5E0R8S3
//{
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 : tFreeDgt;
SymbInUse : array[0..10] of char;
DgtToSymb : array[0..10] of UInt8;
Words :array[0..maxIDx] of tSymbWord;
DgtWords : array[0..maxIDx] of tDgtWord;
SymbInUseCount,gblCount : Uint32;
fullStop: boolean;
ch : char;
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;
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;
while j < maxLen do
begin
inc(j);
Words[i] := Low(SymbToIdx)+Words[i];
end;
RevString(Words[i]);
end;
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;
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
write(SymbInUse[i]);
writeln(SymbInUseCount-1:4,' symbols');
end;
procedure OneSol(idx:int32);
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(DigitSample[symbolIdx]);
end;
writeln(cSumWords[idx]:maxLen+2);
end;
function AddWords(const DS:tFreeDgt):boolean;
var
col,row,
sum,carrySum,carry : NativeUInt;
begin
// No zero as first symbol
For row := maxIdx downto 0 do
with DgtWords[row] do
if DS[DW_DgtsIdx[DW_maxidx]] = 0 then
EXIT(false);
carry := 0;
carrySum := 0;
For col := 1 to maxLen do
Begin
sum := carrysum MOD 10;
carrysum := carrysum DIV 10;
carry :=0;
For row := maxIdx-1 downto 0 do
Begin
sum := sum+DS[DgtWords[row].DW_DgtsIdx[col]];
if sum > 9 then
begin
carry := sum DIV 10;
sum := sum - 10 * carry;
inc(CarrySum,Carry);
end;
end;
//digit of sum
if sum <> DS[DgtWords[maxIDx].DW_DgtsIdx[col]] then
EXIT(false);
end;
if carrysum <>0 then
EXIT(false);
For row := 0 to High(DgtWords)do
OneSol(row);
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 : 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;
writeln;
WriteLn(gblCount,' checks ',FormatDateTime(' NN:SS.ZZZ',T1-t0),' secs');
end.
- @TIO.RUN:
8 symbols 9567 SEND 1085 MORE 10652 MONEY 2704147 checks 00:00.090 secs 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 496179 checks 00:00.061 secs
Phix
Mighta gota bit carried away here...
with javascript_semantics sequence answer procedure solve(sequence sums,solve_order,firsts,correct_to, integer l,avail,done=0) done += 1 integer d = solve_order[done] for ad=firsts[done] to 9 do integer m = power(2,ad) if and_bits(avail,m) then answer[d] = ad integer ct = correct_to[done] if ct then integer carry = 0, bOK = true for i=1 to ct do carry += sum(extract(answer,sums[i][1])) if remainder(carry,10)!=answer[sums[i][2]] then bOK = false exit end if carry = floor(carry/10) end for if bOK then if ct=length(sums) then if carry=0 then ?answer end if else solve(sums,solve_order,firsts,correct_to,l,avail-m,done) end if end if else solve(sums,solve_order,firsts,correct_to,l,avail-m,done) end if answer[d] = -1 end if end for end procedure procedure cryptarithm(string s) integer eq = find('=',s) sequence ans = trim(s[eq+1..$]), words = apply(split(s[1..eq-1],'+'),trim), res = join(unique(join(words,"")&ans,"STABLE"),"") integer l = length(res) for i,w in words do words[i] = apply(true,find,{w,{res}}) end for ans = apply(true,find,{ans,{res}}) sequence sums = {}, solve_order = {} for i=1 to length(ans) do sequence set = {} for w in words do if length(w)>=i then integer wi = w[-i] set &= wi if not find(wi,solve_order) then solve_order &= wi end if end if end for integer ai = ans[-i] if not find(ai,solve_order) then solve_order &= ai end if sums = append(sums,{set,ai}) end for assert(length(solve_order)=l) sequence firsts = repeat(0,l), correct_to = repeat(0,l) for f in unique(join(apply(true,extract,{words,{{1}}}),{})&ans[1]) do firsts[find(f,solve_order)] = 1 end for integer mm = 0 for i,fs in apply(sums,flatten) do integer m = max(apply(true,find,{fs,{solve_order}})) mm = max(m,mm) correct_to[mm] = i end for assert(correct_to[$]=length(sums)) answer = repeat(-1,l) printf(1,"%s - %s is ",{s,res}) solve(sums,solve_order,firsts,correct_to,l,0b1_111_111_111) end procedure constant tests = { `SEND+MORE=MONEY`, `TO+GO=OUT`, `SEND + A + TAD + MORE = MONEY`, `ABRA + CADABRA + ABRA + CADABRA = HOUDINI`, `I + GUESS + THE + TRUTH = HURTS`, `THATS + THE + THEORY = ANYWAY`, -- tad slow, 5.8s vs 0.2s for all above: `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`} papply(tests,cryptarithm)
- Output:
SEND+MORE=MONEY - SENDMORY is {9,5,6,7,1,0,8,2} 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} ABRA + CADABRA + ABRA + CADABRA = HOUDINI - ABRCDHOUIN is {7,4,5,1,9,3,6,0,8,2} 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} 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 - SOMANYRETH is {3,1,2,7,6,4,8,0,9,5}
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
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 int $s = 7;
while ++$s <= 9 {
next if $s == 0;
my int $e = -1;
while ++$e <= 9 {
next if $e == $s;
my int $n = -1;
while ++$n <= 9 {
next if $n == $s;
next if $n == $e;
my int $d = -1;
while ++$d <= 9 {
next if $d == $s;
next if $d == $e;
next if $d == $n;
my int $send = $s*1000 + $e*100 + $n*10 + $d;
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 =
$m*10000 + $o*1000 + $n*100 + $e*10 + $y;
next unless $send + $more == $money;
say 'SEND + MORE == MONEY';
say "$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
Ring
t1 = clock() // start
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 "Time: "+ clock() - t1 // end
see "done..." + nl
- Output:
works... SEND = 9567 MORE = 1085 MONEY = 10652 done... Time: 31.9 s
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