Combine 10 cycles into one in Javascript - javascript

Here's my code with cycles and I want to make it shorter (in one cycle if possible).
function plan(piece) {
for (i = 0; i < 10; i++) {
piece.addStep('right');
}
for (i = 0; i < 9; i++) {
piece.addStep('down');
}
for (i = 0; i < 8; i++) {
piece.addStep('left');
}
for (i = 0; i < 7; i++) {
piece.addStep('up');
}
}
etc... to i < 1
I thought about it that case,
function plan(piece) {
for (i=10; i>1; i--){
piece.addStep('right');
piece.addStep('down');
piece.addStep('left');
piece.addStep('up');
}
but it's was wrong. Help pls!
here's look of task(maze)

You can add function for the repeating logic :
function addSteps(piece, n) {
while (n--) {
piece.addStep(piece);
}
}
addSteps('right', 10);
addSteps('down', 9);
addSteps('left', 8);
addSteps('up', 7);

Simply combine all of them by introducing some if Checks.
For Example :
function plan(piece) {
for (i = 0; i < 10; i++) {
piece.addStep('right');
if(i < 9)
piece.addStep('down');
if(i < 8)
piece.addStep('left');
if(i < 7)
piece.addStep('up');
}
}

One option is:
function plan(piece) {
['right', 'down', 'left', 'up'].forEach((dir, ind) => {
for (let i = 0; i < 10 - ind; i++) {
piece.addStep(dir);
}
});
}

Doubt it is efficient, but you can be Array fill, concat, and forEach
var steps = [].concat(Array(10).fill("right"), Array(9).fill("down"), Array(8).fill("left"), Array(7).fill("up"))
steps.forEach(dir => piece.addStep(dir));

You could take nested loops and increment the index for getting the right direction.
var sequence = ['right', 'down', 'left', 'up'],
i, j,
k = 0,
l = sequence.length;
for (i = 0; i < 10; i++) {
for (j = i; j < 10; j++) {
document.getElementById('out').innerHTML += sequence[k] + '\n';
// or piece.addStep(sequence[k]);
}
++k;
k %= l;
}
<pre id="out"></pre>

Related

using splice inside 2D Array in Javascript

I've created this 2D array, and I'm trying to delete the rows that are having 5 "ones" or more,
I tried it with splice (a.splice(j,1)) but it doesn't work . I think because when using this method it changes the whole quantity of rows and that's affects the for loops.
Is it because I don't use splice correctly or should I use different method ?
Thanks !
a = Array(7).fill(0).map(x => Array(10).fill(0))
for (let i = 0; i < 5; i++) {
a[1][i + 2] = 1;
a[4][i + 2] = 1;
a[5][i + 2] = 1;
}
console.log(a);
let count = 0;
for (let j = 0; j < 7; j++) {
for (let i = 0; i < 10; i++) {
if (a[j][i] == 1) {
count = count + 1;
}
}
if (count > 4) {
console.log("Line" + j);
// a.splice(j,1);
}
count = 0;
// a.splice(j,1);
}
Your splice is correct but you move forward through the array (j is incremented). To do this type of operation you need to move backward through the array (j is decremented) - this way the changing array indices don't intefere with your loop.
See the example below:
a = Array(7).fill(0).map(x => Array(10).fill(0))
for (let i=0; i<5; i++) {
a[1][i+2] = 1;
a[4][i+2] = 1;
a[5][i+2] = 1;
}
console.log("Original array");
console.log(a);
for (let j = a.length - 1; j > 0; j--) {
var count;
for (let i = 0; i < a[j].length; i++) {
if (a[j][i] === 1) {
count += 1
}
}
if (count > 4) {
a.splice(j, 1);
}
count = 0;
}
console.log("Filtered array");
console.log(a);

Matrix elements sum

I want to get the sum of the matrix elements, except for those over which the number 0, and get error:
Uncaught TypeError: Cannot set property '0' of undefined
function matrixElementsSum(matrix) {
let s = 0;
for (var i = 0; i < matrix.length; i++) {
for (var j = 0; j <= matrix.length; j++) {
if (matrix[i][j] == 0) {
matrix[i+1][j] = 0;
}
s += matrix[i][j]
}
}
return s
}
console.log(matrixElementsSum([[0, 1, 2, 0],
[0, 3, 2, 1],
[2, 0, 2, 3]]))
Your loop counter i should iterate over number of rows and j should iterate over number of columns. Also before setting matrix[i+i][j] to 0, you should also check if i+1 < matrix.length (number of rows)
function matrixElementsSum(matrix) {
let s = 0;
for (var i = 0; i < matrix.length; i++) {
for (var j = 0; j < matrix[0].length; j++) {
if (matrix[i][j] == 0 && i+1 < matrix.length) {
matrix[i+1][j] = 0;
}
s += matrix[i][j]
}
}
return s
}
Here is my solution to this problem. Hope it would help someone.
function matrixElementsSum(matrix) {
let susp = [];
return matrix.reduce((t, arr, i)=>{
return arr.reduce((tt, val, ii)=>{
if (val === 0) susp.push(ii);
if (susp.includes(ii)) {
return tt;
} else {
return tt+val;
}
}, 0) + t;
}, 0);
}
Here is my solution with Python:
def solution(matrix):
row_len = len(matrix)
col_len = len(matrix[0])
sum = 0
for c_index in range(col_len):
for r_index in range(row_len):
if matrix[r_index][c_index] == 0:
break
else:
sum += matrix[r_index][c_index]
return sum
function solution(matrix) {
let sum= 0;
for (let i = 0; i < matrix[0].length; i++) {
for (let j = 0; j < matrix.length; j++) {
if (matrix[j][i] === 0) break;
sum+= matrix[j][i];
}
}
return sum;
}
function solution(matrix) {
for(var r=0,j=0;j<matrix[0].length;j++){
for(var i=0;i<matrix.length;i++){
if(matrix[i][j]===0) break
else r+=matrix[i][j]
}
}
return r
}
It took me some time to solve this exercise. I see it was not very complicated.

Print prime numbers between 0 and 100

I'm trying to print all prime number between 0 and 100, but when executing this code the browser's tab just outputs nothing!!
for(var i = 2; i < 100; i++)
{
var prime = [];
for(var j = 0; j <= i; j++)
{
var p = i % j;
}
if(p != 0) prime.push(i);
else continue;
}
for(var k = 0; k < prime.length; k++)
{
document.writeln(prime[k], "<br>");
}
Try this one. I have also optimise the code (you only need to check upto sqrt(i) ).
var prime = [];
prime.push(2); //smallest prime
var flag = 0;
for(var i = 3; i < 100; i=i+2) //skip all even no
{
for(var j = 3; j*j <= i; j=j+2) //check by upto sqrt(i), skip all even no
{
if(i % j == 0) {
flag = 0;break; //not a prime, break
}
flag = 1;
}
if (flag == 1) prime.push(i); //prime, add to answer
}
for(var k = 0; k < prime.length; k++)
{
document.writeln(prime[k], "<br>");
}
Because you blank your list of primes EVERY loop cycle, move it outside the for loop
You need to make your variable prime outside of your loop
This is the code you have re-written
var prime = [];
for(var i = 2; i < 100; i++)
{
for(var j = 0; j <= i; j++)
{
var p = i % j;
}
if(p != 0) prime.push(i);
else continue;
}
for(var k = 0; k < prime.length; k++)
{
document.writeln(prime[k], "<br>");
}
I'm a fan of the sieve of Eratosthenes.
The following code should do what you wanted.
var prime = Array(101).fill(true);
for (var i = 2; i < 100; ++i){
if (prime[i]){
document.writeln(i, "<br>");
for (var j = i*i; j < 100; j += i){
prime[j] = false;
}
}
}
Or since it's only up to 100 you could just manually type the list (but, hey where's the learning if you do it that way?).
(1) Move prime outside the for loop, (2) start j at 2 and end when j < i, (3) check when p == 0 with a boolean flag and break inner loop.
var prime = []; //put prime out here so it does not reassign
for(var i = 2; i < 100; i++)
{
var isPrime = true;
for(var j = 2; j < i; j++) //start j at 2
{
var p = i % j;
if(p == 0)
{
isPrime = false;
break;
}
}
if(isPrime) prime.push(i);
}
for(var k = 0; k < prime.length; k++)
{
document.writeln(prime[k], "<br>");
}

Else statement won't work in for loop

I have a function here that is not working as I hoped it would. After a bit of testing, I discovered that it is not running the "else if" statement.
Here is the code:
getWeights : function() {
weights = [];
for (var i = 0; i < hiddenLayer.length; i++) {
weights[i] = {};
for (var j = 0; j < Object.keys(hiddenLayer[i]).length * 3; j++) {
if (i == 0) {
for (var t = 0; t < input.length; t++) {
weights[i]["weightsSet" + j] = 1;
}
}
else {
weightCalc = Object.keys(hiddenLayer[i - 1]).length;
for (var u = 0; u < Object.keys(hiddenLayer[i]).length * weightCalc; u++) {
weights[i]["weightsSet" + j] = 1;
}
}
}
}
},
Please help me find out why it won't work.
Any help is greatly appreciated.
EDIT
Removed comment
EDIT 2
I figured out the problem. Thanks for all the help :)
Try simplifying the function as follows and then debug to see what is happening:
getWeights : function() {
weights = [];
for (var i = 0; i < hiddenLayer.length; i++) {
weights[i] = {};
var limit = input.length;
if (i > 0) {
var weightCalc = Object.keys(hiddenLayer[i - 1]).length;
limit = Object.keys(hiddenLayer[i]).length * weightCalc;
}
for (var j = 0; j < Object.keys(hiddenLayer[i]).length * 3; j++) {
for (var t = 0; t < limit; t++) {
weights[i]["weightsSet" + j] = 1;
}
}
}
}
For any further help you would need to add data related to this code, and expected output in your question.
Check 2nd or 3rd for loop may be its running for infinitive number of times

remove value from two tables

I have two table is I remove the value in both tables if in a table of the value is marked by a flag to false
this.notInModel = function (tab1, tab2) {
for (var i = 0; i <= tab1.length - 1; i++) {
if (!tab1[i].inModel) {
for (var j = 0; j <= tab2.length - 1; j++) {
if(tab1[i].name === tab2[j].name)
tab2.splice(j, 1);
}
}
}
for (var i = 0; i <= tab2.length - 1; i++) {
if (!tab2[i].inModel) {
for (var j = 0; j <= tab1.length - 1; j++) {
if(tab2[i].name === tab1[j].name)
tab1.splice(j, 1);
}
}
}
}
I think my curls are a bit repetitive and wanted to know if we could not refactor the code ..?
thank you.
Try this:
this.notInModel = function (tab1, tab2) {
for (var i = tab1.length; i--; ) {
for (var j = tab2.length; j--; ) {
if(tab1[i].name !== tab2[j].name)
continue;
var tab2InModel = tab2[j].inModel;
if(!tab1[i].inModel)
tab2.splice(j, 1);
if(!tab2InModel)
tab1.splice(i, 1);
}
}
}
The trick is to loop through both tabs in reverse order and make the checks for the name and inModel properties for every element combination.
DEMO
You could make it more modular by creating a new function to iterate through the arrays like this:
this.notInModel = function (tab1, tab2) {
function nim(t1,t2) {
for (var i = 1; i <= t1.length - 1; i++) {
if (!t1[i].inModel) {
for (var j = 1; j <= t2.length - 1; j++) {
if(t1[i].name === t2[j].name)
t2.splice(j, 1);
}
}
}
}
nim(tab1,tab2);
nim(tab2,tab1);
}
The following code seems to be equivalent, though I could not test without the definition of splice or without knowing how inModel field is set.
this.notInModel = function (tab1, tab2) {
for (var i = 1; i <= tab1.length - 1; i++) {
for (var j = 1; j <= tab2.length - 1; j++) {
if(!tab1[i].inModel) {
if (tab1[i].name === tab2[j].name)
tab2.splice(j, 1);
}
if(!tab2[j].inModel) {
if (tab1[i].name === tab2[j].name)
tab1.splice(i, 1);
}
}
}
}

Categories

Resources