Skip to content

Instantly share code, notes, and snippets.

@jcorbin
Last active August 29, 2015 14:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jcorbin/af23ca6d81f7ca8b70fe to your computer and use it in GitHub Desktop.
Save jcorbin/af23ca6d81f7ca8b70fe to your computer and use it in GitHub Desktop.
// Inspired by http://blog.plover.com/prog/monad-search-2.html
// S E N D
// + M O R E
// -----------
// M O N E Y
function toNumber(digits) {
var r = 0;
for (var i = 0; i < digits.length; i++) {
r += digits[i] * Math.pow(10, digits.length - i - 1);
}
return r;
}
function chooseADigit(digits, each) {
for (var i = 0; i < digits.length; i++) {
var digit = digits[i];
var remain = digits.slice(0, i).concat(digits.slice(i + 1));
each(remain, digit);
}
}
function chooseFilter(choice, filter, digits, each) {
choice(digits, function got(digits, digit) {
if (filter(digit)) {
each(digits, digit);
}
});
}
function notZero(digit) {
return digit !== 0;
}
function chooseWaterfall(choices, digits, each) {
if (!choices.length) {
each(digits, []);
return;
}
firstChoice(digits, [], 0);
function firstChoice(digits, r, i) {
choices[i](digits, function got(digits, digit) {
var s = r.concat([digit]);
nextChoice(digits, s, 1);
});
}
function nextChoice(digits, r, i) {
if (i >= choices.length) {
each(digits, r);
return;
}
choices[i](r, digits, function got(digits, digit) {
var s = r.concat([digit]);
nextChoice(digits, s, i + 1);
});
}
}
function chooseSeries(choices, digits, each) {
nextChoice(digits, [], 0);
function nextChoice(digits, r, i) {
if (i >= choices.length) {
each(digits, r);
return;
}
choices[i](digits, function got(digits, digit) {
var s = r.concat([digit]);
nextChoice(digits, s, i + 1);
});
}
}
var start = process.hrtime();
function chooseThree(digits, next) {
return chooseSeries([
chooseADigit,
chooseADigit,
chooseADigit
], digits, next);
}
function chooseTwo(digits, next) {
return chooseSeries([
chooseADigit,
chooseADigit
], digits, next);
}
function chooseInitial(digits, next) {
chooseFilter(chooseADigit, notZero, digits, next);
}
function chooseTwoInitials(digits, next) {
chooseSeries([
chooseInitial,
chooseInitial
], digits, next);
}
function chooseDEY(digits, next) {
chooseFilter(chooseThree, checkSum, digits, next);
}
function chooseNR(groups, digits, next) {
chooseFilter(chooseTwo, checkSecondSum, digits, next);
function checkSecondSum(nr) {
return checkSum(groups[0], nr);
}
}
function chooseO(groups, digits, next) {
chooseFilter(chooseADigit, checkThirdSum, digits, next);
function checkThirdSum(o) {
return checkSum(groups[0], groups[1], o);
}
}
function chooseSM(groups, digits, next) {
chooseFilter(chooseTwoInitials, function checkFourthSum(sm) {
return checkSum(groups[0], groups[1], groups[2], sm);
}, digits, next);
}
function checkSum(dey, nr, o, sm) {
var d = dey[0];
var e = dey[1];
var y = dey[2];
if ((d + e) % 10 != y) return false;
if (nr === undefined) return true;
var rem1 = Math.floor((d + e) / 10);
var n = nr[0];
var r = nr[1];
if ((n + r + rem1) % 10 != e) return false;
if (o === undefined) return true;
var rem2 = Math.floor((n + r + rem1) / 10);
if ((e + o + rem2) % 10 != n) return false;
if (sm === undefined) return true;
var rem3 = Math.floor((e + o + rem2) / 10);
var s = sm[0];
var m = sm[1];
if ((s + m + rem3) % 10 !== o) return false;
var rem4 = Math.floor((s + m + rem3) / 10);
return rem4 === m;
}
chooseWaterfall([
chooseDEY,
chooseNR,
chooseO,
chooseSM
], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], function process(digits, groups) {
var dey = groups[0];
var d = dey[0];
var e = dey[1];
var y = dey[2];
var nr = groups[1];
var n = nr[0];
var r = nr[1];
var o = groups[2];
var sm = groups[3];
var s = sm[0];
var m = sm[1];
var send = toNumber([s, e, n, d]);
var more = toNumber([m, o, r, e]);
var money = toNumber([m, o, n, e, y]);
console.log('%s + %s = %s', send, more, money);
});
var end = process.hrtime();
var d = [
end[0] - start[0],
end[1] - start[1]
];
if (d[1] < 0) {
d[0]--;
d1 += 1e9;
}
console.log('took %sms', d[0] * 1e3 + d[1] / 1e6);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment