How could I achieve this below in JavaScript. I tried searching for it on MDN but couldn't find any method for it.
let a, b
let allNumbers = []
for (a = 10; a < 60; a = a + 10) {
for (b = 1; b <= 3; b++) {
allNumbers.push(a + b)
}
}
The desired outcome is an array inside the allNumbers array:
[[11,12,13], [21,22,23], [31,32,33], [41,42,43], [51,52,53]]
Just create a temporary Array in the outer loop and push the elements from the inner loop into it, after the inner Loop is finished, push the temporary array in the main one:
let a, b
let allNumbers = []
for (a = 10; a < 60; a += 10) {
let someNumbers = [];
for (b = 1; b <= 3; b++) {
someNumbers.push(a + b)
}
allNumbers.push(someNumbers)
}
console.log(JSON.stringify(allNumbers))
how about this
var a, b
var allNumbers = []
for (a = 10; a < 60; a = a + 10) {
var part = [];
for (b = 1; b <= 3; b++) {
part.push(a + b)
}
allNumbers.push(part)
}
You have to use one second array.
let a, b
let allNumbers = []
for (a = 10; a < 60; a = a + 10) {
second = [];
for (b = 1; b <= 3; b++) {
second.push(a + b);
}
allNumbers.push(second)
}
console.log(allNumbers);
You can apply a shorted version using ES6 features.
allNumbers = []
for (a = 10; a < 60; a = a + 10) {
allNumbers.push([...Array(3)].map((_, i) => i + a + 1))
}
console.log(allNumbers);
You can try:
const result = Array(5).fill(1).map((a, i) => Array(3).fill(1).map((a, j) => +`${i+1}${j+1}`));
console.log(JSON.stringify(result));
You have to create a new array an add the element to it in the second loop and the add this array to the final one after the second loop.
let a, b
let allNumbers = []
for (a = 10; a < 60; a = a + 10) {
data = []
for (b = 1; b <= 3; b++) {
data.push(a + b)
}
allNumbers.push(data)
}
console.log(allNumbers)
You need to declare a second array inside your loop. Like following:
let a, b
let allNumbers = []
for (a = 10; a < 60; a = a + 10) {
var tempArray = [];
for (b = 1; b <= 3; b++) {
tempArray.push(a + b)
}
allNumbers.push(tempArray);
}
console.log(allNumbers);
Just create an array and push the new array int allNumbers:
...
let c = []
for (b = 1; b <= 3; b++) {
c.push(a + b)
}
allNumbers.push(c)
...
Related
I'm new to JavaScript, I'm trying to solve leetcode question 37. I need to a create a blank two dimensional array, I initially used the method in the comments; however, it doesn't work correctly, it will change all the value. Then, I used the for loop method to create array and currently it worked correctly. But I still cannot figured out why this will happen, could anyone explain the reason why this will happen, is this because of shallow copy?
var solveSudoku = function (board) {
// let rows = new Array(9).fill(new Array(10).fill(0)),
let rows = new Array(9);
for (let i = 0; i < 9; i++) {
rows[i] = new Array(10).fill(0);
}
let cols = new Array(9);
for (let i = 0; i < 9; i++) {
cols[i] = new Array(10).fill(0);
}
let boxes = new Array(9);
for (let i = 0; i < 9; i++) {
boxes[i] = new Array(10).fill(0);
}
// let cols = new Array(9).fill(new Array(10).fill(0)),
// boxes = new Array(9).fill(new Array(10).fill(0));
for (let i = 0; i < 9; i++) {
for (let j = 0; j < 9; j++) {
let c = board[i][j];
if (c !== '.') {
let n = parseInt(c),
bx = Math.floor(j / 3),
by = Math.floor(i / 3);
// 0代表为使用,1为使用过
rows[i][n] = 1;
console.log(i, n)
cols[j][n] = 1;
// box索引
boxes[by * 3 + bx][n] = 1;
}
}
}
fill(board, 0, 0)
function fill(board, x, y) {
// 完成填充条件
if (y === 9) return true;
// 下一个点的坐标
let nx = (x + 1) % 9,
// 判断进入是否下一行
ny = (nx === 0) ? y + 1 : y;
// 如果已经填充,则进入下一个点
if (board[y][x] !== '.') return fill(board, nx, ny);
// 没有被填充过
for (let i = 1; i <= 9; i++) {
let bx = Math.floor(x / 3),
by = Math.floor(y / 3),
box_key = by * 3 + bx;
if (!rows[y][i] && !cols[x][i] && !boxes[box_key][i]) {
rows[y][i] = 1;
cols[x][i] = 1;
boxes[box_key][i] = 1;
board[y][x] = i.toString();
console.log(board[y][x])
// 递归向下一个点求解
if (fill(board, nx, ny)) return true;
// 恢复初始状态
board[y][x] = '.';
boxes[box_key][i] = 0;
rows[y][i] = 0;
cols[x][i] = 0;
}
}
return false;
}
console.log(board);
};
The problem with fill(), at least with object, is that it passes the same object, by reference, to all element of the array. So if you mutate this object, then it will mutate every object of every arrays.
Note that in your case, you are creating a new Array object using it's constructor ( new Array() ) which makes them objects.
const matrix = new Array(5).fill(new Array(5).fill(0));
console.log(matrix);
In the previous snippet, you can see that the values of the other rows, from the second one to the end, are reference to the initial row.
To get around that, you can fill you array with empty values and then use the map() to create unique object for each position in the array.
const matrix = new Array(5).fill().map(function() { return new Array(5).fill(0); });
console.log(matrix);
As you can see in the previous snippet, all the rows are now their unique reference.
This is the reason all of your values were changed.
I've applied this solution to your code. I wasn't able to test it, because I wasn't sure of the initial parameters to pass.
I've also used anonymous function here ( function() { return; } ), but I would success using arrow function ( () => {} ) instead, if you are comfortable with them. It's cleaner.
var solveSudoku = function (board) {
let rows = new Array(9).fill().map(function() { return new Array(10).fill(0); }),
cols = new Array(9).fill().map(function() { return new Array(10).fill(0); }),
boxes = new Array(9).fill().map(function() { return new Array(10).fill(0); });
for (let i = 0; i < 9; i++) {
for (let j = 0; j < 9; j++) {
let c = board[i][j];
if (c !== '.') {
let n = parseInt(c),
bx = Math.floor(j / 3),
by = Math.floor(i / 3);
// 0代表为使用,1为使用过
rows[i][n] = 1;
console.log(i, n)
cols[j][n] = 1;
// box索引
boxes[by * 3 + bx][n] = 1;
}
}
}
fill(board, 0, 0)
function fill(board, x, y) {
// 完成填充条件
if (y === 9) return true;
// 下一个点的坐标
let nx = (x + 1) % 9,
// 判断进入是否下一行
ny = (nx === 0) ? y + 1 : y;
// 如果已经填充,则进入下一个点
if (board[y][x] !== '.') return fill(board, nx, ny);
// 没有被填充过
for (let i = 1; i <= 9; i++) {
let bx = Math.floor(x / 3),
by = Math.floor(y / 3),
box_key = by * 3 + bx;
if (!rows[y][i] && !cols[x][i] && !boxes[box_key][i]) {
rows[y][i] = 1;
cols[x][i] = 1;
boxes[box_key][i] = 1;
board[y][x] = i.toString();
console.log(board[y][x])
// 递归向下一个点求解
if (fill(board, nx, ny)) return true;
// 恢复初始状态
board[y][x] = '.';
boxes[box_key][i] = 0;
rows[y][i] = 0;
cols[x][i] = 0;
}
}
return false;
}
console.log(board);
};
I am doing Integer right triangles. I have written a very simple brute force solution that runs through every combination.
I am pretty sure that there would be a better method for working out the answer but I can't think of any that reduce the computational complexity. Here's my current solution:
const main = () => {
let map = new Map();
for (let a = 1; a < 1001; a++) {
for (let b = a; b < 1001; b++) {
const c = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
const perimeter = (a + b + c);
if (perimeter > 1000) {
break;
}
if (c % 1 === 0) {
map.set(perimeter, (map.get(perimeter) ? map.get(perimeter) + 1 : 1));
}
}
}
// Sorting by the incremented value then returning the highest
return new Map([...map.entries()].sort((a, b) => b[1] - a[1]))
.entries()
.next()
.value[0];
};
console.log(main());
Thanks!
Some remarks about your code:
As the perimeter cannot be larger than 1000, and a < b < c, a should not have to iterate up to 1000, but only to 332. Similarly, b should not iterate further than 1000 - 2*a.
You can avoid taking the square root by increasing the previous value for c with 1, and adjusting the corresponding square. Similarly you can apply incremental logic to the squares of a and b, and the sum of squares.
Sorting is overkill. You only need to find the entry with the maximum count. So just iterate over the map to find that maximum
Before showing a faster method, the above will already speed up your code considerably. Your code would then look like this:
const main = () => {
let map = new Map();
for (let a = 1; a < 333; a++) {
let limit = 1000 - 2*a;
let aSquare = Math.pow(a, 2);
let aSquarePlusBSquare = 2*aSquare;
let c = Math.floor(a * 1.14142);
let cSquare = c*c;
let perimeter = 2*a+c;
for (let b = a+1; b < limit; b++) {
aSquarePlusBSquare += 2*b - 1;
perimeter++;
while (cSquare < aSquarePlusBSquare) {
c++;
perimeter++;
cSquare += 2*c - 1;
}
if (perimeter > 1000) {
break;
}
if (cSquare === aSquarePlusBSquare) {
map.set(perimeter, (map.get(perimeter) ? map.get(perimeter) + 1 : 1));
}
}
}
let max = 0;
for (let [i, k] of map) {
if (k <= max) continue;
max = k;
result = i;
}
return result;
};
console.log(main());
Now, you can also go for a different algorithm. I implemented one that uses the tree of primitive Pythagorian triplets. This performs 20 times better than your original code, and like 5 times better than the above implementation:
function main() {
let map = new Map;
function recur(a, b, c) {
let sum = a+b+c;
if (sum >= 1001) return;
// As this is a primitive case, also count the multiples:
for (let p = sum; p < 1001; p += sum) map.set(p, map.get(p)+1 || 1);
// Calculate the 3 "children" of this primitive Pythagorean triple,
// using Berggren's tree
let a2 = a<<1, a4 = a<<2, b2 = b<<1, b4 = b<<2;
let temp = a2 - b2 + (c<<1);
a = temp - a;
b += temp;
c += temp;
recur(a, b, c);
a += b4;
b += b2;
c += b4;
recur(a, b, c);
recur(a-a2, b-a4, c-a4);
}
recur(3, 4, 5);
let max = 0;
for (let [i, k] of map) {
if (k <= max) continue;
max = k;
result = i;
}
return result;
}
console.log(main());
So I have this task where I have to nest three loops together then find out all the three digit numbers where product == sum.
For example:
123
1*2*3 = 6
1+2+3 = 6
This is what I have tried so far:
var summen = a + b + c;
var produktet = a * b * c;
for (var i = 100; i <= 100; i++) {
for (var j = 100; j <= 101; j++) {
for (var e = 100; e < 1000; e++) {
if (summen == produktet) {
pOutput.innerHTML += e + " ";
}
}
}
Thank you in advance and any help is really appreciated!
(i thought that i need to use if and else but i'm basically stuck to be honest)
If you want to do it with three loops, use three that start at 0 and end at 9, and then add and multiply in the inner loop:
let output = [];
for (let a = 0; a < 10; a++) {
for (let b = 0; b < 10; b++) {
for (let c = 0; c < 10; c++) {
if (a * b * c === a + b + c) output.push("" + a + b + c)
}
}
}
console.log(output)
You could iterate from zero to 999 and take the stringed value as array. Then check the sum against the product and store the value if equal.
const
sum = array => array.reduce((a, b) => a + b),
product = array => array.reduce((a, b) => a * b);
var i,
temp,
values = [];
for (i = 0; i < 1000; i++) {
temp = Array.from(i.toString().padStart(3, '0'), Number);
if (sum(temp) === product(temp)) {
values.push(temp.join(''));
}
}
console.log(values);
I want to create a array like this:
[{'b':0,'c':1,'d':2},{'b':1,'c':2,'d':3},{'b':2,'c':3,'d':4}]
How can I do this in Javascript?
I have tried this:
for(i = 0; i < 3; i++){
var b = i;
var c = i+1;
var d = i+2;
};
dataResult={"b":b,"c":c,"d":d};
alert(dataResult) //not working result [{'b':0,'c':1,'d':2},{'b':1,'c':2,'d':3},{'b':2,'c':3,'d':4}]
You are just overriding value of 'b','c','d' and at the end assigning that value to 'dataResult', so you are not getting expected result.
Try this.
dataResult = [];
for(i = 0; i < 3; i++){
dataResult.push({ 'b': i, 'c': i+1, 'd': i+2 });
};
console.log(dataResult);
You'll have to create the object inside the loop, and then push it to the array:
const arr = [];
for (let i = 0; i < 3; i++) {
var b = i;
var c = i + 1;
var d = i + 2;
arr.push({ b, c, d });
}
console.log(arr);
But it would be a bit more elegant to use Array.from here:
const arr = Array.from({ length: 3 }, (_, i) => {
const b = i;
const c = i + 1;
const d = i + 2;
return { b, c, d };
});
console.log(arr);
Create the object inside the loop and push it to an array
var arr = [];
for (var i = 0; i < 3; i++) {
let obj = {
b: i,
c: i + 1,
d: i + 2,
}
arr.push(obj)
};
console.log(arr)
var myArr = [];
for(var i = 0; i < 3; i++){
var data = i;
myArr.push({
b: data,
c: data + 1,
d: data + 2
})
}
console.log(myArr)
You were creating the object outside the loop. You need to create object inside the loop.
Try following
var arr = [];
for(let i = 0; i < 3; i++){
var b = i;
var c = b+1; // as b = i, you can change c = b + 1
var d = c+1; // as c = i + 1, you can change d = c + 1
arr.push({b,c,d});
};
console.log(arr);
You are setting the value of b, c, d after it loops so it puts the latest value of b, c, d in dataResult. Instead, you should initialize dataResult with an empty array and push values to the array after every step of the loop
var a,b,c;
var dataResult = [];
for(i = 0; i < 3; i++){
b = i;
c = i+1;
d = i+2;
dataResult.push({"b":b, "c":c, "d":d});
};
alert(dataResult);
If I put this in to codeacademy labs, it returns the sum. But I can't figure out why it won't print/log/return the total when I tell it to.
var a = 0,
b = 1,
f = 1,
fibNums = [];
sum = 0;
while (f < 4000000) {
f = a + b;
if ( f > 4000000 ) {
break;
} else {
a = b;
b = f;
fibNums.push(f);
i ++;
}
}
for (i =0; i < fibNums.length; i++) {
if (fibNums % 2 === 0) {
sum += fibNums(i);
}
}
You have several errors in your code.
You need to access array elements using [] and not (). In your case sum is always 0 since you are accessing array in wrong way.
Here is the working code:
var a = 0,
b = 1,
f = 1,
fibNums = [];
sum = 0;
while (f < 4000000) {
f = a + b;
if (f > 4000000) {
break;
} else {
a = b;
b = f;
fibNums.push(f);
}
}
for (var i = 0; i < fibNums.length; i++) {
if (fibNums[i] % 2 == 0) { // access array elements using [] notation
sum += fibNums[i]; // access array using []
}
}
console.log(sum); // Log the sum
console.log(fibNums); //log the fibNums array