I trying to push an array I've generated to a multidimensional array, and for some reason the value of all the other positions in the array's values, are the same as the value I just pushed.
For example: I do
var grades = [];
for(var i = 0; i < num_qes + 1; i++){
var grade = [0, 0, 0, 0];
grade[0] = i;
for(var n = 0; n < num_qes+ 1; n++){
grade[1] = n;
for(var f = 0; f < num_qes+ 1; f++){
grade[2] = f;
for(var t = 0; t < num_qes+ 1; t++){
grade[3] = t;
allGrad = grade[0] + grade[1] + grade[2] + grade[3];
//println(allGrad);
if(allGrad === num_qes){
grades.push(grade);
}
}
}
}
Here at the end I check to see if all of the values in my generated array are exactly equal to the number of questions.
if(allGrad === num_qes){
grades.push(grade);
}
Let's say that grade = [9, 1, 0, 0], when I push this value to the multidimensional array, grades, all the values change to [9, 1, 0, 0]. So the multidimensional array looks like this: [[9, 1, 0, 0], [9, 1, 0, 0], [9, 1, 0, 0]], when it SHOULD look like this: [[9, 0, 0, 1], [9, 0, 1, 0], [9, 1, 0, 0]].
I hope what I said make senses, and thanks in advance for ansnewing.
The jsfiddle is right here
Is this what you are after?
var grades = [];
var num_qes = 4;
for(var i = 0; i <= num_qes; i++){
for(var n = 0; n <= num_qes; n++){
for(var f = 0; f <= num_qes; f++){
for(var t = 0; t <= num_qes; t++){
var sum = i + n + f + t;
if(sum === num_qes){
console.log(i + ',' + n + ',' + f + ',' + t);
var grade = [i, n, f, t];
grades.push(grade);
}
}
}
}
}
Notes:
I've replaced i < num_qes + 1 with i <= num_ques for simplicity
Only creating the grade array in the inner loop when your condition is met (makes it much more readable)
Summing the numbers directly rather than reading from the grade array you've just populated (again more readable)
Using console.log() to output results that match criteria
Results in console look like this...
0,0,0,4
0,0,1,3
0,0,2,2
0,0,3,1
0,0,4,0
0,1,0,3
0,1,1,2
0,1,2,1
0,1,3,0
etc
Related
I want to collect all subarrays for further computation efficiently in javascript. I'm not sure this is possible, but it seems for a subarray sum kadane's formula is o(n) which is more efficient than other methods. But I'm not sure I how I can store the array at each step.
Similar to this quora question, for me the pseudo code was not enough. Thanks for the further breakdown.
another meta link
an example in action of this for [3, 3, 9, 9, 5]
[3], [9], [5], [9, 5], [9, 3], [9, 9], [3, 3],
[3, 9, 9], [3, 3, 9], [9, 9, 5], [3, 3, 9, 9],
[3, 9, 9, 5], [3, 3, 9, 9, 5]
I had done a work previously to calculate all combinations of amino acids total molecular weight. If you neglect the empty one you should have 2^n - 1 sub arrays. So there is no O(n) here. I've got two methods as binary and recursive.
function getSubArrays(arr){
var len = arr.length,
subs = Array(Math.pow(2,len)).fill();
return subs.map((_,i) => { var j = -1,
k = i,
res = [];
while (++j < len ) {
k & 1 && res.push(arr[j]);
k = k >> 1;
}
return res;
}).slice(1);
}
console.log(JSON.stringify(getSubArrays([1,2,3,4,5])));
function getSubArrays(arr){
if (arr.length === 1) return [arr];
else {
subarr = getSubArrays(arr.slice(1));
return subarr.concat(subarr.map(e => e.concat(arr[0])), [[arr[0]]]);
}
}
console.log(JSON.stringify(getSubArrays([1,2,3,4,5])));
I couldn't manage to get subarrays of an array with more than 23 items though.
Here are the performances. To be on the safe side i try with 22 items, first with recursive and then with binary route.
function getSubArrays(arr){
if (arr.length === 1) return [arr];
else {
subarr = getSubArrays(arr.slice(1));
return subarr.concat(subarr.map(e => e.concat(arr[0])), [[arr[0]]]);
}
}
var aminos = Array(22).fill().map((_,i) => i+1),
subarrs = [],
ps = 0,
pe = 0;
ps = performance.now();
subarrs = getSubArrays(aminos);
pe = performance.now();
console.log("recursive route took: " + (pe-ps) + "msec to produce " + subarrs.length + " sub arrays");
function getSubArrays(arr){
var len = arr.length,
subs = Array(Math.pow(2,len)).fill();
return subs.map((_,i) => { var j = -1,
k = i,
res = [];
while (++j < len ) {
k & 1 && res.push(arr[j]);
k = k >> 1;
}
return res;
}).slice(1);
}
var aminos = Array(22).fill().map((_,i) => i+1),
subarrs = [],
ps = 0,
pe = 0;
ps = performance.now();
subarrs = getSubArrays(aminos);
pe = performance.now();
console.log("binary route took: " + (pe-ps) + "msec to produce " + subarrs.length + " sub arrays");
This is fairly simple to do: https://jsfiddle.net/j1LuvxLq/
All you do is iterate possible lenghts and starting points and just print out the subsets. Complexity is O(n²) where n is the length of the original array. No way to improve it thought because that's the order of how many subsets there are.
var set = [3, 3, 9, 9, 5].join('')
var set_length = set.length
var subsets = []
for (var length_of_subset = 1; length_of_subset <= set_length; length_of_subset++) {
for (var start_of_subset = 0; start_of_subset <= set_length - length_of_subset; start_of_subset++) {
var current_subset = set.substring(start_of_subset, start_of_subset + length_of_subset)
if(subsets.indexOf(current_subset) == -1) {
subsets.push(current_subset.split(''))
}
}
}
// print the subsets out
for (s in subsets) {
$('body').append(subsets[s].join(', ') + '<br>')
}
Alternative, possibly nicer solution would be to use dynamic programming. Start with 3 and either remove last element or add next element. Check it out here: https://jsfiddle.net/p82fcs4m/
var set = [3, 3, 9, 9, 5].join('')
var subsets = []
take(set[0], set.substring(1))
function take(chosen, left) {
if(subsets.indexOf(chosen) != -1) {
return
}
subsets.push(chosen)
if (chosen.length > 1) {
take(chosen.substring(1), left)
}
if (left.length > 0) {
take(chosen.concat(left[0]), left.substring(1))
}
}
$('body').append(subsets.join('<br>'))
Try this:
function getSubArrays(arr) {
const subArrays = [];
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length - i; j++) {
const subArray = arr.slice(i, j + i + 1);
subArrays.push(subArray);
}
}
}
Still O(n²) tho
I believe using Array.slice is the most clean way to do it, isn't it?
function getSubArrays(arr) {
const subArrays = [];
for (var i = 0; i < arr.length; i++) {
for (var j = i; j < arr.length; j++) {
subArrays.push(arr.slice(i, j + 1));
}
}
return subArrays;
}
I am new to JavaScript, and I have an array which contains numbers.
var arr = [2,4,8,1,5,9,3,7,6];
How can I sort it using a native for loop in JavaScript?
I know sort function is available, but I want it through for loop.
The output should be:
var res = [1,2,3,4,5,6,7,8,9];
var Arr = [1, 7, 2, 8, 3, 4, 5, 0, 9];
for (var i = 1; i < Arr.length; i++)
for (var j = 0; j < i; j++)
if (Arr[i] < Arr[j]) {
var x = Arr[i];
Arr[i] = Arr[j];
Arr[j] = x;
}
console.log(Arr);
I would do something like this...
var input = [2,3,8,1,4,5,9,7,6];
var output = [];
var inserted;
for (var i = 0, ii = input.length ; i < ii ; i++){
inserted = false;
for (var j = 0, jj = output.length ; j < jj ; j++){
if (input[i] < output[j]){
inserted = true;
output.splice(j, 0, input[i]);
break;
}
}
if (!inserted)
output.push(input[i])
}
console.log(output);
Maybe there are more efficient ways, but if you want to use the for loop, it's my first idea...
First create an empty array where the sorted numbers will be pushed into.
let sorted = [];
Secondly, create a very large amount of numbers that none of the numbers of the array can match. This number will be used for the very first comparison to determine which number of the array is smaller.
let comparison = 9000000000;
Create a for loop.
This loop will have another loop inside of it. The inner loop will check for the smallest number in a given array, and once the smallest number is gotten, it will be push into the empty array we created. The smallest number will also be removed from the initial array and then the array will run again.
for(a = 0; a < arr.length; a++){
//This inner loop fetches the smallest number.
for(b = 0; b < arr.length; a++){
if(comparison > arr[b]){
comparison = arr[b];
}
}
// The smallest number is assigned to comparison
// Now it being pushed to the empty array
sorted.push(comparison);
// Remove the smallest number from the initial array
let indexOfSmallNumber = arr.indexOf(comparison);
arr.splice(indexOfSmallNumber, 1);
// Set the comparison back to 9000000000;
comparison = 90000000000;
a = -1;
// Here, "a" is our main loop index counter and we are
// setting it to -1 because we don't want it to change
// to 2 by default, doing this will make the loop run
// forever until the initial array is empty.
}
let arr = [4, 2, 5, 1]
let temp;
function converter(arr) {
for(let i=0; i<arr.length; i++) {
for (let j=i+1; j<arr.length; j++) {
if(arr[i] > arr[j]) {
temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
}
}
}
return arr
}
const newArr = converter(arr)
console.log(newArr)
Use:
let s = [4, 6, 3, 1, 2];
for (let i = 0; i < s.length;) {
if (s[i] > s[i + 1]) {
let a = s[i];
s[i] = s[i + 1];
s[i + 1] = a;
i--;
}
else {
i++;
}
}
This is a sorting algorithm which has a best time complexity of O(n) and the worst time of O(n^2).
This code checks for each number, and then compares to all numbers on the left side.
To check the time it takes each code to run, you can also use this code below:
let start = process.hrtime.bigint()
let end = process.hrtime.bigint()
console.log(end - start) // This measures the time used in nano seconds.
Also for microseconds, you can use this performance.now().
Here there is a very simple solution that uses a temporary array to store the values greater than the current one. Then it puts the current value between the lesser and the greater values:
var arr = [2,4,8,1,5,9,3,7,6];
var res = [];
for (const c of arr) {
let tmp = [];
while (c < res[res.length-1]) {
tmp.unshift(res.pop());
}
res = [...res, c, ...tmp];
}
const numberArr = [5, 9, 2, 8, 4, 10, 1, 3, 7, 6];
function sortedFunction(arr) {
let sortedArr = [];
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
let n = 0;
if (arr[i] > arr[j]) {
n = arr[i];
arr[i] = arr[j];
arr[j] = n;
}
}
sortedArr.push(arr[i]);
}
return sortedArr;
}
sortedFunction(numberArr);
Under the JavaScript array sort section of W3Schools it talks about how to compare a value in an array with the others and then order them based on the values being returned. I updated the code to use a for loop to sort values.
// Ascending points
var points = [5.0, 3.7, 1.0, 2.9, 3.4, 4.5];
var output = [];
var i;
for (i = 0; i < points.length; i++) {
points.sort(function (a, b) {
return a - b
});
output += points[i] + "<br>";
}
console.log(output);
// Descending points
var points = [5.0, 3.7, 1.0, 2.9, 3.4, 4.5];
var output = [];
var i;
for (i = 0; i < points.length; i++) {
points.sort(function (a, b) {
return b - a
});
output += points[i] + "<br>";
}
console.log(output);
const array = [12, 3, 45, 61, 23, 45, 6, 7];
function sortArray(array) {
for (var i = 0; i < array.length; ++i) {
for (var j = 0; j < array.length - 1 - i; ++j) {
if (array[j] > array[j + 1]) {
[array[j], array[j + 1]] = [array[j + 1], array[j]];
}
}
}
return array;
}
console.log(sortArray(array));
Here are the two solutions for the same algorithm:
Solution 1:
We can directly use JavaScript functions:
let arr = [2, 4, 8, 1, 5, 9, 3, 7, 6]
const changeOrder = (arr) => {
return arr.sort((a, b) => a - b)
}
let result = changeOrder(arr);
console.log(result) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Solution 2:
We can use a JavaScript for loop for doing the same
let arr = [2, 4, 8, 1, 5, 9, 3, 7, 6]
const changeOrder = (arr) => {
for(let i=1; i< arr.length; i++) {
for(let j=0; j < i; j++) {
if(arr[i] < arr[j]) {
let x = arr[i]
arr[i] = arr[j]
arr[j] = x
}
}
}
return arr;
}
let result = changeOrder(arr);
console.log(result) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
An improvement to previous answer
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
let temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
I am attempting to get all the numbers between 1-400 listed within a multidimensional array.
I do not want any repeating numbers ( 1 will only be in the array once, as will 18, 100, 385, and so on ) and I do not wish for these numbers to just be completely in order, I want them to be placed in the array at random locations..
Example (I made this by hand from 1-10):
var pairs =[
[3, 9],
[6, 4],
[2, 1],
[5, 8],
[7, 10],
//... and up to
[185, 400]
]
So, is there any way to make javascript create an array like this automatically, but to much larger numbers?
Thanks for any help!
You can use a standard Fisher-Yates shuffle algorithm as follows:
function generateRandomPairs(numberOfPairs)
{
var i, j, numbers, tmp, pairs;
// fill array
numbers = [];
for (i = 0; i < numberOfPairs * 2; i++)
{
numbers[i] = i + 1;
}
// randomize array really good
for (i = 0; i < numberOfPairs * 2 - 1; i++)
{
j = Math.floor(Math.random() * (numberOfPairs * 2 - i)) + i;
// swap element i with element j
tmp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = tmp;
}
// transform linear array to pairs
pairs = [];
for (i = 0; i < numberOfPairs * 2; i += 2)
{
pairs.push([ numbers[i], numbers[i + 1] ]);
}
return pairs;
}
fill a one-dimensional array with the numbers from 1 to 400
shuffle the array (for instance with a Fisher-Yates shuffle)
copy the elements of the 1 dimensional array into your multi-dimensional array
Try this:
function range(from, to){
for(var i=0,n=from,r=[]; n<=to; i++,n++){
r[i] = n;
}
return r;
}
function shuffle(array){
for(var i=0,l=array.length,n,t,r=[]; i<l; i++){
n = Math.floor(Math.random()*(i+1)); t = array[i]; r[i] = array[n]; r[n] = t;
}
return r;
}
function randPairsFromRange(rangeArray){
var l = rangeArray.length;
if(l % 2 !== 0){
return false;
}
for(var i=0,n=1,s=shuffle(rangeArray),r=[]; i<l; i+=2,n+=2){
r.push([s[i], s[n]]);
}
return r;
}
console.log(randPairsFromRange(range(1,400)));
I have this array:
var x = [1,2,3,4,5,"a","b","c",9,10];
I would like to slice this array into this pattern:
var x = [[1,2,3],[2,3,4],[3,4,5],[4,5,"a"],[5,"a","b"],["a","b","c"],["b","c",9],["c",9,10]];
I used the following code and been able to get [[1,2,3],[4,5,"a"],["b","c",9],[10,11,12]] . But it doesn't work for me. I need to get the pattern above.
var stream = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
var x = ["a", "b", "c"];
var ad_time = 6;
var result = [];
var ad_index = stream.indexOf(ad_time);
if (~ad_index) {
for (var i = 0; i < x.length; i++) {
stream[ad_index + i] = x[i];
}
}
while (stream.length > 0) {
var chunk = stream.splice(0, 3);
result.push(chunk);
}
console.log(JSON.stringify(result));
Thanks in advence!
This code should do it:
var x = [1,2,3,4,5,"a","b","c",9,10];
var new_array = [];
for (var i = 0; i < x.length - 2; i++) {
new_array.push(x.slice(i, i + 3));
}
You can achieve it with a simple for loop:
var x = [1,2,3,4,5,"a","b","c",9,10];
var result = [];
for (var i = 0, il = x.length - 2; i < il; i++) {
result.push([x[i], x[i + 1], x[i + 2]]);
}
console.log(result);
EDIT: Array.slice() is more elegant, however it is much slower. On Chrome it is 80% - 85% slower according to this test. If you don't need to worry about performance, choose whichever you like. For example if you need to slice 8 elements from the array, then using x.slice(i + 8) is easier to write and read than [x[i], x[i + 1], x[i + 2], x[i + 3], ...]. However if performance matters, then direct access might be a better choice.
I am creating a game and I need to generate some game pieces. Each piece is an array consisting of 4 numbers(each represents a property of the piece) ranging from 0-2. I need to generate all combinations to get all the game pieces.
So I would need [1, 0, 2, 0], [2, 0, 0, 1], [0, 0, 0, 0], [1, 0, 1, 0] etc..
There should be 81 total combinations of [a, b, c, d] where each variable is a number 0-2.
I am using javascript but any psudocode would be helpful.
Any help is appreciated. Thanks!
Mine
var arr=[];
for (var str,i=0;i<81;i++) {
str = i.toString(3);
arr.push(("000"+str).slice(-4)); // Hmm, I thought slice returned an array.
}
Here is an update taking into account the comments from #katspaugh and #herby
var arr=[];
for (var str,i=81;i<162;i++) {
str = i.toString(3);
arr.push((str).slice(-4).split('').map(Number));
}
If it is a homework, tag it as such.
var BASE = 3, LEN = 4, LIMIT = Math.round(Math.pow(BASE, LEN));
var c = [];
for (var i = 0; i < LIMIT; ++i) {
var item = [];
for (var j = 0, k = i; j < LEN; ++j, k = Math.floor(k/BASE)) {
item.push(k % BASE);
}
c.push(item);
}
Here is a more tricky solution but showing the math behind it better, hopefully:
var BASE = 3, LEN = 4;
var powers = [];
for (var i = 0, LIMIT = 1; i < LEN; ++i, LIMIT *= BASE) {
powers.push(LIMIT);
}
var c = [];
for (i = 0; i < LIMIT; ++i) {
c.push(powers.map(function(basePower) {
return Math.floor(i/basePower) % BASE;
}));
}
var BASE = 3, COMB_LEN = 4
var max = parseInt(new Array(COMB_LEN + 1).join(BASE - 1), BASE),
comb = new Array(COMB_LEN + 1).join(0).split('').map(Number)
var combinations = [], i, n
for (i = 0; i <= max; i++) {
n = i.toString(BASE).split('').map(Number)
combinations.push(
comb.slice(0, COMB_LEN - n.length).concat(n)
)
}