permutation need help to code - javascript

Thank for your reply, first thing i wish to thank you for trying to help me out, and i have post this in few website also no one trying to help at all.
For my code, what i wish to do is permutation count.
it will count from top to bottom
1,2,3
1,2,3
1,2,3
output to
111 = 1
112 = 1
113 = 1
121 = 1
122 = 1
123 = 1
133 = 1
211 = 1
212 = 1
213 = 1
333 = 1
and continue till all number is count and also store to the array which can check how many count after all
code will check the input number and count how many outcome and show the results with how many outcome and each have how many after permutation count.
Its hard to do?.
Anyway thank you for help.

It's not that hard, I guess. It's just the standard permutation thing. You'll need to use a little recursion:
function permute(size) {
var range = getRange(size);
var result = [];
getSubPerms('', range, result);
return result;
};
function getRange(size) {
var range = [];
for (var i = 0; i < size; i++) {
range.push(i + 1);
}
return range;
}
function getSubPerms(perm, range, result) {
for (var i = 0; i < range.length; i++) {
var perm2 = perm + range[i];
if (perm2.length == range.length) {
result.push(perm2);
} else {
getSubPerms(perm2, range, result);
}
}
}
var foo = permute(4); //an array of all of your results.
alert(foo.length); //256
However, if you're only interested in the length of that, without having to generate the results, it would simply be Math.pow(size, size) to get the length of your results.

Related

Countdown 3rd array element and print sorted even numbers

I am trying to solve this task I have and I do not seem to know what is the issue with it exactly.
My task requires the following;
1- countdown from a given number by 3
2- only print the even numbers
4- sorted
what I did so far;
function cd (num){
let arrayCount = [];
let arrayEven = [];
for(let i = 0; i <= num; i++) {
arrayCount.push(num-i);
}
//return arrayCount;
for (let j = 0; j <= arrayCount.length; j+=3) {
if (arrayCount[j] % 2 == 0) {
arrayEven.push(arrayCount[j]);
}
}
arrayEven.sort(function(a,b){return a - b;});
return arrayEven;
}
console.log(cd(10)); // expected output [4]
console.log(cd(23)); // expected output [2,8,14,20]
console.log(cd(103)); // expected output [4,10,16,22,28,34,40,46,52,58,64,70,76,82,88,94,100]
console.log(cd(15)); //expected output [6,12]
My issue is with input 15 and 10 and I am not sure what I am doing work. Any help would be appreciated.
So, I figured out what was missing. The thing is that the loop would always print the first element and THEN apply the conditions you want on the rest of the elemnts, and that is why in input [10] the number 10 was printed. In short, I just needed to let my loop start from i = num-3. Thank you for you comments as they helped me a lot. Although the solution was right there, still I wanted to share the updated part, so here you go:
for (let i = num-3; i > 0; i-=3) {
if (i % 2 == 0)
array.push(i);
} let result = array.sort((a, b) => a - b);

How to get numbers of variants numerical combinations in javascript?

I need to implement a function that accepts two parameters - the number of 0 and the number of 1 and determine how many ways to place these 0 and 1 so that there are no two zeros in a row.
For example, I need to find all methods of placing two 0 and two 1.
There are six possible ways to place them: 0011, 0101, 0110, 1001, 1010, 1100.
In three cases there are two zeros in a row: 0011, 1001 and 1100.
I subtract them from the total number and get three possible ways: 0101, 0110 and 1010. So the answer is 3.
First, I'm trying to write script to recognize which cases I need
let arr = ["1100","1010","1001","0011","0101","0110"]
let result = [];
for (let i = 0; i < arr.length; i++){
let expVal = arr[i];
for (let p = 0; p < expVal.length; p++){
if (expVal[p] === expVal[p++] || expVal[p] === "0"){
result.push(expVal)
}
}
}
console.log(result);
It's does not work. I don't know how to fix it.
And I don't understand what I need to do later
The problem you are solving is equivalent to the Fibonacci sequence.
filter for includes '00'
recursive function x generates binary number strings using n0 zeroes, n1 ones. Works by branching to (add a zero, find combos for one less zero)'0'+x(n0-1,n1) and (add a one, find combos for one less 1)'1'+x(n0,n1-1).
let arr = ["1100","1010","1001","0011","0101","0110"]
const x = (n0,n1) =>
!(n0 === 0 || n1 === 0) ?
x(n0-1,n1).map(x=>'0'+x).concat(
x(n0,n1-1).map(x=>'1'+x))
: ['0'.repeat(n0)||'1'.repeat(n1)]
arr = x(2,2)
console.log(
x(2,2)
)
console.log(arr.filter(x=>x.includes('00')))
There are 2 issues with the code, as far as I can see:
You're incrementing p two times: once in the for definition, and once in the execution itself (p++). The second one should be replaced by p+1
Also, you're checking if the next character is equal to the current, OR the current character is 0. This should be AND.
let arr = ["1100","1010","1001","0011","0101","0110"]
let result = [];
for (let i = 0; i < arr.length; i++){
let expVal = arr[i];
for (let p = 0; p < expVal.length; p++){
if (expVal[p] === expVal[p+1] && expVal[p] === "0"){
result.push(expVal)
}
}
}
console.log(result);
Changing those two things fixes it.

Why does this loop terminate partway through?

I'm trying to write a program to find the smallest common multiple of the provided parameters that can be evenly divided by both, as well as by all sequential numbers in the range between these parameters.
The range will be an array of two numbers that will not necessarily be in numerical order.
For example, for 1 and 3 - find the smallest common multiple of both 1 and 3 that is evenly divisible by all numbers between 1 and 3.
Why does the loop stop at i = 510,000 (or something close to that) instead of 7,000,000, as I set it?
I also have a screenshot with the output:
function smallestCommons(arr) {
var start;
var finish;
var something;
if(arr[0] < arr[1]){start = arr[0]; finish = arr[1];}else{
start = arr[1]; finish = arr[0];
}
for(var i = finish;i <= 7000000;i++){
var boolea = true;
for(var j = start;j <= finish;j++){
if(i % j !== 0){boolea = false;break;} // 2 % 1
}
if(boolea)return i;
something = i;
}
console.log("final i = " + i);
return 0;
}
Try to add this at the beginning of your loop
// noprotect
it must be that jsbin is forcing your code to exit from the loop. See source

Efficiently find every combination of assigning smaller bins to larger bins

Let's say I have 7 small bins, each bin has the following number of marbles in it:
var smallBins = [1, 5, 10, 20, 30, 4, 10];
I assign these small bins to 2 large bins, each with the following maximum capacity:
var largeBins = [40, 50];
I want to find EVERY combination of how the small bins can be distributed across the big bins without exceeding capacity (eg put small bins #4,#5 in large bin #2, the rest in #1).
Constraints:
Each small bin must be assigned to a large bin.
A large bin can be left empty
This problem is easy to solve in O(n^m) O(2^n) time (see below): just try every combination and if capacity is not exceeded, save the solution. I'd like something faster, that can handle a variable number of bins. What obscure graph theory algorithm can I use to reduce the search space?
//Brute force
var smallBins = [1, 5, 10, 20, 30, 4, 10];
var largeBins = [40, 50];
function getLegitCombos(smallBins, largeBins) {
var legitCombos = [];
var assignmentArr = new Uint32Array(smallBins.length);
var i = smallBins.length-1;
while (true) {
var isValid = validate(assignmentArr, smallBins, largeBins);
if (isValid) legitCombos.push(new Uint32Array(assignmentArr));
var allDone = increment(assignmentArr, largeBins.length,i);
if (allDone === true) break;
}
return legitCombos;
}
function increment(assignmentArr, max, i) {
while (i >= 0) {
if (++assignmentArr[i] >= max) {
assignmentArr[i] = 0;
i--;
} else {
return i;
}
}
return true;
}
function validate(assignmentArr, smallBins, largeBins) {
var totals = new Uint32Array(largeBins.length);
for (var i = 0; i < smallBins.length; i++) {
var assignedBin = assignmentArr[i];
totals[assignedBin] += smallBins[i];
if (totals[assignedBin] > largeBins[assignedBin]) {
return false;
}
}
return true;
}
getLegitCombos(smallBins, largeBins);
Here's my cumbersome recursive attempt to avoid duplicates and exit early from too large sums. The function assumes duplicate elements as well as bin sizes are presented grouped and counted in the input. Rather than place each element in each bin, each element is placed in only one of duplicate bins; and each element with duplicates is partitioned distinctly.
For example, in my results, the combination, [[[1,10,20]],[[4,5,10,30]]] appears once; while in the SAS example in Leo's answer, twice: once as IN[1]={1,3,4} IN[2]={2,5,6,7} and again as IN[1]={1,4,7} IN[2]={2,3,5,6}.
Can't vouch for efficiency or smooth-running, however, as it is hardly tested. Perhaps stacking the calls rather than recursing could weigh lighter on the browser.
JavaScript code:
function f (as,bs){
// i is the current element index, c its count;
// l is the lower-bound index of partitioned element
function _f(i,c,l,sums,res){
for (var j=l; j<sums.length; j++){
// find next available duplicate bin to place the element in
var k=0;
while (sums[j][k] + as[i][0] > bs[j][0]){
k++;
}
// a place for the element was found
if (sums[j][k] !== undefined){
var temp = JSON.stringify(sums),
_sums = JSON.parse(temp);
_sums[j][k] += as[i][0];
temp = JSON.stringify(res);
var _res = JSON.parse(temp);
_res[j][k].push(as[i][0]);
// all elements were placed
if (i == as.length - 1 && c == 1){
result.push(_res);
return;
// duplicate elements were partitioned, continue to next element
} else if (c == 1){
_f(i + 1,as[i + 1][1],0,_sums,_res);
// otherwise, continue partitioning the same element with duplicates
} else {
_f(i,c - 1,j,_sums,_res);
}
}
}
}
// initiate variables for the recursion
var sums = [],
res = []
result = [];
for (var i=0; i<bs.length; i++){
sums[i] = [];
res[i] = [];
for (var j=0; j<bs[i][1]; j++){
sums[i][j] = 0;
res[i][j] = [];
}
}
_f(0,as[0][1],0,sums,res);
return result;
}
Output:
console.log(JSON.stringify(f([[1,1],[4,1],[5,1],[10,2],[20,1],[30,1]], [[40,1],[50,1]])));
/*
[[[[1,4,5,10,10]],[[20,30]]],[[[1,4,5,10,20]],[[10,30]]],[[[1,4,5,20]],[[10,10,30]]]
,[[[1,4,5,30]],[[10,10,20]]],[[[1,4,10,20]],[[5,10,30]]],[[[1,4,30]],[[5,10,10,20]]]
,[[[1,5,10,20]],[[4,10,30]]],[[[1,5,30]],[[4,10,10,20]]],[[[1,10,20]],[[4,5,10,30]]]
,[[[1,30]],[[4,5,10,10,20]]],[[[4,5,10,20]],[[1,10,30]]],[[[4,5,30]],[[1,10,10,20]]]
,[[[4,10,20]],[[1,5,10,30]]],[[[4,30]],[[1,5,10,10,20]]],[[[5,10,20]],[[1,4,10,30]]]
,[[[5,30]],[[1,4,10,10,20]]],[[[10,10,20]],[[1,4,5,30]]],[[[10,20]],[[1,4,5,10,30]]]
,[[[10,30]],[[1,4,5,10,20]]],[[[30]],[[1,4,5,10,10,20]]]]
*/
console.log(JSON.stringify(f([[1,1],[4,1],[5,1],[10,2],[20,1],[30,1]], [[20,2],[50,1]])));
/*
[[[[1,4,5,10],[10]],[[20,30]]],[[[1,4,5,10],[20]],[[10,30]]],[[[1,4,5],[20]],[[10,10,30]]]
,[[[1,4,10],[20]],[[5,10,30]]],[[[1,5,10],[20]],[[4,10,30]]],[[[1,10],[20]],[[4,5,10,30]]]
,[[[4,5,10],[20]],[[1,10,30]]],[[[4,10],[20]],[[1,5,10,30]]],[[[5,10],[20]],[[1,4,10,30]]]
,[[[10,10],[20]],[[1,4,5,30]]],[[[10],[20]],[[1,4,5,10,30]]]]
*/
Here's a second, simpler version that only attempts to terminate the thread when an element cannot be placed:
function f (as,bs){
var stack = [],
sums = [],
res = []
result = [];
for (var i=0; i<bs.length; i++){
res[i] = [];
sums[i] = 0;
}
stack.push([0,sums,res]);
while (stack[0] !== undefined){
var params = stack.pop(),
i = params[0],
sums = params[1],
res = params[2];
for (var j=0; j<sums.length; j++){
if (sums[j] + as[i] <= bs[j]){
var _sums = sums.slice();
_sums[j] += as[i];
var temp = JSON.stringify(res);
var _res = JSON.parse(temp);
_res[j].push(i);
if (i == as.length - 1){
result.push(_res);
} else {
stack.push([i + 1,_sums,_res]);
}
}
}
}
return result;
}
Output:
var r = f([1,5,10,20,30,4,10,3,4,5,1,1,2],[40,50,30]);
console.log(r.length)
console.log(JSON.stringify(f([1,4,5,10,10,20,30], [40,50])));
162137
[[[30],[1,4,5,10,10,20]],[[10,30],[1,4,5,10,20]],[[10,20],[1,4,5,10,30]]
,[[10,30],[1,4,5,10,20]],[[10,20],[1,4,5,10,30]],[[10,10,20],[1,4,5,30]]
,[[5,30],[1,4,10,10,20]],[[5,10,20],[1,4,10,30]],[[5,10,20],[1,4,10,30]]
,[[4,30],[1,5,10,10,20]],[[4,10,20],[1,5,10,30]],[[4,10,20],[1,5,10,30]]
,[[4,5,30],[1,10,10,20]],[[4,5,10,20],[1,10,30]],[[4,5,10,20],[1,10,30]]
,[[1,30],[4,5,10,10,20]],[[1,10,20],[4,5,10,30]],[[1,10,20],[4,5,10,30]]
,[[1,5,30],[4,10,10,20]],[[1,5,10,20],[4,10,30]],[[1,5,10,20],[4,10,30]]
,[[1,4,30],[5,10,10,20]],[[1,4,10,20],[5,10,30]],[[1,4,10,20],[5,10,30]]
,[[1,4,5,30],[10,10,20]],[[1,4,5,20],[10,10,30]],[[1,4,5,10,20],[10,30]]
,[[1,4,5,10,20],[10,30]],[[1,4,5,10,10],[20,30]]]
This problem is seen often enough that most Constraint Logic Programming systems include a predicate to model it explicitly. In OPTMODEL and CLP, we call it pack:
proc optmodel;
set SMALL init 1 .. 7, LARGE init 1 .. 2;
num size {SMALL} init [1 5 10 20 30 4 10];
num capacity{LARGE} init [40 50];
var WhichBin {i in SMALL} integer >= 1 <= card(LARGE);
var SpaceUsed{i in LARGE} integer >= 0 <= capacity[i];
con pack( WhichBin, size, SpaceUsed );
solve with clp / findall;
num soli;
set IN{li in LARGE} = {si in SMALL: WhichBin[si].sol[soli] = li};
do soli = 1 .. _nsol_;
put IN[*]=;
end;
quit;
This code produces all the solutions in 0.06 seconds on my laptop:
IN[1]={1,2,3,4,6} IN[2]={5,7}
IN[1]={1,2,3,4} IN[2]={5,6,7}
IN[1]={1,2,3,6,7} IN[2]={4,5}
IN[1]={1,2,5,6} IN[2]={3,4,7}
IN[1]={1,2,5} IN[2]={3,4,6,7}
IN[1]={1,2,4,6,7} IN[2]={3,5}
IN[1]={1,2,4,7} IN[2]={3,5,6}
IN[1]={1,2,4,6} IN[2]={3,5,7}
IN[1]={1,3,4,6} IN[2]={2,5,7}
IN[1]={1,3,4} IN[2]={2,5,6,7}
IN[1]={1,5,6} IN[2]={2,3,4,7}
IN[1]={1,5} IN[2]={2,3,4,6,7}
IN[1]={1,4,6,7} IN[2]={2,3,5}
IN[1]={1,4,7} IN[2]={2,3,5,6}
IN[1]={2,3,4,6} IN[2]={1,5,7}
IN[1]={2,3,4} IN[2]={1,5,6,7}
IN[1]={2,5,6} IN[2]={1,3,4,7}
IN[1]={2,5} IN[2]={1,3,4,6,7}
IN[1]={2,4,6,7} IN[2]={1,3,5}
IN[1]={2,4,7} IN[2]={1,3,5,6}
IN[1]={3,5} IN[2]={1,2,4,6,7}
IN[1]={3,4,7} IN[2]={1,2,5,6}
IN[1]={3,4,6} IN[2]={1,2,5,7}
IN[1]={3,4} IN[2]={1,2,5,6,7}
IN[1]={5,7} IN[2]={1,2,3,4,6}
IN[1]={5,6} IN[2]={1,2,3,4,7}
IN[1]={5} IN[2]={1,2,3,4,6,7}
IN[1]={4,6,7} IN[2]={1,2,3,5}
IN[1]={4,7} IN[2]={1,2,3,5,6}
Just change the first 3 lines to solve for other instances. However, as others have pointed out, this problem is NP-Hard. So it can switch from very fast to very slow suddenly. You could also solve the version where not every small item needs to be assigned to a large bin by creating a dummy large bin with enough capacity to fit the entire collection of small items.
As you can see from the "Details" section in the manual, the algorithms that solve practical problems quickly are not simple, and their implementation details make a big difference. I am unaware of any CLP libraries written in Javascript. Your best bet may be to wrap CLP in a web service and invoke that service from your Javascript code.

How to sum up distinct value using javascript

I want to try and sum up distinct value from a list.. currently i am able to do so if theres only 2 similar record. If theres more than 2 i am not able to do the checking. Following is the javascript code:
function validateData(){
var total = document.frm.size.value;
var msg="";
var tbxA;
var tbxB;
var tbxA2;
var tbxB2;
var tbxC;
var totalValue =0;
var repeatedValue= 0;
var row = 0;
var row2 = 0;
for(var i=0; i<parseInt(total); i++){
tbxA = document.getElementById('tbx_A'+i).value;
tbxB = document.getElementById('tbx_B'+i).value-0;
tbxC = document.getElementById('tbx_C'+i).value;
for(var j=i+1; j<parseInt(total); j++){
tbxA2 = document.getElementById('tbx_A'+j).value;
tbxB2 = document.getElementById('tbx_B'+j).value-0;
if (tbxA==tbxA2) {
totalValue = tbxB + tbxB2;
}
if (totalValue != tbxC) {
repeatedValue= 1;
row = i;
row2 = j;
msg+="*total value does not add up at row " +(row2+1);
break;
}
}
if(repeatedValue== 1){
break;
}
}
return msg;
}
For example A:type of fruit, B: total of each fruit, C: how many bought at a time
total of C should be equal to B. i.e Apple: 3+3+4 = 10. So if the total is not equals to 10 it should prompt me an error.
A B C
Apple 10 3
Orange 10 10
Apple - 3
Apple - 4
My code above will prompt error bt it doesnt go beyond 2nd occurence of Apple.
So yes, how should i go about to ensure it loop through the whole list to sum up all similar values?
Thanks in advance for any possible help!
Try this:
var total = +document.frm.size.value,
data = {};
for(var i=0; i<total; ++i) {
var key = document.getElementById('tbx_A'+i).value;
data[key] = data[key] || {B:0, C:0};
data[key].B += +document.getElementById('tbx_B'+i).value || 0;
data[key].C += +document.getElementById('tbx_C'+i).value || 0;
}
for(var i in data) {
if(data.hasOwnProperty(i) && data[i].B != data[i].C) {
return "total value does not add up";
}
}
return "";
Some comments:
parseInt (and parseFloat) is very slow. + operator before string converts it to a number much faster. But if you really want to make sure the numbers are integers, use Math.floor(), Math.round(), Math.ceil() or the faster but illegible |0.
In case you really want parseInt (e.g. you want to convert '123foobar' into 123), always use a radix. For example: parseInt('123', 10)
Avoid doing calculations at the condition of a loop, because they run at each iteration. Just do the calculation once before the loop and save the result in a variable.

Categories