Creating a large letter X - javascript

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.

Related

Multiplication table in a console for entered number

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 Align Text in Browser Console Properly?

I have a task to take values from a prompt and put them like in the picture, but I don’t really understand how to make everything on the same level, for example, so that the '|' was always under the plus, not paying attention to the length of the word.
My result:
var arr = []
for (var i = 0; i >= 0; i++) {
var input = prompt('Enter any value (enter end to complete the operation) ');
if (input === 'end') break;
arr[i] = input;
}
console.log(arr)
for (var i = 0; i < arr.length; i++) {
console.log(`+-----------------+---------------------+ \n| ${arr[i]} |`)
}
You can do something like this, but fonts have variable widths so I don't expect this to work 100%.
var maxLength = 21;
var arr = []
for (var i = 0; i >= 0; i++) {
var input = prompt('Enter any value (enter end to complete the operation) ');
if (input === 'end') break;
arr[i] = input;
}
console.log(arr)
for (var i = 0; i < arr.length; i++) {
console.log(`+${'-'.repeat(maxLength-1)}+${'-'.repeat(maxLength-1)}+ \n|${' '.repeat((maxLength-arr[i].length)/2)}${arr[i]}${' '.repeat((maxLength-arr[i].length)/2)}|`)
}
For example number 2 is wider than 1 so this happens:
An alternative that lets you adjust your spacing and width of your 'columns'. Choose a font that has equal width for all characters for this to work.
const arr = ['ab', 'abc', 'abcdef', 'a']
// Figure out the max length of your string array
let max = 0
arr.forEach(s => {
if (max < s.length) max = s.length
})
// Set your column with -
const spacing = 3
const dashes = '-'.repeat(max + spacing * 2);
const firstLine = `+${dashes}+`
console.log(firstLine)
for (let i = 0; i < arr.length; i++) {
const padLeft = Math.floor((max - arr[i].length) / 2)
const padRight = max - arr[i].length - padLeft
console.log('|' + ' '.repeat(spacing + padLeft) + arr[i] + ' '.repeat(spacing + padRight) + '|')
}
console.log(firstLine)
The following solution will add 5 or more spaces to each side of each string and add an extra space to even length strings in order to insure evenly spaced vertical borders. As long as the font is a monospace typeface (which is the console default) the content will be displayed perfectly aligned.
Note, in the second image in the OP (Original Post) each string is in it's own "cell" within it's own "row", whilst the first image in the OP shows 2 strings within it's own "cell" on each "row". My answer coincides with the former since the code in OP does as well.
Determine total number of characters of the longest string in array and divide it by 2.
// Define >max< outside of loop
let max = 0;
// Compare and redefine >max< within loop
if (max < (input.length / 2)) max = input.length / 2
Define border outside of loop which should accommodate the longest string in the array plus 5 spaces on both of it's sides.
const border = `+${"-".repeat(max + 5)}+${"-".repeat(max + 5)}+ \n`;
Define space within loop so the value changes according to current string to be displayed.
let space = (max - (arr[i].length / 2)) + 5;
Define offset for even length strings
/* If the remainder of the string length divided by 2 is 0, then >offset< is 1
else it's 0 */
let offset = arr[i].length % 2 === 0 ? 1 : 0;
Finally, interpolate each string within the loop.
`${border}|${" ".repeat(space)}${arr[i]}${" ".repeat(space + offset)}|`
Example
let arr = [];
let max = 0;
for (let i = 0; i >= 0; i++) {
let input = prompt('Enter any value (enter "end" to complete the operation) ');
if (input === 'end') break;
arr[i] = input;
if (max < input.length / 2) max = input.length / 2;
}
console.log(arr)
const border = `+${"-".repeat(max + 5)}+${"-".repeat(max + 5)}+ \n`;
for (let i = 0; i < arr.length; i++) {
let space = (max - (arr[i].length / 2)) + 5;
let offset = arr[i].length % 2 === 0 ? 1 : 0;
console.log(`${border}|${" ".repeat(space)}${arr[i]}${" ".repeat(space + offset)}|`);
}
console.log(border);

Storing concatenated numbers as string in a 2D array. Result remains "undefined"

I am a novice programmer. I am creating a 2D battleship game. I have successfully randomised the spawn points of said ships and I have an idea on how to proceed next.
I am using a 2D ship array to store the ships coordinates and the last address in each row would be its status: 0=floats, 1=single hit, 2=two hits and so on. But I ran into a problem and need help. I seem to be unable to store anything to said array. as you can see in my code board[][] works but ship[][] doesn't.
I am having an error in this segment:
var z = 1; //set to 1 for debugging purposes. z is supposed to be the length of each battleship.
ship[c][z] = 1; // for debug only. line to be removed during final iteration
console.log("c z = " + c + " " + z);
console.log("ship c z = " + ship[c][z]);
if(c == 0)
{
for(z = 0; z < 4; z++)// this for loop is for battlehsip. more for loops to be added one for each ship type.
{
console.log("a b = " + a + " " + b);
ship[c][z] = ("" + a + b);
console.log("sketchy array " + ship[c][z]);
a++;
console.log("Z = " + z);
}
}
and this is the console output(trimmed):
Loop start
i = 0
rn = 7
rn = 0
x y =7 0
board x y = 1
Board 7 0
C = 0
rng = 0
VH = 0
c z = 0 1
ship c z = undefined
a b = 7 0
sketchy array undefined
Z = 0
a b = 8 0
sketchy array undefined
Z = 1
a b = 9 0
sketchy array undefined
Z = 2
a b = 10 0
sketchy array undefined
Z = 3
This is my full code. Maybe this will clear out what I am trying to achieve. feel free to correct my existing logic.
var vhposition = 0;
var x = 0;
var y = 0;
var guess;
var guesses
var fsunk;
var userchoices = [];
var board = [];
var ship = []; //ship array. converted to 2D array to hold ship status and X
Y coordinates.
function createboard()
{
for (var i = 0; i < 10; i++)
{
board[i] = [];
}
return board;
}
function fleet()
{
for(var i = 0; i < 10; i ++)
ship[i] = [];
}
function rng() //Generates Random Numbers
{
var rn = Math.floor(Math.random() * 10);
console.log("rn = " + rn);
return rn;
}
function rngesus()
{
var rng = Math.floor(Math.random() * 2);
console.log("rng = " + rng);
return rng;
}
function play() // onclick function
{
console.log("game start");
bhit = 0; //battleship hit counter set to zero
c1hit = 0; //cruiser hit counter set to zero
//console.log("sunk array = " + sunk[0] + " " + sunk[1]);
fsunk = 0; //fleet status
createboard();
fleet();
var i = 0;
while(i < 10) // generates random points for ship spawn
{
ship[i] = 0; //overkill to ensure no residual data
console.log("Loop start"); //makes reading console easier
console.log("i = " + i);
spawn(i); //i acts as the ship id that is being worked on
i++;
}
//game();
}
function spawn(j) // ship positon generated, i think
{
x = rng();
y = rng();
console.log("x y =" + x +" "+ y);
board[x][y] = 1;
console.log(" board x y = " + board[x][y]);
position(x, y, j);
}
function position(a,b,c)
{
console.log("Board " + a + " " + b);
console.log("C = " + c);
vhposition = rngesus(); //returns 0 or 1 for ship orienetation. maybe later will add 4 way
console.log("VH = " + vhposition);
var z = 1; //set to 1 for debugging purposes. z is supposed to be the length of each battleship.
ship[c][z] = 1; // for debug only. line to be removed during final iteration
console.log("c z = " + c + " " + z);
console.log("ship c z = " + ship[c][z]);
if(c == 0)
{
for(z = 0; z < 4; z++)// this for loop is for battleship. more for loops to be added one for each ship type.
{
console.log("a b = " + a + " " + b);
ship[c][z] = ("" + a + b);
console.log("sketchy array " + ship[c][z]);
a++;
console.log("Z = " + z);
}
}
}
//function game()
{
//to be continued...
}
function userinput()// this works fine
{
guess = prompt("Enter the grid coordinates. Do not use space. X-coordinates 0-6, Y-coordinates 0-6.");
console.log("users input = " + guess);
while(guess < 0 || guess > 99 || userchoices.includes(guess)) //checks user input for repeated strikes or out of range. Suggest better way if possible. this is just bad code
{
alert("You have entered an invalid coordinate.");
guess = prompt("Try Again!");
}
guesses++; //increments no of guessess
userchoices.push(guess); //add users guess to array
return guess;
}
Sorry for the long question/post.
Thank you.
function position is called from spawn, spawn is called from play and in play you assign 0 to ship[i] ? So the ship is no longer a 2D array.

Javascript snake pattern grid

I am trying to draw a grid on screen numbered in a snake pattern in Javascript, I have a working grid but it follows the pattern of
12345
67890
And what I need is
12345
09876
I have seen this done with modulo and have tried to implement but im having trouble getting the right number sequence.
Here is my function
function createGrid(length, height) {
var ledNum = 0;
for (var rows = 0; rows < height; rows++) {
for (var columns = 0; columns < length; columns++) {
var backwards = ledNum + columns;
if (rows % 2 == 0 || rows != 0) {
$("#container").append("<div class='grid' id='" + ledNum + "'>" + //HERE IS MY PROBLEM+"</div>");
}
else if (!rows % 2 == 0) {
$("#container").append("<div class='grid' id='" + ledNum + "'>" + ledNum + "</div>");
}
ledNum++;
};
};
$(".grid").width(960 / length);
$(".grid").height(960 / height);
};
How do I work out the true modulo case to show the numbers correctly in snake pattern?
I am not well versed with 2d arrays but perhaps that might be a better way?
The best way I can think of is to use an object with arrays and exploit its inbuilt functions to ease your job...for example
function createGrid(length,height) {
var lednum = 0;
var grid = [];
for (var row = 0; row < height; row++) {
grid[row] = [];
for (var col = 0; col < length; col++) {
if ((row % 2) === 0) {
grid[row].push(lednum);
} else {
grid[row].unshift(lednum);
}
lednum++;
}
}
return grid;
}
console.log(createGrid(10, 10))
Then you can just print out above grid
Update : How to print above data. You could simply use two for loops.
var length = 10;
var height = 15;
var brNode = document.createElement('br');
var grid = createGrid(length, height));
for (var row = 0; row < height; row++) {
var rowPrint = "";
for (var col = 0; col < length; col++) {
rowPrint += String(grid[row][col]) + " ";
}
var rowNode = document.createTextNode(rowPrint)
$("#container").appendChild(rowNode);
$("#container").appendChild(brNode);
}
Note that this will create rows of textNode broken by <br/> tags. if you want it formatted in some other way..well you have the preformatted data..all you need to do is traverse through it and print it how you want.
This general idea seems to work...
// Input variables
var data = 'abcdefghijklmnopqrstuvwxyz';
var width = 5;
// The actual algorithm.
var rows = Math.ceil(data.length / width);
for (var y = 0; y < rows; y++) {
var rowText = "";
for (var x = 0; x < width; x++) {
// Basically, for every other row (y % 2 == 1),
// we count backwards within the row, as it were, while still
// outputting forward.
var offset = y * width + (y % 2 == 1 ? width - 1 - x : x);
rowText += data[offset] || " ";
}
console.log(rowText);
}
$ node so51356871.js
abcde
jihgf
klmno
tsrqp
uvwxy
z
As I mentioned in comments, there is a lot wrong with the boolean logic in your code:
The first if condition always evaluates to true, except in the first iteration
The second if condition is therefor only evaluated once, and it will be false.
I would split the functionality in two parts:
Create a 2D array with the numbers in "snake" sequence
Create the DOM elements from such a matrix, using some CSS to control the line breaks
function createSnake(width, height) {
const numbers = [...Array(width*height).keys()];
return Array.from({length:height}, (_, row) =>
numbers.splice(0, width)[row % 2 ? "reverse" : "slice"]()); // 2D array
}
function createGrid(matrix) {
$("#grid").empty().append(
[].concat(...matrix.map(row => row.map((val,i) =>
$("<div>").addClass("grid").toggleClass("newline", !i).text(val))))
);
}
// Demo generating a 3 x 3 grid
createGrid(createSnake(3,3));
.grid {
float: left;
padding: 3px;
}
.newline {
clear:left
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="grid"></div>

Nested Loop to add numbers

I am currently trying to create a double nested loop that adds a number to itself, given the number of instances you want it to be added by.
So when you input something in the Number, for example "5" and you input "3" for the number of instances, then the following would be printed:
5=5
5+5=10
5+5+5=15
More information on my JsFiddle
<div>
<h2>Loop</h2>
Number
<input type='text' id='tbox'>
<br>
Number of Instances
<input type='text' id='theNumber'>
<button onclick=doubleLoop;>
Add Numbers.
</button>
</div>
<div id="content">
</div>
<script>
function doubleLoop(){
var theText = document.getElementById('tbox').value;
var theNumber = document.getElementById('theNumber').value;
var content = document.getElementById('content');
content.innerHTML = '';
for (var i = 0; i < theNumber; i++) {
content.innerHTML = content.innerHTML + (i + 1) + ')';
//start of the second part of the Double Loop
for (var j = 0; j < (i + 1); j++){
if (i === 0){
content.innerHTML = content.innerHTML + theText + '=' + theText + '<br>';
} else if (i > 0) {
content.innerHTML = content.innerHTML + theText.repeat(j) + '=' + (theText * (i+1));
}
}
}
}
</script>
Here you go
https://jsfiddle.net/mkarajohn/qkn2ef4L/
function createString(number, times) {
/*
* We will create each side of the equation separately and we will concatenate them at the end
*/
var leftSide = '',
rightSide = '',
i;
for (i = 1; i <= times; i++) {
leftSide += number.toString();
if ((times > 1) && (i < times)) {
leftSide += '+';
}
}
rightSide = number * times
return (leftSide + '=' + rightSide);
}
function loop(){
// .value returns a string, so we make sure the values are converted to integers by calling parseInt()
// See https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/parseInt
var theText = parseInt(document.getElementById('tbox').value);
var theNumber = parseInt(document.getElementById('theNumber').value);
var content = document.getElementById('content');
var output = '';
content.innerHTML = '';
for (var i = 1; i <= theNumber; i++) {
output += createString(theText, i);
output += '<br />'
}
content.innerHTML = output;
}
var button = document.getElementById('run');
run.addEventListener('click', loop);
If there is something that is not clear feel free to ask.
EDIT: If you are hell bent on doing it with two nested loops, here's how it would go:
function loop(){
// .value returns a string, so we make sure the values are converted to integers by calling parseInt()
// See https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/parseInt
var theText = parseInt(document.getElementById('tbox').value);
var theNumber = parseInt(document.getElementById('theNumber').value);
var content = document.getElementById('content');
var output = '';
var leftSide = '',
rightSide = '';
content.innerHTML = '';
for (var i = 1; i <= theNumber; i++) {
leftSide = '';
for (var j = 1; j <= i; j++) {
leftSide += theText.toString();
if ((i > 1) && (j < i)) {
leftSide += '+';
}
}
rightSide = theText * i;
output += (leftSide + '=' + rightSide);
output += '<br />'
}
content.innerHTML = output;
}
var button = document.getElementById('run');
run.addEventListener('click', loop);
First things first: You're naming your variables very poorly, it's really difficult to understand what you're trying to do, specially when you don't say what you want directly in the question. doubleLoop says how your function works but not what it does. getMultiplicationProcess would have been a better name. Also, you could be passing the values as arguments and just returning the result, it would look A LOT better.
Anyway, I couldn't figure how you were trying to achieve this. I've renamed your variables and did everything my way. Never name a variable theNumber or theText because doing so says nothing about what information it holds. You could have named them firstInput and secondInput but even that way it would not be clear.
Here's the code, scroll down for explanation:
var submit = document.getElementById("submit"),
firstInput = document.getElementById("tbox"),
secondInput = document.getElementById("theNumber"),
answerField = document.getElementById("content");
submit.addEventListener("click", function () {
answerField.innerHTML = getMultiplicationProcess(Number(firstInput.value), Number(secondInput.value), "<br/>");
});
function getMultiplicationProcess(multiplicand, multiplier, lineBreak) {
var result = "";
for (var i = 0; i < multiplier; ++i) {
for (var j = 0; j < i + 1; ++j) {
if (i === j) {
result += multiplicand + " = " + (multiplicand * (i + 1));
} else result += multiplicand + " + ";
}
result += lineBreak || "\n";
}
return result;
}
JSFiddle
Explanation:
The outer for loop runs as many times as the second input, or multiplier. So if you input 5 and 3 respectively this loop will run three times. It represents each line of the resulting string.
The inner loop runs as many times as the current iteration number of the outer loop more one. So for our example inputs it will run like this:
0: 1; 1: 2; 2: 3;
I use it to place the multiplicand multiple times in the current line.
The first line will contain a single 5 (not including the answer for this multiplication) so j is i + 1 which is 1 because during the first iteration from the outer loop i equals 0:
5 = 5
The second line contains 2 5s and i is 1 because we're in the second iteration for the outer loop, so j = i + 1 = 2 which is how many fives we'll place in the string:
5 + 5 = 10
if it's the last iteration of the inner loop instead of adding "5 + " to the resulting string it places "5 = (i + 1) * multiplier" which will be the result for the current line. Then the inner loop ends, the outer loop adds a line break and restarts the process for the next line.

Categories