Efficient way to get longest palindrome subsequence in a string - javascript

I'm trying to implement a function that takes a string as input and returns the longest palindrome subsequence in the string.
I've tried using dynamic programming and have come up with the following code:
function longestPalindromicSubsequence(str) {
let n = str.length;
let dp = Array(n);
for (let i = 0; i < n; i++) {
dp[i] = Array(n);
dp[i][i] = 1;
}
for (let cl = 2; cl <= n; cl++) {
for (let i = 0; i < n - cl + 1; i++) {
let j = i + cl - 1;
if (str[i] === str[j] && cl === 2)
dp[i][j] = 2;
else if (str[i] === str[j])
dp[i][j] = dp[i + 1][j - 1] + 2;
else
dp[i][j] = Math.max(dp[i][j - 1], dp[i + 1][j]);
}
}
return dp[0][n - 1];
}
However, this code doesn't seem to be giving me efficient and better results for all test cases. The Time and Space Complexity is also be reduced. I've been struggling with this for days and can't seem to find the issue. Can someone help me figure out what's going wrong and how to fix it?

Oh, I think Dynamic Programming does not work with this sort of problem, because it does not break down recursively, i.e. to find the longest palindrome in a string, you don't need all second-largest palindromes. You can just check at each position and see if it is the center of a palindrome longer than any before. This can be solved with a greedy algorithm:
const pals = "asd1234321fghjkl1234567887654321qwertzu1234321"
function palindromeAtPos(str, pos, checkEven = false){
let ix = 0
const off = checkEven ? 2 : 1
while(pos-ix-1 >= 0 && pos+ix+1+off < str.length && str[pos-ix-1] === str[pos+ix+off]){
ix++
}
return ix === 0 ? str[pos] : str.substring(pos-ix, pos+ix+off)
}
function longestPalindrome(str){
let longest = ''
for(let i = 1; i < str.length; i++){
const odd = palindromeAtPos(str, i)
longest = odd.length > longest.length ? odd : longest
const even = palindromeAtPos(str, i, true)
longest = even.length > longest.length ? even : longest
}
return longest
}
console.log(longestPalindrome(pals))
On paper (and for a string like aaaaaaaaaa), this has quadratic complexity, but for most strings, it will be almost linear.

/*
* s => string
* return [] of strings witch have the max lenth
*/
function maxLenPalindromes(s) {
const l = s.length
let c, z, zz, a, b, a1, b1, maxl = 0, result = []
if (l < 2) return result
for (c = 0; c < l - 1; c++) {
a = -1
if (maxl>(l-c)*2+1) return result
if (c > 0 && s[c - 1] == s[c + 1]) {
zz = Math.min(c, l - c - 1)
for (z = 1; z <= zz; z++) {
if (s[c - z] != s[c + z]) {
a = c - z + 1; b = c + z
break
}
else if (z == zz) {
a = c - z; b = c + z + 1
break
}
}
if (a >= 0) {
if (b-a > maxl) {
result = [s.slice(a, b)]
maxl = b-a
}
else if (b-a == maxl) {
result.push(s.slice(a, b))
}
}
}
a=-1
if (s[c] == s[c + 1]) {
if (c == 0 || c == l - 2) {
a = c; b = c + 2
}
else {
zz = Math.min(c, l - c - 2)
for (z = 1; z <= zz; z++) {
if (s[c - z] != s[c + z + 1]) {
a = c - z + 1; b = c + z + 1
break
}
else if (z == zz) {
a = c - z; b = c + z + 2
break
}
}
}
if (a >= 0) {
if (b-a > maxl) {
result = [s.slice(a, b)]
maxl = b-a
}
else if (b-a == maxl) {
result.push(s.slice(a, b))
}
}
}
}
return result
}
const s1="112233111222333"
const s2="11_22_33_111_222_333"
const s3="12345_54321xqazws_swzaq_qwertytrewq"
const s4="sdfgsdfg1qqqqqAAAAA_123456789o o987654321_AAAAAqqqqq;lakdjvbafgfhfhfghfh"
console.log(maxLenPalindromes(s1))
console.log(maxLenPalindromes(s2))
console.log(maxLenPalindromes(s3))
console.log(maxLenPalindromes(s4))

Related

Sorting an integer without using string methods and without using arrays

can anyone come with an idea of how to sort an integer without using an array, and without using string methods as well as sort() method?
for example
input: 642531
output: 123456
I started by writing 2 simple functions - one which checks the length of the number, the other one splits the integer at some point and switches between 2 desired numbers. Below are the 2 functions.
I got stuck with the rest of the solution...
function switchDigits(num, i) { // for input: num=642531, i = 4 returns 624135
let temp = num;
let rest = 0;
for (let j = 0; j < i - 1; j++) {
rest = rest * 10;
rest = rest + temp % 10;
temp = (temp - temp % 10) / 10;
}
let a = temp % 10;
temp = (temp - a) / 10;
let b = temp % 10;
temp = (temp - b) / 10;
temp = Math.pow(10, i - 2) * temp;
temp = temp + 10 * a + b;
temp = Math.pow(10, i - 1) * temp;
temp = temp + rest;
return temp;
}
function checkHowManyDigits(num) { //input: 642534, output: 6 (length of the integer)
let count = 0;
while (num > 0) {
let a = num % 10;
num = (num - a) / 10;
count++;
}
return count;
}
let num = 642534;
let i = checkHowManyDigits(num);
console.log(switchDigits(num));
It actually complicated requirement and so does this answer. It's pure logic and as it is it's a question from a test you should try understanding the logic on your own as a homework.
function checkHowManyDigits(num) { //input: 642534, output: 6 (length of the integer)
let count = 0;
while (num > 0) {
let a = num % 10;
num = (num - a) / 10;
count++;
}
return count;
}
function sortDigit(numOriginal) {
let i = checkHowManyDigits(numOriginal);
let minCount = 0;
let min = 10;
let num = numOriginal;
while (num > 0) {
let d = num % 10;
num = (num - d) / 10;
if (d < min) {
min = d;
minCount = 0;
} else if (d === min) {
minCount++;
}
}
let result = 0;
while (minCount >= 0) {
result += min * Math.pow(10, i - minCount - 1);
minCount--;
}
let newNum = 0;
num = numOriginal;
while (num > 0) {
let d = num % 10;
num = (num - d) / 10;
if (d !== min) {
newNum = newNum * 10 + d;
}
}
if (newNum == 0) return result;
else return result += sortDigit(newNum);
}
console.log(sortDigit(642531));
You could have a look to greater and smaller pairs, like
64
46
The delta is 18, which gets an idea if you compare other pairs, like
71
17
where the delta is 54. Basically any difference of two digits is a multiple of 9.
This in mind, you get a function for taking a single digit out of a number and a single loop who is sorting the digits by using the calculated delta and subtract the value, adjusted by the place.
function sort(number) {
const
getDigit = e => Math.floor(number / 10 ** e) % 10,
l = Math.ceil(Math.log10(number)) - 1;
let e = l;
while (e--) {
const
left = getDigit(e + 1),
right = getDigit(e);
if (left <= right) continue;
number += (right - left) * 9 * 10 ** e;
e = l;
}
return number;
}
console.log(sort(17)); // 17
console.log(sort(71)); // 17
console.log(sort(642531)); // 123456
console.log(sort(987123654)); // 123456789
So eventually I found the best solution.
*This solution is based on a Java solution I found in StackOverFlow forums.
let store = 0;
function getReducedNumbr(number, digit) {
console.log("Remove " + digit + " from " + number);
let newNumber = 0;
let repeateFlag = false;
while (number>0) {
let t = number % 10;
if (t !== digit) {
newNumber = (newNumber * 10) + t;
} else if (t == digit) {
if (repeateFlag) {
console.log(("Repeated min digit " + t + " found. Store is : " + store));
store = (store * 10) + t;
console.log("Repeated min digit " + t + " added to store. Updated store is : " + store);
} else {
repeateFlag = true;
}
}
number = Math.floor(number / 10);
}
console.log("Reduced number is : " + newNumber);
return newNumber;}
function sortNum(num) {
let number = num;
let original = number;
let digit;
while (number > 0) {
digit = number % 10;
console.log("Last digit is : " + digit + " of number : " + number);
temp = Math.floor(number/10);
while (temp > 0) {
console.log("subchunk is " + temp);
t = temp % 10;
if (t < digit) {
digit = t;
}
temp = Math.floor(temp/10);
}
console.log("Smallest digit in " + number + " is " + digit);
store = (store * 10) + digit;
console.log("store is : " + store);
number = getReducedNumbr(number, digit);
}
console.log(("Ascending order of " + original + " is " + store));
return store;
}
console.log(sortNum(4214173));
you can see how it works here https://jsfiddle.net/9dpm14fL/1/

Number Formatting for large integer numbers in Javascript

I know there are in-build function in javascript like toLocalString() to achieve number formatting. But this question is purely for learning and logic understanding.
I have a function in javascript that formats given number in Indian Number formatting standards (eg: 1,234 | 12,21,123 | etc)
Code
function formatter(input) {
var inputStr = input.toString(), l = inputStr.length;
var c = 1, f = 0;
console.log(l);
for (var x=l-1; x>=0; x--) {
if (x === 0) {
continue;
}
if (c === 3 && f === 0) {
inputStr = inputStr.substring(0, x) + ',' + inputStr.substring(x);
f = 1;
c = 0;
} else if (c % 2 === 0 && f === 1) {
inputStr = inputStr.substring(0, x) + ',' + inputStr.substring(x);
c = 0;
}
c++;
}
return inputStr;
}
Now this works for most part (as far as I have test, do point out bugs if you spot any). But my question is how do I handle large number in this, i.e. how do I handle values greater than 9007199254740991.
Hope this now fixes the issue:
function formatter(inputStr) {
inputStr+="";
let c = 1, f = 0;
for (let x=inputStr.length-1; x>=0; x--) {
if (x === 0) continue;
if (c === 3 && f === 0) {
inputStr = inputStr.substring(0, x) + ',' + inputStr.substring(x);
f = 1;
c = 0;
} else if (c % 2 === 0 && f === 1) {
inputStr = inputStr.substring(0, x) + ',' + inputStr.substring(x);
c = 0;
}
c++;
}
return inputStr;
}
//========= Tests =======
console.log(formatter(9007199254740991));
console.log(formatter("900719925474093454549341"));
console.log(formatter("123456678890987665443221112345667676766545434243"));

Executing java-script and using the result in my php query

I have a java-script function that carries out a calculation. I would like to use the answer to that calculation in my php code.
document.write(Fixed((PoissonTerm( X, Y )),8,4))
Both values X and Y come from variables within my php code so
<?php
$valueofx;
$valueofy;
?>
In the ideal world I would like to to look like this
<?php
$thejavascriptvalue = document.write(Fixed((PoissonTerm( $valueofx, $valueofy )),8,4))
?>
I know this can't be done and i have 5 different values i need to pull and use. Is there anyway I can work around it? I dont mind refreshing the page or grabbing it from another page as long as i can have 5 values to use in my php code.
I would need to run the javascript 10 times before redirecting like
document.write(Fixed((PoissonTerm(0.1, 0 )),8,4))
document.write(Fixed((PoissonTerm( 8, 2 )),8,4))
document.write(Fixed((PoissonTerm( 6, 3 )),8,4))
below if the javascript
function Fixed( s, wid, dec ) {
// many combinations of possibilities
// maybe prepare for upcoming truncate
var z = 1
if (dec > 0) {
z /= Math.pow( 10, dec );
if (s < -z) s -= 0.5 * z;
else
if (s > z) s += 0.5 * z;
else
s = 0;
}
// assure a string
s = "" + s;
// chop neg, if any
var neg = 0;
if (s.charAt(0) == "-") {
neg = 2;
s = s.substring( 1, s.length );
}
// chop exponent, if any
var exp = "";
var e = s.lastIndexOf( "E" );
if (e < 0) e = s.lastIndexOf( "e" );
if (e > -1) {
exp = s.substring( e, s.length );
s = s.substring( 0, e );
}
// if dec > 0 assure "."; dp == index of "."
var dp = s.indexOf( ".", 0 );
if (dp == -1) {
dp = s.length;
if (dec > 0) {
s += ".";
dp = s.length - 1;
}
}
// assure leading digit
if (dp == 0) {
s = '0' + s;
dp = 1;
}
// not enough dec pl? add 0's
while ((dec > 0) && ((s.length - dp - 1) < dec))
s += "0";
// too many dec pl? take a substring
var places = s.length - dp - 1;
if (places > dec)
if (dec == 0)
s = s.substring( 0, dp );
else
s = s.substring( 0, dp + dec + 1 );
// recover exponent, if any
s += exp;
// recover neg, if any
if (neg > 0)
s = "-" + s;
// if not enough width, add spaces IN FRONT
// too many places? tough!
while (s.length < wid)
s = " " + s;
return s
}
function Prb( x ) {
if (x < 0) x = 0;
else
if (x > 1) x = 1;
return x;
}
function PosV( x ) {
if (x < 0) x = -x;
return x;
}
// FACTORIALS
function Fact( x ) {
// x factorial
var t=1;
while (x > 1)
t *= x--;
return t;
}
function LnFact( x ) {
// ln(x!) by Stirling's formula
// see Knuth I: 111
if (x <= 1) x = 1;
if (x < 12)
return Math.log( Fact(Math.round(x)) );
else {
var invx = 1 / x;
var invx2 = invx * invx;
var invx3 = invx2 * invx;
var invx5 = invx3 * invx2;
var invx7 = invx5 * invx2;
var sum = ((x + 0.5) * Math.log(x)) - x;
sum += Math.log(2*Math.PI) / 2;
sum += (invx / 12) - (invx3 / 360);
sum += (invx5 / 1260) - (invx7 / 1680);
return sum;
}
}
// POISSON
function PoissonPD( u, k ) {
// Peizer & Pratt 1968, JASA 63: 1416-1456
var s = k + (1/2);
var d1 = k + (2/3) - u;
var d2 = d1 + 0.02/(k+1);
var z = (1 + g(s/u)) / u;
z = d2 * Math.sqrt(z);
z = NormalP( z );
return z;
}
function PoissonTerm( u, k ) {
// by logs
return Math.exp( (k * Math.log(u)) - u - LnFact(k) );
}
function PoissonP( u, k ) {
// term-by-term summation
if (k >= 20) return PoissonPD( u, k );
else {
var sum = 0.0, j = 0;
while (j <= k)
sum += PoissonTerm( u, j++ );
if (sum > 1) sum = 1;
return sum;
}
}
function DoPoi( aform ) {
var u = PosV(parseFloat(aform.u.value));
aform.u.value = Fixed(u,10,4);
var k = PosV(parseInt(aform.k.value));
aform.k.value = Fixed(k,8,0);
aform.tnk.value = Fixed(PoissonTerm( u, k ),8,4);
var t = PoissonP( u, k );
aform.puk.value = Fixed(t,8,4);
aform.quk.value = Fixed(1-t,8,4);
}
This is very generic. You're going to have to modify this to your needs. But this will give you the basic idea:
<form name="thisform" action="phpPage.php" method="POST">
X: <input type="text" name="val_x" id="val_x" value="40" /><br />
Y: <input type="text" name="val_y" id="val_y" value="60" /><br />
<input type="button" onclick="sendForm();" value="send form"/>
</form>
JavaScript:
function sendForm(){
//Choose one of these methods:
//This will generate a string that you can use as a location.
//use $_GET in PHP to retrieve the values
var valofX = document.getElementById("val_x").value;
var valofy = document.getElementById("val_y").value;
generateURL = 'phpPage.php?val_x=' + valofX;
generateURL += '&val_y=' + valofy;
document.location = generateURL;
//This will submit the form.
//use $_POST in PHP to retrieve the values
document.getElementById("thisform").submit();
}
Once the form is submitted, or the location is sent, you'll need to grab the values in PHP:
$val_x = $_POST['val_x'];
$val_y = $_POST['val_y'];
//OR
$val_x = $_GET['val_x'];
$val_y = $_GET['val_y'];
You would use $_GET or $_POST depending on how the values are sent.

Diamond-Square Algorithm Seems to Be Taking Values from Opposite Edge of Array

I made a map using the diamond-square algorithm. It works, but there are areas exclusively at the top of the map that seem to be using values from the other side of the map. I do not know what is causing this, and would like some help finding it.
Here's an image of the problem:
This is the relevant code, but I do not know where the problem occurs.
p = [
[y[0] + c, y[1]],
[y[0] - c, y[1]],
[y[0], y[1] + c],
[y[0], y[1] - c]
];
for (var m = 0; m < 4; m++) {
//Calculate Current Suare
var t = [];
// Add only those points to t that do not cross the edge in
// the direction in which they move away from p[m]:
if (p[m][0] + c <= s) {
t.push([p[m][0] + c, p[m][1]]);
}
if (p[m][0] - c >= 0) {
t.push([p[m][0] - c, p[m][1]]);
}
if (p[m][1] + c <= s) {
t.push([p[m][0], p[m][1] + c]);
}
if (p[m][1] - c >= 0) {
t.push([p[m][0], p[m][1] - c]);
}
var z = [
p[m],
y
];
//Check for edge
if ((p[m][0] === 0 || p[m][0] == s) || (p[m][1] === 0 || p[m][1] == s)) {
for (var k = 0; k < t.length; k++) {
if ((t[k][0] < 0 || t[k][0] > s) || (t[k][1] < 0 || t[k][1] > s)) {
t.splice(k, 1);
break;
}
}
}
//Set values
ar[p[m][0]][p[m][1]] = (t.map(function (e) {
return ar[e[0]][e[1]];
}).reduce(function (a, b) {
return a + b;
}) / t.length) + rand(n);
}
Here is a fiddle of the complete code:
http://jsfiddle.net/Shamadruu/7zutLnfL/18/
The problem is in the for(var k loop: you stop looking for cross-edge conditions once
you have found one (you break), but there could be two of them.
Although you could solve that by removing the break and adding k--;, there is a more
efficient way to deal with the edges: test before adding the points to t whether they
are within the edges. With these particular points that means you need to test them only
against one edge each, which is a savings of factor 4!
var t = [];
// Add only those points to t that do not cross the edge in
// the direction in which they move away from p[m]:
if (p[m][0] + c <= s) {
t.push([p[m][0] + c, p[m][1]]);
}
if ([p[m][0] - c >= 0) {
t.push([p[m][0] - c, p[m][1]]);
}
if (p[m][1] + c <= s) {
t.push([p[m][0], p[m][1] + c]);
}
if (p[m][1] - c >= 0) {
t.push([p[m][0], p[m][1] - c]);
}
var z = [
p[m],
y,
];
//Set values ...etc.
Similarly, you will have to review the inclusion of squares in z to make sure they do not cross the edge:
//Find New Square
switch (m) {
case 0:
if (p[m][0] - c >= 0 && p[m][1] + c <= s) {
z.push([p[m][0] - c, p[m][1] + c], [p[m][0], p[m][1] + c]);
}
break;
// ... etc.

Most effecient way to solve a formula in javascript

Say I have the following formula
a + (13 * (b/c)) + d + (12 * e) - f - 11 + (g * (h/i)) - 10 = 66;
Now the letters a-i can represent a number from 1-9. However, each number can only be used once. What would be the most efficient way to solve this? The way I have at the moment is to generate an array of random numbers e.g.
array[2,5,1,7,8,6,9,3,4]
I then fit this into the formula to check if it equals 66. If not, I generate a new array of numbers. I was thinking there should be a better way to do this though, maybe using recursion?
Just wanted to get some input in how you would tackle this?
Thanks
I think there's no smarter algorithm than just trying with each permutation of the numbers in the set for equality. Which I think will be easier for you, than creating everytime an unique array, that was not already generated.
In the code bellow I have used very primitive check for equality between numbers. There might be an easier way from the standard javascript library (e.g. if number is found in the predefined set...)
var solutions = [];
for (var a = 1; a <= 9; a++) {
for (var b = 1; b <= 9; b++) {
if ( b == a ) continue;
for (var c = 1; c <= 9; c++) {
if ( c == b || c == a ) continue;
for (var d = 1; d <= 9; d++) {
if ( d == c || d == b || d == a ) continue;
for (var e = 1; e <= 9; e++) {
if ( e == d || e == c || e == b || e == a ) continue;
for (var f = 1; f <= 9; f++) {
if ( f == e || f == d || f == c || f == b || f == a ) continue;
for (var g = 1; g <= 9; g++) {
if ( g == f || g == e || g == d || g == c || g == b || g == a ) continue;
for (var h = 1; h <= 9; h++) {
if ( h == g || h == f || h == e || h == d || h == c || h == b || h == a ) continue;
for (var i = 1; i <= 9; i++) {
if ( i == h || i == g || i == f || i == e || i == d || i == c || i == b || i == a ) continue;
if ((a + (13 * (b/c)) + d + (12 * e) - f - 11 + (g * (h/i)) - 10) == 66) {
solutions.push(a + "," + b + "," + c + "," + d + "," + e + "," + f + "," + g + "," + h + "," + i);
}
}
}
}
}
}
}
}
}
}
console.log(solutions);
Which results into a lot of solutions
["1,2,6,4,7,8,3,5,9", "1,2,6,4,7,8,5,3,9", "1,3,2,4,5,8,7,9,6", "1,3,2,4,5,8,9,7,6", "1,3,2,9,5,6,4,7,8", "1,3,2,9,5,6,7,4,8", "1,3,4,7,6,5,2,9,8", "1,3,4,7,6,5,9,2,8", "1,3,6,2,7,9,4,5,8", "1,3,6,2,7,9,5,4,8", "1,3,9,4,7,8,2,5,6", "1,3,9,4,7,8,5,2,6", "1,4,8,2,7,9,3,5,6", "1,4,8,2,7,9,5,3,6", "1,5,2,3,4,8,7,9,6", "1,5,2,3,4,8,9,7,6", "1,5,2,8,4,7,3,9,6", "1,5,2,8,4,7,9,3,6", "1,5,3,9,4,2,7,8,6", "1,5,3,9,4,2,8,7,6", "1,9,6,4,5,8,3,7,2", "1,9,6,4,5,8,7,3,2", "1,9,6,7,5,2,3,4,8", "1,9,6,7,5,2,4,3,8", "2,1,4,3,7,9,5,6,8", "2,1,4,3,7,9,6,5,8", "2,3,6,1,7,9,4,5,8", "2,3,6,1,7,9,5,4,8", "2,4,8,1,7,9,3,5,6", "2,4,8,1,7,9,5,3,6", "2,8,6,9,4,1,5,7,3", "2,8,6,9,4,1,7,5,3", "2,9,6,3,5,1,4,7,8", "2,9,6,3,5,1,7,4,8", "3,1,4,2,7,9,5,6,8", "3,1,4,2,7,9,6,5,8", "3,2,1,5,4,7,8,9,6", "3,2,1,5,4,7,9,8,6", "3,2,4,8,5,1,7,9,6", "3,2,4,8,5,1,9,7,6", "3,2,8,6,5,1,7,9,4", "3,2,8,6,5,1,9,7,4", "3,5,2,1,4,8,7,9,6", "3,5,2,1,4,8,9,7,6", "3,6,4,9,5,8,1,7,2", "3,6,4,9,5,8,7,1,2", "3,9,2,8,1,5,6,7,4", "3,9,2,8,1,5,7,6,4", "3,9,6,2,5,1,4,7,8", "3,9,6,2,5,1,7,4,8", "4,2,6,1,7,8,3,5,9", "4,2,6,1,7,8,5,3,9", "4,3,2,1,5,8,7,9,6", "4,3,2,1,5,8,9,7,6", "4,3,9,1,7,8,2,5,6", "4,3,9,1,7,8,5,2,6", "4,9,6,1,5,8,3,7,2", "4,9,6,1,5,8,7,3,2", "5,1,2,9,6,7,3,4,8", "5,1,2,9,6,7,4,3,8", "5,2,1,3,4,7,8,9,6", "5,2,1,3,4,7,9,8,6", "5,3,1,7,2,6,8,9,4", "5,3,1,7,2,6,9,8,4", "5,4,1,9,2,7,3,8,6", "5,4,1,9,2,7,8,3,6", "5,4,8,9,6,7,1,3,2", "5,4,8,9,6,7,3,1,2", "5,7,2,8,3,9,1,6,4", "5,7,2,8,3,9,6,1,4", "5,9,3,6,2,1,7,8,4", "5,9,3,6,2,1,8,7,4", "6,2,8,3,5,1,7,9,4", "6,2,8,3,5,1,9,7,4", "6,3,1,9,2,5,7,8,4", "6,3,1,9,2,5,8,7,4", "6,9,3,5,2,1,7,8,4", "6,9,3,5,2,1,8,7,4", "7,1,4,9,6,5,2,3,8", "7,1,4,9,6,5,3,2,8", "7,2,8,9,6,5,1,3,4", "7,2,8,9,6,5,3,1,4", "7,3,1,5,2,6,8,9,4", "7,3,1,5,2,6,9,8,4", "7,3,2,8,5,9,1,6,4", "7,3,2,8,5,9,6,1,4", "7,3,4,1,6,5,2,9,8", "7,3,4,1,6,5,9,2,8", "7,5,2,8,4,9,1,3,6", "7,5,2,8,4,9,3,1,6", "7,6,4,8,5,9,1,3,2", "7,6,4,8,5,9,3,1,2", "7,9,6,1,5,2,3,4,8", "7,9,6,1,5,2,4,3,8", "8,2,4,3,5,1,7,9,6", "8,2,4,3,5,1,9,7,6", "8,3,2,7,5,9,1,6,4", "8,3,2,7,5,9,6,1,4", "8,5,2,1,4,7,3,9,6", "8,5,2,1,4,7,9,3,6", "8,5,2,7,4,9,1,3,6", "8,5,2,7,4,9,3,1,6", "8,6,4,7,5,9,1,3,2", "8,6,4,7,5,9,3,1,2", "8,7,2,5,3,9,1,6,4", "8,7,2,5,3,9,6,1,4", "8,9,2,3,1,5,6,7,4", "8,9,2,3,1,5,7,6,4", "9,1,2,5,6,7,3,4,8", "9,1,2,5,6,7,4,3,8", "9,1,4,7,6,5,2,3,8", "9,1,4,7,6,5,3,2,8", "9,2,8,7,6,5,1,3,4", "9,2,8,7,6,5,3,1,4", "9,3,1,6,2,5,7,8,4", "9,3,1,6,2,5,8,7,4", "9,3,2,1,5,6,4,7,8", "9,3,2,1,5,6,7,4,8", "9,4,1,5,2,7,3,8,6", "9,4,1,5,2,7,8,3,6", "9,4,8,5,6,7,1,3,2", "9,4,8,5,6,7,3,1,2", "9,5,3,1,4,2,7,8,6", "9,5,3,1,4,2,8,7,6", "9,6,4,3,5,8,1,7,2", "9,6,4,3,5,8,7,1,2", "9,8,6,2,4,1,5,7,3", "9,8,6,2,4,1,7,5,3"]
If the formula is only this, and will not change, you might try to think if there are ranges that are not included in the result set per definition. For example, if you find that some of the numbers cannot be 9, you should not iterate to 9. E.g. the multiplications in the formula might exceed a number that even added to the minimal values in the other variables to exceed 66.
Brute force method:
function findSolution() {
for (var a = 1; a <= 9; a++) {
for (var b = 1; b <= 9; b++) {
for (var c = 1; c <= 9; c++) {
for (var d = 1; d <= 9; d++) {
for (var e = 1; e <= 9; e++) {
for (var f = 1; f <= 9; f++) {
for (var g = 1; g <= 9; g++) {
for (var h = 1; h <= 9; h++) {
for (var i = 1; i <= 9; i++) {
if (
[b,c,d,e,f,g,h,i].indexOf(a) >= 0 ||
[a,c,d,e,f,g,h,i].indexOf(b) >= 0 ||
[a,b,d,e,f,g,h,i].indexOf(c) >= 0 ||
[a,b,c,e,f,g,h,i].indexOf(d) >= 0 ||
[a,b,c,d,f,g,h,i].indexOf(e) >= 0 ||
[a,b,c,d,e,g,h,i].indexOf(f) >= 0 ||
[a,b,c,d,e,f,h,i].indexOf(g) >= 0 ||
[a,b,c,d,e,f,g,i].indexOf(h) >= 0 ||
[a,b,c,d,e,f,g,h].indexOf(i) >= 0
) {
continue;
}
if (a + (13 * (b/c)) + d + (12 * e) - f - 11 + (g * (h/i)) - 10 === 66) {
return [a,b,c,d,e,f,g,h,i];
}
}
}
}
}
}
}
}
}
}
}
document.getElementById('result').innerText = findSolution().join(', ')
<span id="result"></span>

Categories