I'm a really beginner and for now im preparing for JavaScript bootcamp. Unfortunately i stuck with one of pre-work excercises.
My task is to do muliplication table, put it into empty 2D Array and print it precisely in this form:
1 x 1 = 1 | 1 x 2 = 2 | 1 x 3 = 3
2 x 1 = 2 | 2 x 2 = 4 | 2 x 3 = 6
3 x 1 = 3 | 3 x 2 = 6 | 3 x 3 = 9
On start I have 2 var declared:
const n = 3;
const calc = [];
I know i have to start with 'for' loop - and i have no idea whats next;
for (let i = 1; i <= n; i++) {
}
EDIT:
Thanks for help, correct code below:
const n = 3;
const calc = [];
for(let i = 0; i < n; i++){
calc[i] = [];
for(let k = 0; k < n; k++){
calc[i][k] = (i + 1) + ' * ' + (k + 1) + ' = ' + (i + 1) * (k + 1);
}
}
for(let i = 0; i < calc.length; i++){
console.log(String(calc[i]).replaceAll(',', ' | '));
}
You need two 'for' loops to fill the array in 2D. After that you need another 'for' loop to print each row (for example in a paragraph tag).
Working example:
const n = 3;
const calc = [];
for(i = 0; i < n; i++){
calc[i] = []; //add the inner arrays (the second dimension)
for(k = 0; k < n; k++){
calc[i][k] = (k + 1) + ' x ' + (i + 1) + ' = ' + (k + 1) * (i + 1);
}
}
for(i = 0; i < calc.length; i++){
const p = document.createElement("p");
//convert each inner array to a string
p.innerHTML = String(calc[i]).replaceAll(',', ' | ');
document.querySelector('#container').appendChild(p);
}
<div id="container"></div>
This is what I have come up with...
n = 3;
// create table array
table = [];
for(row=0; row<n;row++){
// generate an array for each row
table.push([])
for(col=0; col<n;col++){
// add the multiplication to each column in the row
// Notice that the column and row numbers start at zero in an array so 1 is added before multiplying
table[row].push((col+1) + ' x ' + (row+1) + ' = ' + (col+1)*(row+1));
}
}
// print the array to the console for fun
console.log(table);
// go through each row in table array, convert it to a string and replace ',' with ' | ' and printing it to the log
// Notice that in the replace argument you have to use /,/g instead of ',' in order to replace all commas and not just the first one
for(row=0; row<table.length;row++){
console.log(String(table[row]).replace(/,/g, ' | '))
}
I have added a bit of commenting. Hopefully you can see what is going on.
Here is the code I would write to solve your problem.
function generate(num, fn) {
var a = Array(num), b = 0;
while (b < num) a[b] = fn(b++);
return a;
}
const table = (num, fn, separator) => generate(num, fn).join(separator);
const entry = (a, b) => `${a} x ${b} = ${a * b}`;
const result = table(3, row => table(3, col => entry(row + 1, col + 1), ' | '), '\n');
console.log(result);
generate returns an array like [fn(0), fn(1), fn(2), ..., fn(num-1)]. There's more than one way to do this but what I provided here is pretty quick.
table calls generate, but with the elements joined together into a string with a separator between them.
entry formats the text of one entry in the table like: 2 x 3 = 6
The result is a table of tables (a two-dimensional table) with | delimiting the columns and \n delimiting the rows.
Note:
If you insist on having a complete 2D array, you could defer the joins until later like this, but it's slower:
function generate(num, fn) {
var array = Array(num), i = 0;
while (i < num) array[i] = fn(i++);
return array;
}
const entry = (a, b) => `${a} x ${b} = ${a * b}`;
const array2d = generate(3, row => generate(3, col => entry(row + 1, col + 1)));
const result = array2d.map(row => row.join(' | ')).join('\n');
console.log(result);
1 Loop for Rows and 1 Loop for Columns
OP wasn't specific about what said output of the multiplication table should be in -- HTML, text, ponies...?
A table can be generated by an outer loop and an inner loop:
The outer loop generates an array rows of a table.
[row 1, row 2, row 3]
The inner loop generates an array of cells (forming a column) for each row.
[col 1, col 2, col 3]
So a 2D array looks like one or more arrays within an array.
[ row 1[col 1, col 2, col 3], row 2[col 1, col 2, col 3], row 3[col 1, col 2, col 3] ]
The example below is a function that will pass a number (num) through and return a table with the same amount of rows and columns as the parameter passed (num). Each cell will contain the text of a simple formula:
row number * col number = X
Each col is delimited by a pipe |, and each row is delimited by a new line.
Details are commented in Snippet
// Pass a number [num]
function mTable(num) {
// Declare [row] array [rData]
const rData = [];
// for each [row] until [num] is reached...
for (let row = 1; row <= num; row++) {
//... declare [col] array [cData]...
const cData = [];
//... then for each [col] until [num] is reached...
for (let col = 1; col <= num; col++) {
//... generate the text✱ repesenting the product of the row and column numbers...
const cell = `${row} X ${col} = ${row*col}`;
//... next, push it to the [cData] array
cData.push(cell);
}
// Once the [cData] is created, convert it into a formatted line of text delimited by pipes '|'
const data = cData.join(' | ');
// Push the [cData] array into the [rData] array
rData.push(data);
}
// After the last [cData] array is pushed into the [tData] array, output [tData] as a formatted line of text delimited by new lines✱
return rData.join(`
`);
}
// Generate a 3x3 table
console.log(mTable(3));
// Generate a 8x8 table
console.log(mTable(8));
/*
✱The special syntax wrapped in grave ticks `...` is called template literals see References
*/
References
for Loop
.push()
.join()
Template Literals
Related
Good day,
I need to make a method that makes the multiplication table in console.log.
This method should receive a number to which it outputs the multiplication table.
The table should be appeared in the console (console.log). For example, if the number 5 came to the input, we get:
Important note:
In the last line between the numbers, exactly one space should be output.
In each column, the numbers should be aligned to the right.
I have searched everywhere, but I have not found a similar solution to this particular problem anywhere.
I don't quite understand how we can indent and add numbers on the sides. I only got it this way:
function multiplicationTable(value) {
let table = '';
for (let i = 1; i <= value; i++) {
let tableString = '';
for (let j = 1; j <= value; j++) {
tableString += ' ' + (i * j) + ' ';
}
tableString += '\n';
table += tableString;
}
return table;
}
console.log(multiplicationTable(5));
Try something like this :
function multiplicationTable(value) {
let table = '\n';
let maxLength = (value * value).toString().length;
for (let i = 0; i <= value; i++) {
let tableString = '';
for (let j = 0; j <= value; j++) {
let product = i * j;
let padding = ' '.repeat(maxLength - product.toString().length + 1);
tableString += padding + (product || ' ');
}
table += tableString + '\n';
}
console.log(table);
}
multiplicationTable(5);
Explanation :
let table = '\n'; creates an empty string with a newline character, which will be used to store the multiplication table.
let maxLength = (value * value).toString().length; finds the length of the largest number that will appear in the table, which is value * value. This length will be used to set the width of each column in the table.
for (let i = 0; i <= value; i++) creates a for loop that will iterate value + 1 times, where i is the row number. The 0 in i = 0 is because we want the first row to display the column headers (i.e. the numbers 0, 1, 2, ..., value).
let tableString = ''; creates an empty string that will be used to store each row of the table.
for (let j = 0; j <= value; j++) creates a nested for loop that will iterate value + 1 times, where j is the column number. The 0 in j = 0 is because we want the first column to display the row headers (i.e. the numbers 0, 1, 2, ..., value).
let product = i * j; calculates the product of the row and column numbers, which is the number that will appear in the table at that position.
let padding = ' '.repeat(maxLength - product.toString().length + 1); adds spaces to the left of the product so that each column has the same width. maxLength is the width of each column, and product.toString().length is the length of the product. The + 1 in maxLength - product.toString().length + 1 adds an extra space to the left of each product.
tableString += padding + (product || ' '); adds the padding and product (or an empty string, ' ', if i or j is 0) to the tableString. This creates the row of the table.
table += tableString + '\n'; adds the tableString and a newline character to the table. This creates a new row in the table.
How to extract elements of a matrix in a particular pattern using javascript?
following is the code for generating a 2d matrix of size any
var matrix = [];
for(var i=0; I<size; i++) {
matrix[i] = [];
for(var j=0; j<size; j++) {
matrix[i][j] = undefined;
}
}
so the first one is the original matrix. second one is the matrix made out by removing some elements/ cells.
// don't worry about splicing... this is just a demo.
[[3,5], [4,5], [4,2] ... ].forEach(([i,j], _, arr) => delete arr[i][j])
***** This is where you begin *****
(from the above splices matrix the following has to be done)
so what I want to achieve is that I want to separate or group cells from the above spliced matrix in the following manner. (like concentric circles/squares fashion by keeping in mind the fact that some cells are removed)
first you start at the central element [i,j], then move to the next level 3 x 3 & assign a value to all concentric cells (or separate cell address out)... then move to the next level 4 x 4 assign a value to all concentric cells (or separate cell address out) and so on...
Note that the spliced matrix is the starting point
travel in this fashion outwards (like concentric squares):
the idea is that:\
generate a matrix of size n * n.
remove some elements (that will be any)
... from here the algorithm starts...
separate cells from the above splices matrix in a concentric square fashion. --> this is where I want help (step 3 only)
In simple terms I want to separate out the cells from the matrix in the following order (one level at a time 3 x 3 first then 4 x 4 then 5 x 5 and so on.... ( from the above spliced matrix, which means that some cells will be already removed.)
keep in mind the fact that some cells are already removed (so you'll have to skip them -)
First, figure out the centroid of the square. The center is going to be at {length / 2, width / 2}. We're dealing in integer units, so floor. Using the convention that the top left of the figure is {0, 0} , then ie a 7x7 square has its center at
{floor(7/2), floor(7/2)} === {3,3}
Then, figure out a distance formula. In the pictures, the unit squares in purple are all the squares where either the x coordinate or y coordinate are N units away from the center. In other words
max(x - centerX, y-centerY) === N
I agree with #audzzy, you don't want to delete anything since that actually changes the length of an individual row, which we don't want. Instead just set it to another value.
So the idea is to:
find the center
iterate over each unit square
clear any unit squares which are N distance from the center
const clearCircle = (mat, N) => {
// find the center
const maxI = mat.length, maxJ = mat[0].length,
center = {
i: Math.floor(mat.length / 2),
j: Math.floor(mat[0].length / 2)
};
// iterate over all units
for (let i = 0; i < maxI; i++) {
for (let j = 0; j < maxJ; j++) {
// check if its N units from the center
if (Math.max(Math.abs(center.i - i), Math.abs(center.j - j)) === N) {
mat[i][j] = " ";
}
}
}
return mat;
}
Full example:
/*jshint esnext: true */
const generateMat = size => {
const mat = [];
for (let i = 0; i < size; i++) {
mat[i] = [];
for (let j = 0; j < size; j++) {
mat[i][j] = "[ ]";
}
}
return mat;
}
const mat = generateMat(9);
const logMat = mat => console.log("\n" + mat.map(row => (row).join(" ")).join("\n") + "\n");
const clearCircle = (mat, N) => {
// find the center
const maxI = mat.length, maxJ = mat[0].length,
center = {
i: Math.floor(mat.length / 2),
j: Math.floor(mat[0].length / 2)
};
// iterate over all units
for (let i = 0; i < maxI; i++) {
for (let j = 0; j < maxJ; j++) {
// check if its N units from the center
if (Math.max(Math.abs(center.i - i), Math.abs(center.j - j)) === N) {
mat[i][j] = " ";
}
}
}
return mat;
}
logMat(mat);
logMat(clearCircle(mat, 1));
logMat(clearCircle(mat, 2));
logMat(clearCircle(mat, 3));
Well... you just need exclude squares outside boundaries, after that you can just select elements which are in the most external layer of the matrix!
Something like that:
function extractElements(layer, matrix) {
const elements = []
const n = matrix.length; // matrix NxN
const frontIndex = layer -1;
const backIndex = n - layer;
if(layer <= 0 || layer > Math.ceil(n/2)) {
console.log("invalid layer");
return [];
}
for(let i = 0; i < n; ++i){
if(i < frontIndex || i > backIndex)
continue;
for(let j = 0; j < n; ++j){
if(j < frontIndex || j > backIndex)
continue;
if(i === frontIndex || i === backIndex || j === frontIndex || j === backIndex) {
if(matrix[i][j] !== undefined)
elements.push(matrix[i][j]);
}
}
}
return elements;
}
So, if you want the most external layer of a matrix 5x5, you can call extractElements(1, matrix)
Good code!
here's some basic code to do what you want (here I colored the cells, you could add them to a result array, or do whateve else you want)
notice it has very little iterations- only goes over the "wanted" cells every time- and colors the relevant lines and columns,
(for visual reasons -
'-' is a regular cell,
' ' is deleted cell,
'a' is a "purple" cell)
setMatrix is basically the interesting part that gets the interesting cells of every level..
let setMatrix = (matrix, level, value) => {
let size = matrix.length;
for(let x=Math.floor(size/2)-level;x<=Math.floor(size/2)+level;x++){
matrix[x][Math.floor(size/2)-level] = matrix[x][Math.floor(size/2)-level] == ' ' ? ' ' : value;
matrix[x][Math.floor(size/2)+level] = matrix[x][Math.floor(size/2)+level] == ' ' ? ' ' : value;
if(x!=Math.floor(size/2)-level && x!=Math.floor(size/2)+level){
matrix[Math.floor(size/2)-level][x] = matrix[Math.floor(size/2)-level][x] == ' ' ? ' ' : value;
matrix[Math.floor(size/2)+level][x] = matrix[Math.floor(size/2)+level][x] == ' ' ? ' ' : value;
}
}
}
and here's some code to call it for each level:
function doWork(){
// init
let size = 7;
var matrix = [];
for(var i=0; i<size; i++) {
matrix[i] = [];
for(var j=0; j<size; j++) {
matrix[i][j] = '-';
}
}
// delete
[[1,1], [2,3], [2,5], [5,1], [6,4]].forEach(([i,j])=> matrix[i][j] = ' ');
// go over each level
for(let i=0;i<=Math.floor(size/2);i++){
// set
setMatrix(matrix, i, 'a');
// print
for(let x=0;x<size;x++){
let line='';
for(let y=0;y<size;y++){
line+=matrix[x][y];
}
console.log(line);
}
console.log();
//reset
setMatrix(matrix, i, '-');
}
}
doWork();
I use Quick Union algorithm to find if one of the first 5 sites are connected with one of the last 5 sites.
The first five sites have the same root, it's a penultimate array element. The last five sites have the same root as well. It's the last array element.
for (let i = 0; i < 5; i++) {
this.union(i,this.array.length-2);
}
for (let j = this.array.length-this.number-2; j < this.array.length-2; j++) {
this.union(j,this.array.length-1);
}
I need to paint a path like this
My code for highlighting the sites is:
let id = this.array[this.array.length-2]
for (let i = 0; i < this.array.length-2; i++) {
if(this.connected(i,id) && $("#result td").eq(i).hasClass('opened')){
$("#result td").eq(i).css({'background':'blue'});
}
}
It results:
But It's not right that 2 left sites are highlighted.
What Algorithm should i use to highlight only right path?
Connected method:
connected(p, q){
return this.root(p) === this.root(q);
}
Root method
root(index){
while(this.array[index] !== index) index = this.array[index];
return index;
}
Looks like you just want a basic Fill algorithm, but with 2 caveats. 1) You only want it to fill downwards as if water was flowing 2) you want the Fill() to be called on every empty space in the first (top) row, as if water was being poured accross the top.
var EMPTY = 0; // empty unfilled spot
var SOLID = 1; // solid spot
var FILLED = 2; // filled spot
var ROWS = 5; // # of rows of data indexed 0 to 4
var COLS = 5; // # of columns of data indexed 0 to 4
var data = [
[1,0,0,1,1],
[1,1,0,1,1],
[0,1,0,0,1],
[0,1,1,0,1],
[0,1,1,0,1]
]; // data that matches the example
// check if a location is EMPTY
function isEmpty(grid, rowIndex, colIndex) {
// valid row and col?
if(rowIndex < 0 || rowIndex >= ROWS || colIndex < 0 || colIndex >= COLS) {
return false;
}
// SOLID or FILLED already?
if(grid[rowIndex][colIndex] !== EMPTY) {
return false;
}
return true;
}
// replace EMPTY locations with FILLED locations
function fillDown(grid, startRow, startCol) {
if(false === isEmpty(grid, startRow, startCol)) {
return;
}
var nextLocation = [[startRow, startCol]]; // list of locations to process
while(nextLocation.length > 0) { // loop
var loc = nextLocation.pop();
var r = loc[0]; // row index
var c = loc[1]; // column index
// fill the empty location
grid[r][c] = FILLED;
// try to fill the locations to the LEFT, RIGHT and DOWN from the current location
if(isEmpty(grid, r, c - 1)) { // left
nextLocation.push([r, c - 1]);
}
if(isEmpty(grid, r, c + 1)) { // right
nextLocation.push([r, c + 1]);
}
if(isEmpty(grid, r + 1, c)) { // down
nextLocation.push([r + 1, c]);
}
}
}
// call fillDown() for the first row of the data (water pouring accross the top)
for(var c = 0; c < COLS; c++) {
fillDown(data, 0, c);
}
// show the result
alert(data.join('\n'));
Extra note, row and column indexes for a 2d array can be converted to a 1d array index by the formula: index = (r * COLS) + c, so the last location in the data row = 4, col = 4 would be 4 * 5 + 4 == 24, the index for the last location in a 1d array.
I am trying to create a script that allows the user to enter a certain amount of rows which will then print a large letter X, so far I am able to print it as a v shape but am struggling to get the rest of the x together.
rows = 0;
space = " ";
var user_input = parseFloat(prompt("Enter how many rows:", 0));
while (rows < user_input) {
space_counter = 0;
while (space_counter < rows) { //process1
document.write(space);
space_counter++;
}
document.write("x"); //process2
rows++;
midspace_counter = 0;
while (midspace_counter < user_input - rows) { //process3
document.write(space + space);
midspace_counter++;
}
document.write("x<br>"); //process4
rows++;
}
How i would do that:
let result = "";
const maxRow = +prompt("how many rows?");
// Knowing the half size of our x might be useful
const half = (maxRow - 1) / 2;
for(let row = 0; row < maxRow; row++){
// For e.g. maxRow = 7 this will be 3 2 1 0 1 2 3
const midspace = Math.abs(half - row);
const pad = maxRow - midspace - 1;// 1 = "x"
// \n means newline
result += " ".repeat(pad) + "x" + " ".repeat(midspace * 2) + "x\n";
}
Then you just need to append that to the document.
I'm trying to rearrange an input number using a function so that a single number is rearranged into descending order.
For example, 234892 would result in 984322.
This is what I have come up with.
function descendingOrder(n){
var num = '';
for(var i = 0; i <= n.length + 1; i++){ // iterates through the number
for(var j = 9; j >= 0; j--){ // starts at 9 and checks numbers descending
if (j == n[i]){
num.push(n[i]); // checks if j == n[i] and if so, pushes to num
}
i = 0; // sets i back to 0 to rescan the number again
}
}
return num;
}
You can convert number to string, split each character, sort it and join it again:
+(234892 + '').split('').sort((a, b) => a < b).join('');
var ordered = +(234892 + '').split('').sort((a, b) => a < b).join('');
document.getElementById('output').appendChild(document.createTextNode(ordered));
234892 → <span id="output"></span>
Detailed explanation:
var str = 234892 + ''; // convert to string
var parts = str.split(''); // convert to array of characters
// sort
parts.sort(function(a, b) {
return a < b;
});
var finalStr = parts.join(''); // join characters to string
var finalNumber = +finalStr; // convert back to number
console.log(finalNumber); // 984322