I'm playing around with online tests to improve my coding logic and I had a test where I needed to create a sample of a chessboard, where basically the input would be rows and columns of the chessboard, and then generate the output that was asked, but I'm not quite happy with my solution, I wonder if it is possible having the same output without having a temp variable, for example store the input values in a array and using some array functions that keeps looping inside giving me different values in the for loops. Here is my code:
/*
Sample output:
0101010
1010101
0101010
1010101
*/
function chess(m, n) { //7,4
var zero = 0;
var um = 1;
var temp = 0;
for (var i = 0; i < n; i++) {
for (var r = 0; r < m; r++) {
if (temp === 1) {
document.write(um);
temp = 0;
}
else {
document.write(zero);
temp = 1;
}
}
document.write("<br>");
}
}
chess(7, 4);
try
function chess(m,n){ //7,4
var zero = 0;
var um = 1;
var temp = 0;
for(var i = 0; i < n; i++){
for(var r = 0; r < m; r++){
if((i+r)%2 === 1){
document.write(um);
}else{
document.write(zero);
}
}
document.write("<br>");
}
}
chess(7,4);
You can directly compute and print. You do not need to store it in any variable.
function chess(m,n){ //7,4
for(var i = 0; i < n; i++){
for(var r = 0; r < m; r++){
document.write((i+r)%2);
}
document.write("<br>");
}
}
chess(7,4);
Related
I am looking to automatically remove tables in slides if they contain a specific text string. This is what I currently have, but for some reason, the findText() doesn't seem to work and I can't figure out an alternative to this...
function removeUnwantedTables() {
var gotSlides =
SlidesApp.openById('1gJjGBbaQXWhP8uhVIoccV2h_RL7_gsxvg_NW-qNCcLU').getSlides();
for (var i = 0; i < gotSlides.length; i++) {
var slide = gotSlides[i];
var tables = slide.getTables();
for (var k = 0; k < tables.length; k++) {
var allTables = tables[k];
if (allTables.findText('{{remove-this-table}}') > 0) {
allTables.remove();
}
}
}
}
Does anyone have a solution to this?
How about this modification? I think that there may be several answers. So please think of this as one of them.
Modification points :
Using getCell(), each cell are retrieved and compared to the string of {{remove-this-table}}.
I couldn't find the method for directly searching the string from a table. So I used this.
When {{remove-this-table}} is found, the table is removed and the for loop is broken away.
Modified script :
function removeUnwantedTables() {
var gotSlides = SlidesApp.openById('1gJjGBbaQXWhP8uhVIoccV2h_RL7_gsxvg_NW-qNCcLU').getSlides();
for (var i = 0; i < gotSlides.length; i++) {
var slide = gotSlides[i];
var tables = slide.getTables();
if (tables.length > 0) {
for (var k = 0; k < tables.length; k++) {
var allTables = tables[k];
row = allTables.getNumRows();
col = allTables.getNumColumns();
var values = [];
for (var r = 0; r < row; r++) {
for (var c = 0; c < col; c++) {
var v = allTables.getCell(r, c).getText().asString();
if (v.indexOf("{{remove-this-table}}") > -1) {
values.push(v);
break;
}
}
if (values.length > 0) {
allTables.remove();
break;
}
}
}
}
}
}
If this was not what you want, I'm sorry.
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;
}
The code below only executes through the first for loop once, yet all the other for loops perform as expected. Does anyone know why this is the case? I'm not sure how relevant the bulk of the (inefficient, poorly formatted) code within the loop is but I include it nonetheless.
var numbers = [9795526789839145, 2861747566959730, 4498854833783559, 6301982162016598, 1131197164065322];
for (i = 0; i < numbers.length; i++) {
var current = numbers[i];
var currentStr = current.toString();
var reverseStr = currentStr.split('').reverse().join('');
var reverseArr = [];
for (i = 0; i < reverseStr.length; i++) {
reverseArr.push(reverseStr[i]);
}
var A = 0;
for (i = 0; i < reverseArr.length; i += 2) {
A += Math.round((reverseArr[i]));
}
var evenDigits = [];
for (i = 1; i < reverseArr.length; i += 2) {
evenDigits.push(reverseArr[i]);
}
for (i = 0; i < evenDigits.length; i++) {
evenDigits[i] = evenDigits[i] * 2;
if (evenDigits[i] > 9) {
var temp = evenDigits[i].toString();
var firstInt = Math.round(temp[0]);
var secondInt = Math.round(temp[1]);
evenDigits[i] = firstInt + secondInt;
}
}
var B = 0;
for (i = 0; i < evenDigits.length; i++) {
B += evenDigits[i];
}
var sum = A + B;
if (sum % 10 == 0) {
console.log('Yes');
} else console.log('No');
}
In your code you are using same instance of 'i' variable to iterate all loops.
Solution is to use different index variables to iterate external and internal loops
var numbers = [9795526789839145, 2861747566959730, 4498854833783559, 6301982162016598, 1131197164065322];
var i = 0;
var j = 0;
for (j=0; j < numbers.length; j++) {
var current = numbers[j];
/...
}
JavaScript behaves like this because 'i' is not scoped to block (like in Java od C#). In ES2015 you can use let or const to bind variable to block scope (in this sample to for loop)
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);
It tells me this "TypeError: Cannot read property 'replace' of undefined
at eval:13:11" which makes no sense to me because its right above it.
The intetended body of the loop for(var i = 0; i <= howM; i++) is not enclosed in braces {..}. As a result, only the statement var sum = 0; will be executed in the loop. Also, you probably meant to say i < howM. So you want something like this for the loop:
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);
Check the comments:
var howM = prompt("How many cards?")
var arr = [];
for(var i = 0; i < parseInt(howM); i++)
arr.push(prompt("Enter a card:")); //No curly braces is fine when its a single line. When there's no braces, JS just runs the next line x amount of times
console.log(arr)
var sum = 0; //Create sum out here. Setting it to zero every loop defeats the purpose
for(var i = 0; i < arr.length; i++)//You said "i <= howM". Better to use the length of the array that is being looped through
{ //Use curly braces to show what code to execute repeatedly
var eXt = arr[i]; //Set eXt to the current number
eXt = eXt.replace("-", ""); //No need for regex
sum += parseInt(eXt); //Convert the input to a number, then add it to sum
}
console.log(sum);
The second for loop doesn't have brackets around it. You can MUST use brackets UNLESS it is a one line loop. For example:
This is fine:
for (var i=0;i<100;i++)
console.log(i);
This is NOT:
for (var i=0;i<100;i++)
var x = i;
x++;
console.log(x);
So the second for loop should be this:
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);
}
Also in the first for loop I would use arr[i] = value instead.
(I'm brand new to JS so bear with me) I am using a table to build a sliding puzzle game. I need a function that will scramble the values, but I am not sure how I should get it to display in the table cells. Right now my code just displays the numbers in order.
I have two functions - one to build the table and the other to shuffle the values:
var _r = 3;
var _c = 3;
//initializes the puzzle
function newPuzzle(r, c)
{
var table = document.createElement("table");
table.id = "myTable";
for (var i = 0; i < r; i++)
{
var row = document.createElement('tr');
for (var j = 0; j < c; j++)
{
var column = document.createElement('td');
row.appendChild(column);
}
table.appendChild(row);
}
document.body.appendChild(table);
//end of table creation
//populate the table
var cell = new Array(r);
for (var i = 0; i < r; i++)
{
cell[i] = new Array(c);
for (var j = 0; j < c; j++)
{
cell[i][j] = i*c + j;
}
}
cell[0][0] = " ";
for (var i = 0; i < cell.length; ++i)
{
var entry = cell[i];
for (var j = 0; j < entry.length; ++j)
{
var n = 0;
var gridTable = document.getElementsByTagName("table");
gridTable[0].rows[i].cells[j].innerHTML = cell[i][j];
document.getElementById("myTable").rows[i].cells[j].id = "even" + (i*c+j);
}
}
shuffle();
}
function shuffle()
{
//declare and populate array
var _array = new Array();
for (var i = 0; i <= r*c; i++)
{
_array[i] = i;
}
//shuffle tiles
for (var i = 0; i <= r*c; i++)
{
var rand = Math.floor(Math.random() * _array.length) + i;
var temp = _array[rand];
_array[rand] = _array[i];
_array[i] = temp;
}
//check to see if puzzle is solveable
var count = 0;
for (var i = 0; i <= r*c; i++)
{
for (var j = i; j <= r*c; j++)
{
if (_array[j] < _array[i])
{
count++;
}
}
}
if (Math.floor(count/2) != count/2)
{
shuffle();
}
else
{
for (var i = 0; i < r*c; i++)
{
//This is where I'm not sure what to do
document.getElementsByTagName("td")[i].innerHTML = _array[i]+1;
}
}
}
Not sure, this may help you.
For solving any mathematics series below algorithm can be used. Even for some cases it will not satisfy your expected answer, but it will be correct in some other way.
Steps are as below:
Get difference between the numbers as shown below:
Keep making difference until it seems same(difference get 0).
Put the same last number which are coming same in that sequence and by adding that difference complete the series by coming up.
Examples are as below:
1 2 3 4 5 6 **7**
1 1 1 1 1 **1**
1 4 9 16 25 **36**
3 5 7 9 **11**
2 2 2 **2**
1 8 27 64 125 **216**
7 19 37 61 **91**
12 18 24 **30**
6 6 **6**
0 **0**
The same above algorithm is implemented in below js code.
//the input
var arr=[1,4,9,16];
var pa6inoArrayMelvo = function(arrr){
var nxtArr=[];
for(i=0;i<arrr.length;i++){
if(arrr[i+1] != undefined){
nxtArr.push(arrr[i+1] -arrr[i]);
}
}
return nxtArr;
}
var keepArray=[];
var keepAlltheArray= function(ar){
var tempArr=[];
keepArray.push(ar);
if(ar.length>1){
tempArr=pa6inoArrayMelvo(ar);
keepAlltheArray(tempArr);
}else{
generateArray(keepArray.length-1);
console.log("ans is:"+keepArray[0]);
}
}
var generateArray=function(idx){
if(keepArray[idx+1]){
var a=keepArray[idx+1];
var b=keepArray[idx];
var ans=a[a.length-1]+b[a.length-1];
keepArray[idx].push(ans);
}else{
var ans=keepArray[idx][keepArray[idx].length-1];
keepArray[idx].push(ans);
}
if(idx>0){
generateArray(idx-1);
}
}
keepAlltheArray(arr);
You need to pass your variables r and c into your shuffle function:
function newPuzzle(r, c)
{
...
shuffle(r, c);
}
function shuffle(r, c) {
...
if (Math.floor(count/2) != count/2)
{
shuffle(r, c);
}
}
And also call newPuzzle(_r, _c); which I'm assuming you are.
With just that change it works, the only problem is that is NaN in this case, you can easily fix that by checking if the value is NaN then replacing that with a space:
if(isNaN(_array[i]))
document.getElementsByTagName("td")[i].innerHTML = " ";
Fiddle Example