Last active
November 11, 2020 20:01
-
-
Save ebresafegaga/bdcde078c1dbf1e490d80a1d5fb44662 to your computer and use it in GitHub Desktop.
SEND + MORE = MONEY puzzle in F#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let rest = [0..9] | |
let first = [1..9] | |
type Letter = S | E | N | D | M | O | R | Y | |
let send = [S;E;N;D] | |
let more = [M;O;R;E] | |
let money = [M;O;N;E;Y] | |
let pick x letter = | |
match letter with | |
| S -> first | |
| M -> rems x first | |
| _ -> rems x rest | |
type Subst = Map<Letter, int> | |
let subst (map : Subst) xs = | |
List.foldBack (fun x s -> Map.find x map :: s) xs [] | |
let (+.) x y = | |
let a = x + y | |
if a >= 10 then (a-10), (a/10) | |
else a, 0 | |
let rec (|Snoc|Nil|) = function | |
| [] -> Nil | |
| x :: Nil -> Snoc (x, []) | |
| x :: Snoc (last, rest) -> Snoc (last, x :: rest) | |
let (++.) xs ys = | |
let rec loop carry result xs ys = | |
match xs, ys with | |
| Nil, Nil -> if carry=0 then result else (carry :: result) | |
| Nil, Snoc (y, ys) -> | |
let n, carry = 0 + y +. carry | |
loop carry (n :: result) xs ys | |
| Snoc (x, ys), Nil -> | |
let n, carry = x + 0 +. carry | |
loop carry (n :: result) xs ys | |
| Snoc (x, xs), Snoc (y, ys) -> | |
let n, carry = x + y +. carry | |
loop carry (n :: result) xs ys | |
loop 0 [] xs ys | |
let (~&) = | |
List.fold (fun s a -> s*10 + a) 0 | |
let correct sub = | |
let subst' = subst sub | |
let s = subst' send // Send | |
let m = subst' more // More | |
let dols = subst' money // Money | |
let sum = s ++. m | |
&sum = &dols | |
let solve () : Subst list = | |
[ for s in pick [] S do | |
for m in pick [s] M do | |
for e in pick [s;m] E do | |
for n in pick [s;m;e] N do | |
for d in pick [s;m;e;n] D do | |
for o in pick [s;m;e;n;d] O do | |
for r in pick [s;m;e;n;d;o] R do | |
for y in pick [s;m;e;n;d;o;r] Y do | |
let sub = Map.ofList [(S,s); (E,e); (N,n); (D,d); (M,m); (O,o); (R,r); (Y,y)] | |
if correct sub then sub ] | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment