SEND + MORE = MONEY: Difference between revisions
→{{header|ALGOL 68}}: Avoid line-wrap |
|||
(42 intermediate revisions by 18 users not shown) | |||
Line 5: | Line 5: | ||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |
||
{{Trans|Julia}} |
{{Trans|Julia}} |
||
This task <i>can</i> be solved |
This task <i>can</i> be solved without using seven nested loops but then again, it can be solved with them - so why not?. |
||
<br> |
<br> |
||
Uses the observations of the Julia sample (unsuprisingly as this is a translation of the Julia sample). |
Uses the observations of the Julia sample (unsuprisingly as this is a translation of the Julia sample). |
||
Line 50: | Line 50: | ||
<pre> |
<pre> |
||
9567 + 1085 = 10652 |
9567 + 1085 = 10652 |
||
</pre> |
|||
=={{header|BASIC}}== |
|||
Rosetta Code problem: https://rosettacode.org/wiki/SEND_%2B_MORE_%3D_MONEY |
|||
by Jjuanhdez, 02/2023 |
|||
==={{header|BASIC256}}=== |
|||
{{trans|FreeBASIC}} |
|||
{{works with|Run BASIC}} |
|||
{{works with|Just BASIC}} |
|||
{{works with|Liberty BASIC}} |
|||
<syntaxhighlight lang="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) 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</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}} |
|||
<pre>Same as FreeBASIC entry.</pre> |
|||
==={{header|Yabasic}}=== |
|||
{{trans|FreeBASIC}} |
|||
<syntaxhighlight lang="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</syntaxhighlight> |
|||
{{out}} |
|||
<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|EasyLang}}== |
|||
<syntaxhighlight lang=text> |
|||
func fac n . |
|||
f = 1 |
|||
for i to n |
|||
f *= i |
|||
. |
|||
return f |
|||
. |
|||
global elements[] nperm permb perma . |
|||
proc perminit a b . . |
|||
perma = a |
|||
permb = b |
|||
elements[] = [ ] |
|||
for i to a |
|||
elements[] &= i - 1 |
|||
. |
|||
nperm = fac a / fac b |
|||
. |
|||
func[] getperm r . |
|||
digs[] = elements[] |
|||
fa = nperm |
|||
for i = perma downto 1 + permb |
|||
fa /= i |
|||
d = r div fa + 1 |
|||
r = r mod fa |
|||
r[] &= digs[d] |
|||
for j = d to i - 1 |
|||
digs[j] = digs[j + 1] |
|||
. |
|||
. |
|||
return r[] |
|||
. |
|||
proc sendmore . . |
|||
perminit 10 2 |
|||
for p range0 nperm |
|||
r[] = getperm p |
|||
if r[1] <> 0 and r[5] <> 0 |
|||
send = 0 |
|||
for i to 4 |
|||
send = 10 * send + r[i] |
|||
. |
|||
more = 0 |
|||
for i = 5 to 7 |
|||
more = 10 * more + r[i] |
|||
. |
|||
more = 10 * more + r[2] |
|||
money = more div 100 |
|||
money = 10 * money + r[3] |
|||
money = 10 * money + r[2] |
|||
money = 10 * money + r[8] |
|||
if send + more = money |
|||
print send & " + " & more & " = " & money |
|||
. |
|||
. |
|||
. |
|||
. |
|||
sendmore |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
9567 + 1085 = 10652 |
|||
</pre> |
|||
=={{header|FreeBASIC}}== |
|||
{{Trans|Julia}} |
|||
<syntaxhighlight lang="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</syntaxhighlight> |
|||
{{out}} |
|||
<pre>9567 + 1085 = 10652</pre> |
|||
=={{header|FutureBasic}}== |
|||
<syntaxhighlight lang="futurebasic"> |
|||
void local fn SendMoreMoney |
|||
int m = 1, s, e, n, d, o, r, y |
|||
for s = 8 to 9 |
|||
for e = 0 to 9 |
|||
if e != m && e != s |
|||
for n = 0 to 9 |
|||
if n != m && n != s && n != e |
|||
for d = 0 to 9 |
|||
if d != m && d != s && d != e && d != n |
|||
for o = 0 to 9 |
|||
if o != m && o != s && o != e && o != n && o != d |
|||
for r = 0 to 9 |
|||
if r != m && r != s && r != e && r != n && r != d && r != o |
|||
for y = 0 to 9 |
|||
if y != m && y != s && y != e && y != n && y != d && y != o |
|||
if ((1000*(s+m))+(100*(e+o))+(10*(n+r))+(d+e)) = ((10000* m)+(1000*o)+(100*n)+(10*e)+y) |
|||
printf @"%d%d%d%d + %d%d%d%d = %d%d%d%d%d", 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 fn |
|||
fn SendMoreMoney |
|||
HandleEvents |
|||
</syntaxhighlight> |
|||
{{output}} |
|||
<pre> |
|||
9567 + 1085 = 10652 |
|||
</pre> |
|||
=={{header|Go}}== |
|||
{{trans|Wren}} |
|||
<syntaxhighlight lang="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)) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Solution(s): |
|||
9567 + 1085 = 10652 |
|||
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 87: | Line 620: | ||
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|Free Pascal}}=== |
|||
simple brute force. Permutation stolen by nQueens. |
|||
<syntaxhighlight lang="pascal"> |
|||
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.</syntaxhighlight> |
|||
{{out|@TIO.RUN}} |
|||
<pre> |
|||
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</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}}== |
|||
<!--(phixonline)--> |
|||
<syntaxhighlight lang="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) |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
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" |
|||
</pre> |
|||
===Translation of Raku=== |
|||
Quite a bit slower than the above |
|||
<!--<syntaxhighlight lang="phix">(phixonline)--> |
|||
<span style="color: #008080;">enum</span> <span style="color: #000000;">S</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">E</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">N</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">D</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">M</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">O</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">R</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">Y</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">check</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">M</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">and</span> |
|||
<span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_mul</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">S</span><span style="color: #0000FF;">,</span><span style="color: #000000;">E</span><span style="color: #0000FF;">,</span><span style="color: #000000;">N</span><span style="color: #0000FF;">,</span><span style="color: #000000;">D</span><span style="color: #0000FF;">}),{</span><span style="color: #000000;">1000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}))+</span> |
|||
<span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_mul</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">M</span><span style="color: #0000FF;">,</span><span style="color: #000000;">O</span><span style="color: #0000FF;">,</span><span style="color: #000000;">R</span><span style="color: #0000FF;">,</span><span style="color: #000000;">E</span><span style="color: #0000FF;">}),{</span><span style="color: #000000;">1000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}))=</span> |
|||
<span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_mul</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">M</span><span style="color: #0000FF;">,</span><span style="color: #000000;">O</span><span style="color: #0000FF;">,</span><span style="color: #000000;">N</span><span style="color: #0000FF;">,</span><span style="color: #000000;">E</span><span style="color: #0000FF;">,</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">}),{</span><span style="color: #000000;">10000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}))</span> <span style="color: #008080;">then</span> |
|||
<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;">" %d%d%d%d\n"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">S</span><span style="color: #0000FF;">,</span><span style="color: #000000;">E</span><span style="color: #0000FF;">,</span><span style="color: #000000;">N</span><span style="color: #0000FF;">,</span><span style="color: #000000;">D</span><span style="color: #0000FF;">}))</span> |
|||
<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;">" + %d%d%d%d\n"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">M</span><span style="color: #0000FF;">,</span><span style="color: #000000;">O</span><span style="color: #0000FF;">,</span><span style="color: #000000;">R</span><span style="color: #0000FF;">,</span><span style="color: #000000;">E</span><span style="color: #0000FF;">}))</span> |
|||
<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;">"= %d%d%d%d%d\n"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">M</span><span style="color: #0000FF;">,</span><span style="color: #000000;">O</span><span style="color: #0000FF;">,</span><span style="color: #000000;">N</span><span style="color: #0000FF;">,</span><span style="color: #000000;">E</span><span style="color: #0000FF;">,</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">}))</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #004600;">false</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #004600;">true</span> <span style="color: #000080;font-style:italic;">-- continue</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">permutes</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">),</span><span style="color: #000000;">check</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">)</span> |
|||
<!--</syntaxhighlight>--> |
|||
{{out}} |
|||
<pre> |
|||
9567 |
|||
+ 1085 |
|||
= 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> |
|||
=={{header|Raku}}== |
|||
=== Idiomatic === |
|||
<syntaxhighlight lang="raku" line> |
|||
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}"; |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
9567 |
|||
+ 1085 |
|||
== 10652 |
|||
</pre> |
|||
=== 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. |
|||
<syntaxhighlight lang="raku" line>my $s = 7; |
|||
while ++$s ≤ 9 { |
|||
my $e = -1; |
|||
while ++$e ≤ 9 { |
|||
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 $send = $s×10³ + $e×10² + $n×10 + $d; |
|||
my ($m, $o) = 1, -1; |
|||
while ++$o ≤ 9 { |
|||
next if $o == $s|$e|$n|$d|$m; |
|||
my $r = -1; |
|||
while ++$r ≤ 9 { |
|||
next if $r == $s|$e|$n|$d|$m|$o; |
|||
my $more = $m×10³ + $o×10² + $r×10 + $e; |
|||
my $y = -1; |
|||
while ++$y ≤ 9 { |
|||
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;</syntaxhighlight> |
|||
{{out}} |
|||
<pre>SEND + MORE == MONEY |
|||
9567 + 1085 == 10652 |
|||
0.080 elapsed seconds</pre> |
|||
=={{header|Ring}}== |
=={{header|Ring}}== |
||
<syntaxhighlight lang="ring"> |
<syntaxhighlight lang="ring"> |
||
// Bert Mariani 2023-02-09 | A Monte Carlo method to solve the encryted message | SEND + MORE = MONEY |
|||
t1 = clock() // start |
|||
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 |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
// Output |
|||
// Start Clock: 32 |
|||
// Solved: SEND: 9567 MORE: 1085 MONEY: 10652 Check 10652 |
|||
// End Clock.: 3792 |
|||
// Count cycles: 28316 |
|||
</pre> |
|||
===original=== |
|||
<syntaxhighlight lang="ring"> |
|||
// Author: Gal Zsolt 2023-02-08 |
|||
see "works..." + nl + nl |
see "works..." + nl + nl |
||
aListSend = [] |
aListSend = [] |
||
Line 151: | Line 1,396: | ||
next |
next |
||
next |
next |
||
see "Time: "+ clock() - t1 // end |
|||
see "done..." + nl |
see "done..." + nl |
||
</syntaxhighlight> |
</syntaxhighlight> |
||
Line 159: | Line 1,403: | ||
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=" |
<syntaxhighlight lang="wren">var start = System.clock |
||
var sends = [] |
var sends = [] |
||
var ors = [] |
var ors = [] |
||
Line 193: | Line 1,489: | ||
for (or in ors) { |
for (or in ors) { |
||
if (send.contains(or[0]) || send.contains(or[1])) continue |
if (send.contains(or[0]) || send.contains(or[1])) continue |
||
var sendmore = send + or |
|||
var MORE = 1000 * m + 100 * or[0] + 10 * or[1] + send[1] |
var MORE = 1000 * m + 100 * or[0] + 10 * or[1] + send[1] |
||
for (y in digits) { |
for (y in digits) { |
||
if ( |
if (send.contains(y) || or.contains(y)) continue |
||
var MONEY = 10000 * m + 1000 * or[0] + 100 * send[2] + 10 * send[1] + y |
var MONEY = 10000 * m + 1000 * or[0] + 100 * send[2] + 10 * send[1] + y |
||
if (SEND + MORE == MONEY) { |
if (SEND + MORE == MONEY) { |
||
Line 211: | Line 1,506: | ||
9567 + 1085 = 10652 |
9567 + 1085 = 10652 |
||
Took 0. |
Took 0.051735 seconds. |
||
</pre> |
|||
=={{header|XPL0}}== |
|||
<syntaxhighlight lang "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</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
9567 + 1085 = 10652 |
|||
</pre> |
</pre> |
Latest revision as of 21:20, 22 July 2024
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.
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
- Output:
Same as FreeBASIC entry.
Run 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
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
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
#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
EasyLang
func fac n .
f = 1
for i to n
f *= i
.
return f
.
global elements[] nperm permb perma .
proc perminit a b . .
perma = a
permb = b
elements[] = [ ]
for i to a
elements[] &= i - 1
.
nperm = fac a / fac b
.
func[] getperm r .
digs[] = elements[]
fa = nperm
for i = perma downto 1 + permb
fa /= i
d = r div fa + 1
r = r mod fa
r[] &= digs[d]
for j = d to i - 1
digs[j] = digs[j + 1]
.
.
return r[]
.
proc sendmore . .
perminit 10 2
for p range0 nperm
r[] = getperm p
if r[1] <> 0 and r[5] <> 0
send = 0
for i to 4
send = 10 * send + r[i]
.
more = 0
for i = 5 to 7
more = 10 * more + r[i]
.
more = 10 * more + r[2]
money = more div 100
money = 10 * money + r[3]
money = 10 * money + r[2]
money = 10 * money + r[8]
if send + more = money
print send & " + " & more & " = " & money
.
.
.
.
sendmore
- Output:
9567 + 1085 = 10652
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
FutureBasic
void local fn SendMoreMoney
int m = 1, s, e, n, d, o, r, y
for s = 8 to 9
for e = 0 to 9
if e != m && e != s
for n = 0 to 9
if n != m && n != s && n != e
for d = 0 to 9
if d != m && d != s && d != e && d != n
for o = 0 to 9
if o != m && o != s && o != e && o != n && o != d
for r = 0 to 9
if r != m && r != s && r != e && r != n && r != d && r != o
for y = 0 to 9
if y != m && y != s && y != e && y != n && y != d && y != o
if ((1000*(s+m))+(100*(e+o))+(10*(n+r))+(d+e)) = ((10000* m)+(1000*o)+(100*n)+(10*e)+y)
printf @"%d%d%d%d + %d%d%d%d = %d%d%d%d%d", 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 fn
fn SendMoreMoney
HandleEvents
- 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.
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 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
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
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
# 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 ++$s ≤ 9 {
my $e = -1;
while ++$e ≤ 9 {
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 $send = $s×10³ + $e×10² + $n×10 + $d;
my ($m, $o) = 1, -1;
while ++$o ≤ 9 {
next if $o == $s|$e|$n|$d|$m;
my $r = -1;
while ++$r ≤ 9 {
next if $r == $s|$e|$n|$d|$m|$o;
my $more = $m×10³ + $o×10² + $r×10 + $e;
my $y = -1;
while ++$y ≤ 9 {
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
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