Move an array in the place of another array - javascript

I am in the making of an apps script, that takes a specified range, divides it into subranges of 4 values each, and returns the array. It looks like this:
Code that follows that to divide it into said subranges:
function sort() {
const chunks = (range, size) =>
Array.from(
new Array(Math.ceil(range.length / size)),
(_, i) => range.slice(i * size, i * size + size)
);
let range = ranges.getValues().flat();
var array = chunks(range, 4)
}
}
}
}
Now, what I want to do with these, is that when someone removes data from one of the subranges, the ones below will go up, so that there are no gaps between the subranges. What I mean by that, is in the case of someone clearing data from, for example, the second subrange, all the ones that are below will go up.
NOTE: It is just a function that I later use in onChange(), and the ranges variable was called earlier throughout the code, and it's just a named range.
So far I've got this piece of code, but it doesn't seem to work:
for (let i = 0; i < array.length; i++) {
for (let j = 0; j < 4; j++) {
var equ = 0;
var mult = 0;
equ += array[i][j];
mult += array[i+1][j];
if (equ == 0 || "" && mult != "" && 0) {
array[i+1].copyTo(array[i], {contentsOnly:true})
}
}

Related

Deleting value from array in Javascript using method (function)

Im just creating a simple game using javascript. im just stuck in deleting a value from array.
I have an array for player one ( for player one values are generated by random number). Value is called in a div when the current random number generated is displayed ....
Now i want to delete value from array if the current generated random number is similar to value in array of player one.
var playerone_arr = [];
for (var i = 0; i <= 3; i++) {
playerone_arr[i] = Math.floor(Math.random() * 10) + 1;
document.getElementById("playerone_no").innerHTML += playerone_arr[i];
}
function player_one_play() {
var random_no = Math.floor(Math.random() * 10) + 1;
document.getElementById("player_result").innerHTML = random_no;
for (var i = 0; i < playerone_arr.length; i++) {
if (playerone_arr[i] == random_no) {
playerone_arr.splice(playerone_arr[i], 1);
}
}
}
Splice expects an index, so provide the index of the element you want to remove.
var index = playerone_arr.indexOf(random_no);
if (index >= 0 ) {
playerone_arr.splice(index, 1);
}

Javascript print square using for loop and conditional statement only

Just started my uni course, struggling a little with javascript. I have been asked to display a square using any character, however, the solution must combine for loops and if statements.
This is what I have so far and I feel pretty close but I just can't get the second line to display. I know this can be done via two for loops, (one for iteration of the variable and another for spaces). But this is not how I have been asked to solve this problem.
Here is my code:
var size = 3;
let i;
for(i = 0; i < size; i++) {
print ("*");
if (size === i){
println ("");
}
}
For context, this is all taking place int he professors homemade learning environment.
You could use nested for loops and take a line break after each filled line.
function print(s) { document.getElementById('out').innerHTML += s; }
function println(s) { document.getElementById('out').innerHTML += s + '\n'; }
var size = 5,
i, j;
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
print("*");
}
println("");
}
<pre id="out"></pre>
Single loop with a check if i is unequal to zero and if the remainder is zero, then add a line break.
Using:
=== identity/strict equality operator checks the type and the value, for example if both are numbers and if the value is the same,
!== non-identity/strict inequality operator it is like above, but it checks the oposite of it,
% remainder operator, which returns a rest of a number which division returns an integer number.
&& logical AND operator, which check both sides and returns the last value if both a truthy (like any array, object, number not zero, a not empty string, true), or the first, if it is falsy (like undefined, null, 0, '' (empty string), false, the oposite of truthy).
function print(s) { document.getElementById('out').innerHTML += s; }
function println(s) { document.getElementById('out').innerHTML += s + '\n'; }
var size = 5,
i;
for (i = 0; i < size * size; i++) {
if (i !== 0 && i % size === 0) {
println("");
}
print("*");
}
<pre id="out"></pre>
Well the for loop is only iterating 3 times, printing the first line. If you want a square you'll have to print 9 stars total, right? So i'm assuming, is this is the approach you'd go for, you would need to iterate not until size, but until size * size.
I'm using console.log to 'print' the square:
var dimension = 10;
var edge = '*';
var inside = ' ';
var printLine;
for (var i = 1; i <= dimension; i++) {
if (i === 1 || i === dimension) {
printline = Array(dimension + 1).join(edge);
} else {
printline = edge + Array(dimension - 1).join(inside) + edge;
}
console.log(printline);
}
Note that in the following example, an array of length 11 gets you only 10 "a"s, since Array.join puts the argument between the array elements:
Array(11).join('a'); // create string with 10 as "aaaaaaaaaa"
You wanna make a square of * where the size is the number of * on its sides?
Let's split a task into 3 parts:
where you print top side like *****
where you print middle (left and right sides) like * *
where you print bottom (same as top)
Now let's code that, I kept the code as simple as possible, this can be done in fewer lines but I think this will be easier to understand for beginners:
var size = 5;
var i = 0;
// top
for (i = 0; i < size; i++)
console.log("*");
//middle
for (var j = 0; j < size - 2; j++){
console.log("\n"); // go to next row
// middle (2 on sides with size-2 in between)
console.log("*");
for (i = 0; i < size-2; i++)
console.log(" ");
console.log("*\n"); // goes to new row as well
}
// same as top
for (i = 0; i < size; i++)
console.log("*");
Full square is even simpler:
var size = 5;
var i = 0;
for (var i = 0; i < size; i++){ // iterates rows
for (var j = 0; j < size; j++) // iterates * in row
console.log("*");
console.log("\n") // moves to new row
}
In order to print a row, you print same sign X times. Well, to print X rows we can use just that 1 more time (only this time we are iterating over a different variable (j is * in a row, i is a number of rows).
After a row is made we go to go to next row with \n.
As for
it must contain if statement
Put this at the end:
if (youCanHandleTheTruth) console.log("It's a terrible practice to tell students their solution MUST CONTAIN CODEWORDS. If you need them to showcase something, write appropriate task that will require them to do so.");

compute determinant of a matrix

I'm trying to compute determinant of a matrix in JS. I used algorithm from http://www.sanfoundry.com/java-program-compute-determinant-matrix/ but I lost my mind on the last condition. I just do not understand. Can you help me?
This is how looks like my code right now. In another function I create an empty 2d array and then copy it to det function. Next I retrieve values from html and then trying to compute determinant of a matrix. The first 2 cases are simple but I have a problem with the last one. I couldn't find working example in JS.
function det() {
var det = 0;
var array1 = array.slice();
for (i = 0; i < array1.length; i++) {
for (j = 0; j < array1[i].length; j++) {
array1[i][j] = parseInt(document.getElementById("element" + (i + 1) + (j + 1)).value, 10);
}
}
if (array1.length == 1) {
det = array1[0][0];
} else if (array1.length == 2) {
det = (array1[0][0] * array1[1][1]) - (array1[1][0] * array1[0][1]);
} else {
}
}
I may suggest my solution, based on recursive algorithm, which takes only few lines of code and, I guess, will suit most of practical applications:
const determinant = m =>
m.length == 1 ?
m[0][0] :
m.length == 2 ?
m[0][0]*m[1][1]-m[0][1]*m[1][0] :
m[0].reduce((r,e,i) =>
r+(-1)**(i+2)*e*determinant(m.slice(1).map(c =>
c.filter((_,j) => i != j))),0)
const test1 = [[3]] // 3
const test2 = [[3,-2],[7,4]] // 26
const test3 = [[1,3,7],[2,-1,4],[5,0,2]] // 81
console.log(determinant(test1))
console.log(determinant(test2))
console.log(determinant(test3))
.as-console-wrapper {min-height: 100%}
I created a Matrix class with some function for the basic operations, one of them the determinant calculation
Here we have the constructor
constructor(rows,cols) {
this.rows = rows;
this.cols = cols;
this.vals = new Array(rows*cols);
for(let i = 0; i < this.vals.length; i++) this.vals[i] = 0;
}
and here the determinant function
determinant() {
if (this.rows != this.cols ) {
console.log("Matrix must be square");
return;
}
let size = this.rows;
if (size == 1) return this.vals[0];
if (size == 2) return this.vals[0]*this.vals[3]-this.vals[1]*this.vals[2];
let sign = 1;
let result = 0;
for (let k = 0 ; k < size ; k++){
let cofactors = new Matrix(size-1,size-1);
cofactors.vals = this.vals.slice(size,size*size).filter((_,index)=>index%size!=k);
result += sign * this.vals[k] * cofactors.determinant();
sign*=(-1);
}
return result;
}
You can see definition of the determinant for square matrix here https://en.wikipedia.org/wiki/Determinant#n_.C3.97_n_matrices.
Algorithm used in http://www.sanfoundry.com/java-program-compute-determinant-matrix/ use some properties of determinat to calculate it in recursive way as sum over all permutations. In this way you get N * N! operations! It is very big even for small N.
For solving this problem you can first transform matrix to triangular with the same determinant and after that calculate determinant as product of all diagonal elements.

Javascript loop infinitely up till a certain condition

// Contains a list of items in each set.
var sets[0] = [1,2,3,4,5,6,7,8,9],
sets[1] = [10,11,12,13,14,15,16,17,18],
sets[2] = [19,20,21,22,23,25,26,27]
// Contains the mins associated to each set item.
var setTimes[0] = [15,15,15,15,15,15,15,15,15],
setTimes[1] = [16,12,11,15,13,15,15,15,14],
setTimes[2] = [16,12,11,15,13,12,11,15,13]
I've got a set of arrays as given above. The sets array has a data set of values. This array can have n number of items in it. Ex, sets[n].
Each sets array has an equivalent setTimes array that has minutes stored in it. setTimes[0][0] is 15min and is the number of minutes for sets[0][0].
Given a set item(ex 12), I'd like to:
Find out which set array does the given number belong to? In our case, since 12 was the item, it belongs to sets[1].
Once I have this, I'd like to get the sum of all mins from the setTimes array for the current sets index and also the next index. In our case, that would be the sum of setTimes[1] and setTimes[2].
In the event we reach the end of sets array, I'd like to get the sum of the first set array.
For ex,
- if I pass 12, I'll need to get the sum of setTimes[1] and setTimes[2]
- If I pass 23, I'll need to get the sum of setTimes[2] and setTimes[0]
Here is the loop I've been thinking, would like to know if there is a better way of doing this.
function computeTotalMin(givenItem)
{
// represents how many sets to loop thorough. I need 2.
for (x = 0; x <= 1; x++)
{
for(i = 0; i < sets.length; i++)
{
// checking to see if i value is on the last index of the sets array.
if(i === sets.length - 1)
{
i = 0;
var item = sets[i].indexOf(givenItem);
if(item !== -1)
{
// Loops through all mins from setTimes[i] array
for(j = 0; j < setTimes[i].length; j++)
{
var total = total + setTimes[j];
}
}
}
}
}
}
You don't need two nested loops for continuing at the end. You should have a single loop that iterates the number of sets you're interested in (2), and has an index (starting at the one set you've found). Inside that loop, you'd make a modulo operation on the index; to get back to the start when you've reached the end. By only looping over the count, not the (resettable) index, you won't get into an infinite loop.
You also should divide your program in just those tasks that you've textually described (find this, then do that), instead of munching everything in one huge nested control structure.
function computeTotalMin(givenItem) {
var setIndex = -1;
for (; setIndex < sets.length; setIndex++)
if (sets[setIndex].indexOf(givenItem) > -1)
break;
if (setIndex == sets.length)
return null; // givenItem found in none of the sets
var sum = 0;
for (var count = 0; count < 2; count++) {
for (var i=0; i<setTimes[setIndex].length; i++)
sum += setTimes[setIndex][i];
setIndex++; // go to next set
setIndex %= sets.length; // which might be 0
// alternatively: if (setIndex == sets.length) setIndex = 0;
}
return sum;
}

Sorting function?

I need to organize an array of strings of random length into the least number of new strings with a max size. Is there a function or something in javascript, or something that can be translated to javascript, that will do this?
For example, the new strings might have max lengths of 1000 characters. The array might have strings of lengths 100, 48, 29, etc. I would want to combine those strings into as few new strings as possible.
edit: Sorry if this doesn't make sense, I tried my best.
No standard method in Javascript, but plenty of theoretical work has been done on this (i.e. the bin packing problem).
http://en.wikipedia.org/wiki/Bin_packing_problem
Some sample pseudo code in the link - should be trivial to translate to javascript.
The algorithm shown isn't going to be optimal in every case. To find the optimal solution to your example you'll just need to iterate over every possibility which might not be that bad depending on how many strings you have.
For my own entertainment, I wrote a simple bin packing algorithm. I picked a simple algorithm which is to sort the input strings by length. Create a new bin. Put the first (longest remaining) string into the bin and then keep filling it up with the longest strings that will fit until no more strings will fit. Create a new bin, repeat. To test it, I allocate an array of strings of random lengths and use that as input. You can see the output visually here: http://jsfiddle.net/jfriend00/FqPKe/.
Running it a bunch of times, it gets a fill percentage of between 91-98%, usually around 96%. Obviously the fill percentage is higher if there are more short strings to fill with.
Here's the code:
function generateRandomLengthStringArrays(num, maxLen) {
var sourceChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY1234567890";
var sourceIndex = 0;
var result = [];
var len, temp, fill;
function getNextSourceChar() {
var ch = sourceChars.charAt(sourceIndex++);
if (sourceIndex >= sourceChars.length) {
sourceIndex = 0;
}
return(ch);
}
for (var i = 0; i < num; i++) {
len = Math.floor(Math.random() * maxLen);
temp = new String();
fill = getNextSourceChar();
// create string
for (var j = 0; j < len; j++) {
temp += fill;
}
result.push(temp);
}
return(result);
}
function packIntoFewestBins(input, maxLen) {
// we assume that none of the strings in input are longer than maxLen (they wouldn't fit in any bin)
var result = [];
// algorithm here is to put the longest string into a bin and
// then find the next longest one that will fit into that bin with it
// repeat until nothing more fits in the bin, put next longest into a new bin
// rinse, lather, repeat
var bin, i, tryAgain, binLen;
// sort the input strings by length (longest first)
input.sort(function(a, b) {return(b.length - a.length)});
while (input.length > 0) {
bin = new String(); // create new bin
bin += input.shift(); // put first one in (longest we have left) and remove it
tryAgain = true;
while (bin.length < maxLen && tryAgain) {
tryAgain = false; // if we don't find any more that fit, we'll stop after this iteration
binLen = bin.length; // save locally for speed/convenience
// find longest string left that will fit in the bin
for (i = 0; i < input.length; i++) {
if (input[i].length + binLen <= maxLen) {
bin += input[i];
input.splice(i, 1); // remove this item from the array
tryAgain = true; // try one more time
break; // break out of for loop
}
}
}
result.push(bin);
}
return(result);
}
var binLength = 60;
var numStrings = 100;
var list = generateRandomLengthStringArrays(numStrings, binLength);
var result = packIntoFewestBins(list, binLength);
var capacity = result.length * binLength;
var fillage = 0;
for (var i = 0; i < result.length; i++) {
fillage += result[i].length;
$("#result").append(result[i] + "<br>")
}
$("#summary").html(
"Fill percentage: " + ((fillage/capacity) * 100).toFixed(1) + "%<br>" +
"Number of Input Strings: " + numStrings + "<br>" +
"Number of Output Bins: " + result.length + "<br>" +
"Bin Legnth: " + binLength + "<br>"
);

Categories

Resources