Generate new random values and store in an array - javascript

I am trying to generate two random values and store them in an array however I would like them to be different values each time a random number between 0-3 is generated.
function new_Randomvalues(n) {
var array1 = [];
for (var i = 0; i < n; i++) {
var row = Math.round(3*Math.random());
var col = Math.round(3*Math.random());
array1.push([row,col]);
}
return array1;
}
console.log(new_Randomvalues(10));
How do I edit this function where if an array of same numbers are pushed into array1 then remove those and generate 10 unique coordinates.
Help would be appreciated thanks

Per sam's question in the comments, here's the code:
function shuffle(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
pairs = [];
for (let i = 0; i <= 3; i++) {
for (let j = 0; j <= 3; j++) {
pairs.push([i, j]);
}
}
shuffle(pairs);
pairs = pairs.slice(0, 10);
console.log(pairs);

Related

How nested loops are executed in this case?

Why the result is [[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0]] ?
How is this code executed? Cause is not so intuitive..
function zeroArray(m, n) {
let newArray = [];
let row = [];
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
row.push(0);
}
newArray.push(row);
}
return newArray;
}
let matrix = zeroArray(3, 2);
console.log(matrix);
Your code adds to row m * n times. The row is pushed m times into new Array
The fact that you add to row after you push it into newArray, doesn't mean row is magically cleared
To prove it is the same array in each row, consider this code
function zeroArray(m, n) {
let newArray = [];
let row = [];
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
row.push(0);
}
newArray.push(row);
}
return newArray;
}
let matrix = zeroArray(3, 2);
matrix[0][0]=1;
console.log(JSON.stringify(matrix));
See how changing [0][0] also changes [1][0] and [2][0] - that's because each row is the exact same array
Note: In the solutions below, I've added matrix[0][0] = 1 to demonstrate that the above problem is not present, i.e. each row is a different array - obviously you'd not include that line in your actual code
Two simple solutions: 1 - set row = [] after you push it
function zeroArray(m, n) {
let newArray = [];
let row = [];
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
row.push(0);
}
newArray.push(row);
row = [];
}
return newArray;
}
let matrix = zeroArray(3, 2);
matrix[0][0]=1;
console.log(JSON.stringify(matrix));
solution 2: declare row inside the first loop
function zeroArray(m, n) {
let newArray = [];
for (let i = 0; i < m; i++) {
let row = [];
for (let j = 0; j < n; j++) {
row.push(0);
}
newArray.push(row);
}
return newArray;
}
let matrix = zeroArray(3, 2);
matrix[0][0]=1;
console.log(JSON.stringify(matrix));
and a modern solution
function zeroArray(m, n) {
return Array.from({length: m}).map(() => Array(n).fill(0));
}
let matrix = zeroArray(3, 2);
matrix[0][0]=1;
console.log(JSON.stringify(matrix));

Performance: why is the first implementation of the same algorithm significantly faster

The algorithm is taken from LeetCode: https://leetcode.com/problems/maximum-product-of-word-lengths/description/
Here is the jsperf I created (I have some local tests which gives the same result): https://jsperf.com/maximum-product-of-word-lengths
Here is the first "slow" implementation:
function maxProduct (words) {
if (!words || !words.length) return 0;
let len = words.length;
let values = [];
// console.log(values)
for (let i = 0; i < len; ++i) {
let tmp = words[i];
let num = 0, len = tmp.length;
for (let j = 0; j < len; ++j) {
num |= 1 << (tmp.charCodeAt(j) - 'a'.charCodeAt(0));
}
values[i] = {
num: num,
len: tmp.length
};
}
let maxProduct = 0;
for (let i = 0; i < len; ++i) {
for (let j = 0; j < len; ++j) {
if ((values[i].num & values[j].num) == 0) {
maxProduct = Math.max(maxProduct, values[i].len * values[j].len);
}
}
}
return maxProduct;
};
Here is the "fast" implementation:
function maxProductFast (words) {
var temp = [];
for(var i = 0; i < words.length; i++){
var tempObj = {};
tempObj.item = words[i];
var num = 0;
for(var j = 0; j < words[i].length; j++){
num |= 1 << (words[i].charCodeAt(j) - 97);
}
tempObj.num = num;
temp.push(tempObj);
}
var res = 0;
for(var i = 0; i < temp.length; i++){
for(var j = i + 1; j < temp.length; j++){
var item1 = temp[i];
var item2 = temp[j];
if((item1.num & item2.num) == 0) {
res = Math.max(res, item1.item.length * item2.item.length);
}
}
}
return res;
}
They're not the same. The second algorithm has a loop with a complexity of (n*(n+1))/2 where each progressive step is from i+1 to the length of temp. the first algorithm has a two nested for loops each with a cost of n^2. the complexity of both will reduce to O(n^2). I believe that both of these will have a similar performance with a significantly large enough set.
The reason you would do n+1 for each sub iteration is because you are trying to find the max of any pair of items. if you place your elements in a grid you will notice that any diagonal pair a_3 * a_2 = a_2 * a_3 produces the same value. you can basically halve the collection and save a few cycles.

Faster Algorithm for JavaScript function call within a function

I have written a function and called another function inside but my tests show that it is not time optimized. How can I make the following code faster?
function maxSum(arr, range) {
function sumAll(array1, myrange) {
var total = 0;
if (Array.isArray(myrange)) {
for (var i = myrange[0]; i <= myrange[1]; i++) {
total += array1[i];
}
return total;
} else return array1[myrange];
}
var mylist = [];
var l = range.length;
for (var n = 0; n < l; n++) {
mylist.push(sumAll(arr, range[n]));
}
return Math.max.apply(null, mylist);
}
Algorithmic optimization: create new array with cumulative sums from index 0 to every index
cumsum[0] = 0;
for (var i = 1; i <= arr.Length; i++) {
cumsum[i] = cumsum[i-1] + arr[i-1]
Now you don't need to calculate sums for every range - just get difference
sum for range (i..j) = cumsum[j+1] - cumsum[i];
in your terms:
function sumAll(array1, myrange) {
return cumsum[myrange[1]+1] - cumsum[myrange[0]];
}
example:
arr = [1,2,3,4]
cumsum = [0,1,3,6,10]
sum for range 1..2 = 6 - 1 = 5
P.S. If your array might be updated, consider Fenwick tree data structure
1) You can define the function sumAll outside of the function maxSum because every time you call maxSum the javascript engine is recreating a fresh new function sumAll.
2) You can define myrange[1] as a variable in the initialiser part to avoid javascript to look for myrange[1] at each iteration.
for (var i = myrange[0]; i <= myrange[1]; i++) {
total += array1[i];
}
become this:
for (var i = myrange[0], len = myrange[1]; i <= len; i++) {
total += array1[i];
}
Full working code based on #MBo's excellent optimization. This passes all the tests at https://www.codewars.com/kata/the-maximum-sum-value-of-ranges-challenge-version/train/javascript, which I gather is where this problem comes from.
function maxSum(arr, ranges) {
var max = null;
var sums = [];
var sofar = 0;
for (var i = 0; i <= arr.length; i++) {
sums[i] = sofar;
sofar += arr[i];
}
for (var i = 0; i < ranges.length; i++) {
var sum = sums[ranges[i][1]+1] - sums[ranges[i][0]];
if (max === null || sum > max) {
max = sum;
}
}
return max;
}

How to I run a function for each piece of an array within a for loop in Javascript?

I have this so far, trying to get it to find the sum of each one of any number of inputted numbers with integers and "-"s.
When I run this,
var howM = prompt("How many cards?")
var arr = [];
for (var i = 0; i < howM; i++)
arr.push(prompt("Enter a card:"));
console.log(arr)
var sumpre = [];
for (var i = 0; i <= howM; i++) {
var sum = 0;
var eXt = arr[i];
eXt = eXt.replace(/-/g, "");
for (i = 0; i < eXt.length; i++) {
sum += parseInt(eXt.substr(i, 1));
}
sumpre.push(sum);
}
console.log(sumpre)
I have also tried
var howM = prompt("How many cards?")
var arr = [];
for (var i = 0; i < howM; i++)
arr.push(prompt("Enter a card:"));
console.log(arr)
for (var i = 0; i < howM; i++) {
var sum = 0;
var eXt = arr[i]
eXt = eXt.replace(/-/g, "");
for (i = 0; i < eXt.length; i++) {
sum += parseInt(eXt.substr(i, 1));
}
}
console.log(sum);
In both cases I get the sum for the first piece in the array and then undefined. How do I get it to run for each piece? I kind of have an idea of what is wrong with it I just don't quite know how to fix it.
You need to use a second counter for the nested for loop, like so:
var howM = prompt("How many cards?")
var arr = [];
for(var i = 0; i < howM; i++)
arr.push(prompt("Enter a card:"));
console.log(arr)
var sumpre = [];
for(var i = 0; i < howM; i++) {
var sum = 0;
var eXt = arr[i];
eXt = eXt.replace (/-/g, "");
for (var j = 0; j < eXt.length; j++) {
sum += parseInt(eXt.substr(j, 1));
}
sumpre.push(sum);
}
console.log(sumpre)
Your var sum = 0; inside your for-loop meaning sum variable will not be accessible outside of the loop

Create multidimensional array in for loop

I want to create a multidimensional array like this:
array[0][1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
array[1][21,22,23,24,25,26,27....]
array[.][....]
How can I do this in Javascript?
I have tried this:
var squares = new Array();
for(var i = 1; i <= 8; i++)
{
for(var j = 1; j <= 20; j++)
{
squares.push(i, j);
}
}
How can I accomplish this?
You can do something like this:
var squares = new Array();
for(var i = 0; i <= 8; i++)
{
squares[i] = new Array();
for(var j = (i * 20) + 1; j <= 20 * i + 20; j++)
if (squares[i] == null)
squares[i] = j;
else
squares[i].push(j);
}
Output comes like:
array[0][1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
array[1][21,22,23,24,25,26,27....]
var array = []; // Main array
var numArrays = 10, // Number of sub-arrays
numPerArray = 20; // Number of squares per sub-array
for(var i = 0; i < numArrays; i++){
var subArray = [];
// Number to start at
var start = i * numPerArray;
// Count up to start + numPerArray
for(var j = start; j < start + numPerArray; j++){
subArray.push(j);
}
// Add to main array
array.push(subArray);
}
Use modulus operand to limit the inner array's size
var limit = 80
var inner_limit = 20
var square=[]
var inner =[]
for(var i=1;i<=limit;i++){
inner.push(i)
if(i%inner_limit==0){
square.push(inner)
inner = []
}
}
You can do it with two "for" loops. In the first loop you go through the main array and for each element add the elements from the second loop.
var arrayLength = 10; // Main array length
var limit = 20; // Number of squares
var array = [];
for ( var i = 0; i < arrayLength; i++ )
{
array[i] = []; // Create subArray
for( var j = 1; j <= limit; j++ )
{
array[i].push(j);
}
}

Categories

Resources