Too short loop and infinite loop? - javascript

I'm trying to make a code that would represent the Law of Large numbers in mathematics. However, I've been having trouble trying to print 20 different numbers with one execution of a code. If I have the for loop limit to little (i.e. any number less than 12), it will only print out one number. If I have the limit too big (numbers bigger than 13), it will print out an infinite set of numbers.
var numPeople = [];
var coin = [0, 1];
var sameSide = [];
for (var i = 0; i < 9; i++) {
numPeople.push(i);
}
function coinFlip() {
for (var i = 0; i < numPeople.length; i++) {
coinChance = Math.floor(Math.random() * 100);
if (coinChance < 50) {
coinSide = coin[1];
} else {
coinSide = coin[2];
}
numPeople[i] = coinSide;
}
}
for (var i = 0; i < 2; i++) {
coinFlip();
for (var i = 0; i < numPeople.length; i++) {
for (var j = i; j < numPeople.length - i; i++) {
if (numPeople[i] === numPeople[j]) {
sameSide.push(true);
}
}
}
console.log(sameSide.length);
}

Related

longest common substring Multiple Input in JS

function LCSubStr(X, Y) {
let m = X.length;
let n = Y.length;
let result = 0;
let end;
let len = new Array(4);
for (let i = 0; i < len.length; i++) {
len[i] = new Array(n);
for (let j = 0; j < n; j++) {
len[i][j] = 0;
}
}
let currRow = 0;
for (let i = 0; i <= m; i++) {
for (let j = 0; j <= n; j++) {
if (i == 0 || j == 0) {
len[currRow][j] = 0;
}
else if (X[i - 1] == Y[j - 1]) {
len[currRow][j] = len[1 - currRow][j - 1] + 1;
if (len[currRow][j] > result) {
result = len[currRow][j];
end = i - 1;
}
}
else {
len[currRow][j] = 0;
}
}
currRow = 1 - currRow;
}
if (result == 0) {
return "-1";
}
return X.substr(end - result + 1, result);
}
// Driver Code
let X = "GeeksforGeeks";
let Y = "GeeksQuiz";
// function call
document.write(LCSubStr(X, Y));
How can I convert this code for multiple input?
I checked many lcs code but no one works with
ABCQEFDEFGHIJ BCXEFGYZBCDEWEFGHU > EFGH
This one just works good without any problem. I should convert this one for multiple input in Javascript.
Now we have X,Y but it shoulde be with multiple inputs.

Sum of Primes using Sieve of Eratosthenes can't find bug

I'm working in JavaScript and this is a bit confusing because the code is returning the correct sum of primes. It is working with larger numbers. There is a bug where for 977 it returns the sum of primes for 976, which is 72179, instead of the sum for 977 which is 73156. Everything I've test so far has come back correctly.
function sumPrimes(num) {
var sum = 0;
var count = 0;
var array = [];
var upperLimit = Math.sqrt(num);
var output = [];
for (var i = 0; i < num; i++) {
array.push(true);
}
for (var j = 2; j <= upperLimit; j++) {
if (array[j]) {
for (var h = j * j; h < num; h += j) {
array[h] = false;
}
}
}
for (var k = 2; k < num; k++) {
if (array[k]) {
output.push(k);
}
}
for (var a = 0; a < output.length; a++) {
sum += output[a];
count++;
}
return sum;
}
sumPrimes(977);
The problem stems from the fact that your "seive" Array is indexed from 0, but your algorithm assumes that array[n] represents the number n.
Since you want array[n]===true to mean that n is prime, you need an Array of length 978 if you want the last item to be indexed as array[977] and mean the number 977.
The issue seems to be fixed when I change all instances of < num to < num+1.

detecting range overlaps in Google Calendar-Style event list

I need help fixing my existing code to accomplish what I am trying to do.
with the following sample data:
var SAMPLE_DATA = [{start: 30, end: 150}, {start: 540, end: 600}, {start: 560, end: 620}, {start: 610, end: 670}];
I need to do the following:
iterate through each sample object
determine if the current objects range (obj.start:obj.end) overlaps with any other object ranges.
record the total number of overlaps for that object into totalSlots property
determine the "index" of the object (used for it's left-to-right positioning)
mockup of what I am trying to accomplish:
As you can see in the mockup, slotIndex is used to determine the left-to-right ordering of the display. totalSlots is how many objects it shares space with (1 meaning it is the only object). 100 / totalSlots tells me how wide the square can be (i.e. totalSlots=2, means it is 100 / 2, or 50% container width).
Current Output from my code
Obj[0] slotIndex=0, totalSlots=0
Obj[1] slotIndex=1, totalSlots=1
Obj[2] slotIndex=1, totalSlots=2
Obj[3] slotIndex=0, totalSlots=1
expected/desired output from my code:
Obj[0] slotIndex=0, totalSlots=0
Obj[1] slotIndex=0, totalSlots=1
Obj[2] slotIndex=1, totalSlots=2
Obj[3] slotIndex=0, totalSlots=1
the code:
detectSlots: function(oldEventArr) {
oldEventArr.sort(this.eventSorter);
var newEventArr = [],
n = oldEventArr.length;
for (var i = 0; i < n; i++) {
var currObj = oldEventArr[i];
if ('undefined' == typeof currObj.totalSlots) {
currObj.slotIndex = 0;
currObj.totalSlots = 0;
}
for (var x = 0; x < n; x++) {
if (i == x) {
continue;
}
var nextObj = oldEventArr[x];
if (currObj.start <= nextObj.end && nextObj.start <= currObj.end) {
currObj.totalSlots++;
nextObj.slotIndex++;
}
}
newEventArr.push(currObj);
}
return newEventArr;
}
Please help me figure out what is going wrong in my code. I'm about 90% sure the problem lies in the if(currObj.start <= nextObj.end && nextObj.start <= currObj.end) statement where I am assigning/incrementing the values but I could use an extra set of eyes on this.
The slotIndex value can be calculated by using graph colouring algorithm. Note that brute force algorithm is exponential in time and will only be a viable solution for a small set of overlapping slots. Other algorithms are heuristics and you won't be guaranteed the least slot possible.
Here is an example of heuristic for your problem:
...
// init
var newEventArr = [], n = oldEventArr.length;
for (var i = 0; i < n; i+=1) {
var currObj = oldEventArr[i];
newEventArr.push({"start":currObj.start,"end":currObj.end,"slotIndex":undefined,"totalSlots":0});
}
var link = {};
// create link lists and totals
for (var i = 0; i < n; i+=1) {
var currObj = newEventArr[i];
if (!link.hasOwnProperty(""+i))
link[""+i] = {};
for (var j = i+1; j < n; j+=1) {
var nextObj = newEventArr[j];
var not_overlap = (currObj.end <= nextObj.start || nextObj.end <= currObj.start);
if (!not_overlap) {
currObj.totalSlots+=1;
nextObj.totalSlots+=1;
link[""+i][""+j] = 1;
if (!link.hasOwnProperty(""+j))
link[""+j] = {};
link[""+j][""+i] = 1;
}
}
}
var arrities = [];
for (var i = 0; i < n; i+=1) {
arrities.push( {"arrity":newEventArr[i].totalSlots, "indx":i} );
}
// sort by arrities [a better solution is using a priority queue]
for (var i = 0; i < n-1; i+=1) {
var current_arrity = -1, indx = -1;
for (var j = i; j < n; j+=1) {
if (arrities[j].arrity > current_arrity) {
indx = j;
current_arrity = arrities[j].arrity;
}
}
var temp = arrities[i];
arrities[i] = arrities[indx];
arrities[indx] = temp;
}
for (var i = 0; i < n; i+=1) {
var nodeIndex = arrities[i].indx;
// init used colors
var colors = [];
for (var j = 0; j < n; j+=1) {
colors.push(0);
}
//find used colors on links
for (var k in link[""+nodeIndex]) {
var color = newEventArr[k].slotIndex;
if (color || color === 0)
colors[color] += 1;
}
//find the first unused color
for (var j = 0; j < n; j+=1) {
if (colors[j] <= 0) {
// color the node
newEventArr[nodeIndex].slotIndex = j;
break;
}
}
}
return newEventArr;
...
like this
var not_overlap = (currObj.end <= nextObj.start || nextObj.end <= currObj.start);
if (!not_overlap) { ...
or
var overlap = (currObj.end > nextObj.start && nextObj.end < currObj.start);
if (overlap) { ...

Got 90% of the JavaScript code - can't figure out the rest

So I am trying to model Gram-Schmidt for any size N×N matrix, and I have officially hit a roadblock I can't get past. I know it's a matter of looping this correctly, but I can't figure out what the problem is. Remember I do not want to just pass in a 3×3 matrix, but any size N×N.
The course notes QR Decomposition with Gram-Schmidt explains exactly what I want to do. Very simple calculation by the way. In the course notes ||u|| means that it is the sum of the square of the elements, so sqrt(x12 + x22 + x32 + .... + xn2).
The multiplication symbol is actually the dot product.
The code I wrote so far is listed below. What is wrong with it?
function qrProjection(arr) {
var qProjected = [];
var tempArray = [];
var aTemp = arr;
var uTemp = new Array(arr.length);
var uSquareSqrt = new Array(arr.length);
var eTemp = [];
var sum = 0;
var sumOfSquares = 0;
var breakCondition = 0;
var secondBreakCondition = 0;
var iterationCounter = 0;
//Build uTemp Array
for (i = 0; i < arr.length; i++) {
uTemp[i] = new Array(arr[i].length);
}
for (i = 0; i < arr.length; i++) {
eTemp[i] = new Array(arr[i].length);
}
uTemp[0] = aTemp[0];
for (j = 0; j <= arr.length; j++) {
for (l = 0; l < arr[j].length; l++) {
if (breakCondition == 1) break;
sumOfSquares = Math.pow(uTemp[j][l], 2) + sumOfSquares;
}
if (breakCondition == 0) {
uSquareSqrt[j] = Math.sqrt(sumOfSquares);
sumOfSquares = 0;
}
for (i = 0; i < arr[j].length; i++) {
if (breakCondition == 1) break;
eTemp[j][i] = (1 / (uSquareSqrt[j])) * (uTemp[j][i]);
}
breakCondition = 1;
if (iterationCounter == 0) {
for (m = 0; m < arr[j].length; m++) {
matrixDotProduct = aTemp[j + 1][m] * eTemp[j][m] + matrixDotProduct;
}
}
else {
for (m = 0; m < arr[j].length; m++) {
for (s = 0; s <= iterationCounter; s++) {
matrixDotProduct = aTemp[j + 1][s] * eTemp[m][s] + matrixDotProduct;
}
for (t = 0; t < arr[j].length; t++) {
uTemp[j + 1][t] = aTemp[j + 1][t] - eTemp[j][t] * matrixDotProduct;
}
}
}
if (iterationCounter == 0) {
for (m = 0; m < arr[j].length; m++) {
uTemp[j + 1][m] = aTemp[j + 1][m] - eTemp[j][m] * matrixDotProduct;
}
}
matrixDotProduct = 0;
for (l = 0; l < arr[j].length; l++) {
sumOfSquares = Math.pow(uTemp[j + 1][l], 2) + sumOfSquares;
}
uSquareSqrt[j + 1] = Math.sqrt(sumOfSquares);
sumOfSquares = 0;
for (i = 0; i < arr[j].length; i++) {
eTemp[j + 1][i] = (1 / (uSquareSqrt[j + 1])) * (uTemp[j + 1][i]);
}
iterationCounter++;
}
qProjected = eTemp;
return qProjected;
}
I must apologize that instead of tweaking your code, I wrote my own from scratch:
/* Main function of interest */
// Each entry of a matrix object represents a column
function gramSchmidt(matrixA, n) {
var totalVectors = matrixA.length;
for (var i = 0; i < totalVectors; i++) {
var tempVector = matrixA[i];
for (var j = 0; j < i; j++) {
var dotProd = dot(matrixA[i], matrixA[j], n);
var toSubtract = multiply(dotProd, matrixA[j], n);
tempVector = subtract(tempVector, toSubtract, n);
}
var nrm = norm(tempVector, n);
matrixA[i] = multiply(1 / nrm, tempVector, n);
}
}
/*
* Example usage:
* var myMatrix = [[1,0,0],[2,3,0],[5,4,7]];
* gramSchmidt(myMatrix, 3);
* ==> myMatrix now equals [[1,0,0],[0,1,0],[0,0,1]]
* 3 here equals the number of dimensions per vector
*/
/* Simple vector arithmetic */
function subtract(vectorX, vectorY, n) {
var result = new Array(n);
for (var i = 0; i < n; i++)
result[i] = vectorX[i] - vectorY[i];
return result;
}
function multiply(scalarC, vectorX, n) {
var result = new Array(n);
for (var i = 0; i < n; i++)
result[i] = scalarC * vectorX[i];
return result;
}
function dot(vectorX, vectorY, n) {
var sum = 0;
for (var i = 0; i < n; i++)
sum += vectorX[i] * vectorY[i];
return sum;
}
function norm(vectorX, n) {
return Math.sqrt(dot(vectorX, vectorX, n));
}
Note that the algorithm above computes the Gram-Schmidt orthogonalization, which is the matrix [e1 | e2 | ... | en], not the QR factorization!

Problem with JavaScript Array

TilesArray.tiles has a wrong output, alert(TilesArray.array); gives me the correct output with randomized numbers, but at the end TilesArray.tiles has the same array in each index.
for (i = 0; i < 200; i++) {
for (j = 0; j < 200; j++) {
TilesArray.array[j] = (Math.round(Math.random() * 499 + 1));
}
alert(TilesArray.array);
TilesArray.tiles[i] = TilesArray.array;
}
Any solution to fix the issue?
You need to copy the array. Could be done with slice()
for (i = 0; i < 200; i++) {
for (j = 0; j < 200; j++) {
TilesArray.array[j] = (Math.round(Math.random() * 499 + 1));
}
alert(TilesArray.array);
TilesArray.tiles[i] = TilesArray.array.slice(0);
}
You're continuously adding a reference to the same array to tiles. To get around this, create a new array in each iteration of the outer loop:
for (i = 0; i < 200; i++) {
TilesArray.array = []; // This is the line
for (j = 0; j < 200; j++) {
TilesArray.array[j] = (Math.round(Math.random() * 499 + 1));
}
alert(TilesArray.array);
TilesArray.tiles[i] = TilesArray.array;
}
Or even better? Add everything directly to your tiles array (it's one less variable to worry about):
for (i = 0; i < 200; i++) {
TilesArray.tiles[i] = [];
for (j = 0; j < 200; j++) {
TilesArray.tiles[i][j] = (Math.round(Math.random() * 499 + 1));
}
}
At each iteration, you fill your TilesArray.array with new random values, and store a reference to this unique array in TilesArray.tiles[i]. But the array of random values is always the same. You just have many pointers to the same array.
You need to allocate a new array at each iteration :
for (i = 0; i < 200; i++) {
TilesArray.array = [];
for (j = 0; j < 200; j++) {
TilesArray.array[j] = (Math.round(Math.random() * 499 + 1));
}
alert(TilesArray.array);
TilesArray.tiles[i] = TilesArray.array;
}

Categories