Skip to content

Instantly share code, notes, and snippets.

@ukslim
Last active January 5, 2022 11:44
Show Gist options
  • Save ukslim/c16cbcc580ce69b377e7da0dae41653c to your computer and use it in GitHub Desktop.
Save ukslim/c16cbcc580ce69b377e7da0dae41653c to your computer and use it in GitHub Desktop.
/*
Find a 5 digit combination that meets these constraints:
x[0] * x[1] == 24
x[3] == x[1] / 3
x[3] + x[4] == x[0] + x[2]
sum(x) == 26
not all the digits are unique
*/
/*
All the functions:
- take a partial array as input (the name of the function indicates the expected length)
- returns a valid combination beginning with the input, if one exists
- returns null if there is no valid combination starting with the input
The general pattern is, for input length l:
- Try digits 0-9 in turn, as the next digit
- If this digit meets the constraints we can test at this length, call the next function.
- If that returns non-null, return that
- Otherwise keep looping
This is similar to recursion, but isn't really recursion because no function actually calls itself.
It might be a nice example to understand before moving on to recursion.
*/
function f0(a) {
console.assert(a.length === 0)
// we know a[0] and a[1] must be >0 because
// their product must be 24
for(var i=1; i<10; i++) {
const r = f1([i]);
if(r) { return r; }
}
return null;
}
function f1(a) {
console.assert(a.length === 1)
// Try candidates where first two digits
// meet the constraint
for(var i=1; i<10; i++) {
if(a[0] * i == 24) {
const r = f2([...a, i]);
if(r) { return r; }
}
}
return null;
}
function f2(a) {
console.assert(a.length === 2)
// There are no constraints we can test about
// 3rd digit, until we have a 5th digit, so all
// are candidates
for(var i=0; i<10; i++) {
const r = f3([...a, i]);
if(r) { return r; }
}
return null;
}
function f3(a) {
console.assert(a.length === 3)
// Try candidates where 4th digits meets constraints
for(var i=0; i<10; i++) {
if(i == a[1] / 3) {
const r = f4([...a, i]);
if(r) { return r; }
}
}
return null;
}
function hasDuplicates(a) {
return (new Set(a)).size !== a.length;
}
function f4(a) {
console.assert(a.length === 4)
// Just return the first candidate that works
for(var i=0; i<10; i++) {
const c = [...a, i]
if(
hasDuplicates(c) &&
( c[3] + c[4] === c[0] + c[2]) &&
( c[0] + c[1] + c[2] + c[3] + c[4] === 26)) {
return c;
}
}
return null
}
const combination = f0([]);
console.log(combination)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment