Eloquent Javascript: Chessboard - javascript

Write a program that creates a string that represents an 8×8 grid, using newline characters to separate lines. At each position of the grid there is either a space or a “#” character. The characters should form a chess board.
My code keeps creating an 8 x 8 structure with all hashes.
Can someone offer some advice to edit my code?
var size = 8;
var str = "";
var altern = false;
var line = 1;
while (line <= size) {
var character = 1;
while (character <= size) {
if (altern) {
if (character % 2 === 0) {
str += "#";
console.log(character);
console.log(str);
} else {
str += " ";
console.log(character);
console.log(str);
}
} else {
if (character % 2 === 0) {
str += " ";
console.log(character);
console.log(str);
} else {
str += "#";
console.log(character);
console.log(str);
}
}
altern = !altern;
character++;
}
str += "\n";
line++;
}
console.log(str);

By using both altern and character % 2 you select the branch with the # every iteration. Use only one of the two.

I couldn't figure out how to answer this myself until I found OP's code. Here is what I found would work:
var size = prompt("What is the size?");
var str = "";
var line = 0;
//Instead of using 1, use 0. It'll make sense in the next comment.
while (line < size) {
var character = 0; // Changed this to 0 as well.
while (character < size) {
if (line % 2 === 0){
/*Instead of using logic negate(altern = !altern), you could use one of the variables
you already have. Changing line = 1 to line = 0, we now can write the conditon above.
Where the first line holds true, because 0 % 2 === 0 is true.*/
if (character % 2 === 0) {
str += " "; // I switched the string values around, to get what is resembled in the book.
console.log(character);
console.log(str);
} else {
str += "#"; // Here
console.log(character);
console.log(str);
}
} else {
if (character % 2 === 0) {
str += "#"; // Here
console.log(character);
console.log(str);
} else {
str += " "; // Here
console.log(character);
console.log(str);
}
}
character++;
}
str += "\n";
line++;
}
alert(str);
//Changed this so the final result is easier to see, rather than in the jumbled mess of the console.

I suspect that you want to toggle altern with each new line, not with each square.
You have a loop inside a loop here. Move your altern toggle code from the inner loop to the outer loop.
while (line <= size) {
var character = 1;
while (character <= size) {
// inner loop code here
character++;
}
// Outer loop end code. HERE is where you toggle altern
str += "\n";
line++;
altern = !altern;
}

Below one works but I replaced spaces with Os (capital o's) and a little change in your code.
var size = 8;
var str = "";
var altern = false;
var line = 1;
while (line <= size) {
var character = 1;
while (character <= size) {
console.log('altern: ' + altern + 'character: ' + character);
if (altern) {
if (character % 2 === 0) {
str += "O";
console.log(character);
console.log(str);
} else {
str += "#";
console.log(character);
console.log(str);
}
} else {
if (character % 2 === 0) {
str += "O";
console.log(character);
console.log(str);
} else {
str += "#";
console.log(character);
console.log(str);
}
}
altern = !altern;
character++;
}
str += "\n";
line++;
}
// console.log(str);
alert(str);
This one works, but not, I suggest you to try to re-write this code in a better way. Hint: pay attention to what #koenpeters said.

Instead of using all those loops you could do this:
var width = 8,
height = 8,
str = new Array(1 + (width * height + height) / 2).join('# ').replace(new RegExp('(.{' + width + '}).', 'g'), '$1\n');
Works as long as width isn't even while at the same time height is odd.
If you just need it for this one specific case you could also get rid of a bit of the overhead and just use this:
var str = new Array(37).join('# ').replace(/(.{8})./g, '$1\n')

Instead of a while loop and over-repetition of your cases based on location (i.e. even vs odd) use two for loops and one case statement for whether a location needs a # vs " ". Store them to a var, then print the var once it is complete.
var board = "";
var countX = 0;
var countY = 0;
var size = 8;
for(var i = 0; i < size; i++) {
for(var j = 0; j < size; j++) {
if((countX + countY) % 2 == 0) {
board += " ";
}
else {
board += "#";
}
countX++;
}
board += "\n";
countY++;
}
console.log(board);
board output:
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #

i would have tackle this problem by first using a while loop to printing out a line of 8 harsh (########) symbol , then repeat it 8 times vertically using another loop, write a test condition that changes the value of y when the value of both iteration are even numbers.
const size = 8
for(let i = 0; i < size; i++){
let y = " "
let cols = 0;
if(i % 2 == 0){
y = "";
}else{
y = " ";
}
while(cols < size){
if( cols % 2 == 0){
y = y + "#"}
else{
y = y + " "
}
rows++
}
console.log(y)
}

Nested For Loop will work the best for this solution as below ---
//to get the input from the user for any size of the array
var charSize=prompt('Enter Number');
var boardChar = "";
//outer loop
for (let i = 1; i <= charSize; i++) {
//inner loop
for (let j = 1; j <= charSize; j++) {
//Check for even column
let evenCol = (i + j) % 2;
if (evenCol == 0) {
boardChar += " ";
} else {
boardChar += "#";
}
}
boardChar += "\n";
}
console.log(boardChar);
//OUTPUT
[Output Image][1]

The essential thing to realise is that given the N th row, its first square will be black if N is odd, and white otherwise.
Also, if the first square of a given row is black, then for a given column M, the square will be black if M is odd, and white if M is even.
Similarly, if the first square is white, then for a column M, the square will be white if M is odd, and black otherwise.
Hope that helps.
EDIT:
try this if you’re a fan of unreadable code:
for i in range(8):
s = ''
for j in range(8):
if (i - j%2) % 2 == 0:
s = s + "#"
else: s = s + 'O'
print s

I also learn JavaScript currently. I was stuck on that for one day. The only thing, that I realize, that if you want to do something useful in JavaScript use loops.
I don't have an idea about complicated coding, but loops could easily do things, that seems at first to be complicated.
Here is my version:
let b = "" //**just create an empty string, because if you won't do that, loop will print out symbols, numbers etc in a single column, but if you use empty string you can in future write symbols inside that string, which allows you to expand string horisontally
let size = 8 //**since loops start at 0 to infinity, you must take it into account,
for (let i = 0; i < size; i++) //**create first loop --> (; ; ). As you can see inside body of loop (the expression, that will be executed until loop is valid) I have just b = b + "#", which means, that my first "for" loop will do looping :) 8 times and will store inside "b" variable THE LAST VALUE (it will be ########), you can check this out in a single sheet (and you will see, that this looping is still going vertically, but the point is that it stores the LAST VALUE)
{ b = b + "#"} //**that is the body of first loop which is described clearly above
for (let a = 0; a < size; a++) //**inside second loop, we create the same routine, and proceed inside that loop with value of "b" from first loop. Notice, that first loop is enclosed {}, so it act independantly.
{
if (a % 2 == 0) //**just condition, which allows us to distribute different strings (rows) of code (I hope you understand what is inside parenthesis
{console.log (" " + b)} //**Since we want to see our chessboard we should print this out onto screen, for that we use "console.log" but again, notice, that here WE DON'T change value of variable "b", we just operate with it, but it will stay the same "########"
else{
console.log (b)} //** And if "if" fails, we will proceed with "########" value, which is NEW origin of "b" variable
}

Related

Print Triangle using javascript function

function makeLine(length) {
var line = "";
for (var i = 1; i <= length; i++) {
for (var j = 1; j <= i; j++) {
line += "*";
}
}
return line + "\n";
}
console.log(makeLine(2));
I am trying to print triangle, i dont know where i am doing wrong, can some please explain the logic behind printing triangle using nested loops
*
**
***
After you finish printing a line, you need to add a newline "\n" so that you move to the next line. You could do this as below :
function makeLine(length) {
// length has the number of lines the triangle should have
var line = "";
for (var i = 1; i <= length; i++) {
// Enter the first for loop for the number of lines
for(var j=1; j<=i; j++){
// Enter the second loop to figure how many *'s to print based on the current line number in i. So the 1st line will have 1 *, the second line will have 2 *s and so on.
line += "*";
}
// Add a newline after finishing printing the line and move to the next line in the outer for loop
line+="\n";
}
// Print an additional newline "\n" if desired.
return line + "\n";
}
console.log(makeLine(2));
don't forget about .repeat()
function makeLine(length) {
var line = "";
for (var i = 1; i <= length; i++) {
line+="*".repeat(i)+"\n";
}
return line;
}
console.log(makeLine(3));
The \n was at an incorrect position.
function makeLine(length) {
var line = "";
for (var i = 1; i <= length; i++) {
for (var j = 1; j <= i; j++) {
line += "*";
}
line += "\n";
}
return line;
}
console.log(makeLine(5));
function hashTriangle(length)
{
let str="";
for(let i=0;i<length;i++)
{
str+="#";
console.log(str);
}
}
hashTriangle(7);
console.log() prints a new line. So it is not necessary for nested loops and confusing newline characters to be appended to our string.
function makeLine(length) {
var line = "";
for (var i = 1; i <= length; i++) {
for (var j = 1; j <= i; j++) {
line += "*";
}
// add new line after loop is completed
line = line + "\n"
}
return line + "\n";
}
console.log(makeLine(5));
you need to add \n to line when the inner loop is completed
const printTriangle=(symbol,gapSymbol,num) =>{
// const num =25;
let gap = 1;
const Sgap = symbol+' ';
for(i= num-1;i>=0;i--){
let prefixSuffix=''
prefixSuffix = gapSymbol.repeat(i);
let line = ''
if(i == num -1){
   line = gapSymbol.repeat(i)+symbol+gapSymbol.repeat(i);
}
if(i != num -1 && i !=0){
     line = gapSymbol.repeat(i)+symbol+gapSymbol.repeat(gap)+symbol+gapSymbol.repeat(i);
    gap = gap+2;
}
if(i<1){
    line = ''+Sgap.repeat(1)+Sgap.repeat(num-2)+Sgap.repeat(1);
}
console.log(line)
}
}
printTriangle('*','.',15)
This is a JavaScript function that generates a triangle shape using the console.log method. The function takes in three parameters:
symbol: the character to be used to draw the triangle
gapSymbol: the character to be used as a gap in between the symbols
num: the size of the triangle (the number of symbols on the base)
The function starts by initializing the variable gap with the value 1 and Sgap as a string of symbol followed by a space. It then uses a for loop to iterate num number of times, starting from num - 1 down to 0.
For each iteration of the loop, the function uses a single line variable to store the string to be logged. The prefixSuffix variable is used to store the repeated gapSymbols, which are used in each iteration of the loop.
The logic for each iteration is controlled by conditional statements, which determine the shape to be drawn based on the value of i. If i is equal to num - 1, the line is constructed using a single symbol surrounded by repeated gapSymbols. If i is not equal to num - 1 and i is not equal to 0, the line is constructed using repeated gapSymbols, a symbol, a gap of repeated gapSymbols, and another symbol, all surrounded by repeated gapSymbols. If i is less than 1, the line is constructed using repeated Sgaps.
Finally, the constructed line is logged using the console.log method.
Simple solution using padStart, padEnd, repeat method for printing right and left triangle
Left triangle
const printLeftTriangle = (n) => {
let output='';
for (let i = 1; i <= n; i++) {
output +="*".repeat(i).padStart(n) + "\n";
}
return output;
}
console.log(printLeftTriangle(5));
Right triangle
const printRightTriangle = (n) => {
let output='';
for (let i = 1; i <= n; i++) {
output +="*".repeat(i).padEnd(n) + "\n";
}
return output;
}
console.log(printRightTriangle(5));
try this solution please:
const halfTriangle = N => {
for (let row = 0; row < N; row++) {
let line = "";
for (let col = 0; col <= N; col++) {
if (col <= row) {
line += '#';
} else {
line += ' '
}
}
console.log(line);
}
}
halfTriangle(4)
// creates a line of * for a given length
function makeLine(length) {
let line = "";
for (var j = 1; j <= length; j++) {
line += "* ";
}
return line + "\n";
}
// your code goes here. Make sure you call makeLine() in your own code.
function buildTriangle(length) {
// Let's build a huge string equivalent to the triangle
var triangle = "";
//Let's start from the topmost line
let lineNumber = 1;
for (lineNumber = 1; lineNumber <= length; lineNumber++) {
// We will not print one line at a time.
// Rather, we will make a huge string that will comprise the whole triangle
triangle = triangle + makeLine(lineNumber);
}
return triangle;
}
// test your code
console.log(buildTriangle(10));
Center Tringle
let line='';
for(let i=1; i<=5;i++){
line += ' '.repeat(5-i)
line += '*'.repeat(i+i-1)+'\n'
}
console.log(line);

How to find and style matching pairs of parentheses within a string?

I am working on a project where I have strings with lots of brackets like ((A and B and (C or (D and E))) or F). I need to find a way to find the pairs and style or color them to show they are matching. For example, the brackets around "D and E" would be green, and the ones around "C or (D and E)" would be blue. For matching pairs I was using a stack but couldn't find a way to set colors, if theres a better way I'm open to try it. I'm working in asp.net and C#. Thanks!
Edit: here is the code that generates the string. terms is a list of values, innerConnector is either "and" or "or" based on user input, and child groups are groups within the larger group. (A and (B or C)) A would be a term, (B or C) would be a child group. I want to take the string this returns and apply the colors to the parentheses.
public string toString()
{
string str = "(";
if(terms.Count > 0)
{
for(int i = 0; i < terms.Count; i++)
{
if(i == 1)
{
str += terms[i];
}
else
{
str += " " + innerConnector + " " + terms[i];
}
}
}
if(children != null)
{
for(int i = 0; i < terms.Count; i++)
{
if(i == 1 && terms.Count == 0)
{
str += childGroups[i].toString();
}
else
{
str += " " + innerConnector + " " childGroups[i].toString();
}
}
}
str += ")";
}
I see you've removed javascript from your question tag. Disregard below then.
This was quite fun to have a play with actually. It's not the most elegant solution!
I've slightly commented the code because I'm such a lovely chap.
// List of colours we'll use.
var colors = ['red', 'blue', 'purple', 'orange', 'green'];
// Define the div and it's contents
var div = document.getElementById('colors')
var string = div.innerHTML;
// A function to return a span object with coloured text.
color_span = function(color, inner) {
return '<span style="color:' + color + '">' + inner + '</span>'
}
var color_count = 0;
var return_html = '';
// Cycle through each character in the string
for (i=0; i < string.length; i++) {
// If it's an open bracket, add a coloured span to the return_html and increment the colour counter
if ( string[i] == '(' ) {
return_html += color_span(colors[color_count], string[i]);
color_count++;
// If close bracket add coloured span and decrement the colour counter.
} else if ( string[i] == ')' ) {
color_count--;
return_html += color_span(colors[color_count], string[i]);
// If neither just add the character.
} else {
return_html += string[i];
}
}
// Change the div's html.
div.innerHTML = return_html
JSFiddle

Javascript: Broken letter shifting function [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
Trying to write a simple function to take a string as input, then shift each character over once alphabetically. (a -> b) (f -> g) (z -> a). My function so far is broken. I'm sure there are better ways to go about this, but if someone would be willing to troubleshoot my function that would be awesome. :)
function translate(str) {
var alphabet = ['a','b','c','d','e','f','g','h','i','j','k',
'l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
str.toLowerCase();
var i = 0;
var j;
//edit: deleted str = ""
while (i < str.length) {
for (j = 0; j < alphabet.length; j++) {
if (str[i] == alphabet[alphabet.length - 1]) { //changed data type
str += alphabet[0]
j=0;
} else if (str[i] == alphabet[j]) {
str += alphabet[j+1]; //fixed this
j=0;
} else {
i++;
}
}
}
return str;
You could also use charCodeAt and fromCharCode to realize your shifting. I might be a little bit more convienent:
function translate(str) {
res = [];
for (var i = 0; i < str.length; i++) {
var ch = str.charCodeAt(i);
//65 => A
//90 => Z
//97 => a
//122 => z
//if ch betweet A and Z or between a and z
if ((ch >= 65 && ch <= 90) || (ch >= 97 && ch <= 122)) {
//if z or Z transform to a or A respectively
if (ch === 90 || ch === 122) ch -= 25;
//else increase by one
else ch += 1;
}
res.push(ch);
}
return = String.fromCharCode.apply(this, res);
}
Both methods use unicode representation of the string. Essentially, you transform the single characters into numbers, increase those numbers by one and transform it back to a letter. Here is a unicode table that shows the value of each letter: http://www.utf8-chartable.de/unicode-utf8-table.pl?utf8=dec
Your logic is a little flawed. Just iterate through the string and use the indexOf method along with the modulo operator:
var index = alphabet.indexOf(char.toLowerCase());
if (index === -1) {
// char isn't in the alphabet, so you should skip it
} else {
var newChar = alphabet[(index + 1) % alphabet.length];
}
(index + 1) adds 1 to the index, which selects the next letter, and % alphabet.length makes it wrap around to the beginning in case of z.
Here's one way to do it:
function translate(str) {
var newStr = "";
var alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
for (var i = 0; i < str.length; i++) {
var currentLetter = str.substring(i, i+1);
var newLetter = alphabet[(alphabet.indexOf(currentLetter.toLowerCase()) + 1) % alphabet.length];
// preserve the case of the letter
newStr += (currentLetter === currentLetter.toUpperCase()) ? newLetter.toUpperCase() : newLetter;
}
return newStr;
}
The general idea is to loop through each character, find its position in the alphabet array, and add its successor to the new string.
You'll have to add more logic if you need it to handle strings containing symbols, numbers, etc.
I can see a few problems here.
var str = "";. str is the variable you are sending as a parameter, so you reset it with this statement.
if (str[i] == alphabet.length - 1). str[i] and alphabet.length - 1 are not the same data type, so this statement is probably not doing what you think it should. Maybe you should have alphabet[alphabet.length - 1] instead.
else if (str[i] == alphabet[j]) { str += alphabet[j]; //... }. This would add the same letter onto your result string if you didn't reset str like in #1. You should have something like alphabet[(j+1) % alphabet.size] instead.
Also, you should use charAt(i) for getting characters in a string, not subscripts ([]), and you don't have to call j=0 at the end of your for loops, since you already say j=0 in the loop.

How to multiply a variable?

<script type = "text/javascript">
//Add spaces between menu links
//Placement: Global Header
//Coded by Game
var spaces = "2"; //Edit number of spaces between menu links (1,2 or 3)
var a = document.getElementsByTagName("a");
for (i = 0; i < a.length; i++) {
if (a[i].parentNode.parentNode.className == "menubg" && a[i].innerHTML.match(/Home|new topics|help|search|members|calendar|admin|profile|logout|register|login/i)) {
if (spaces == "1") {
a[i].innerHTML += " ";
}
if (spaces == "2") {
a[i].innerHTML += " ";
}
if (spaces == "3") {
a[i].innerHTML += " ";
}
}
}
</script>
The code above is meant to let the useer add spaces between their menu items. It works fine. But how do I make it to where they can add as many spaces as they would like, instead of limiting them to 3? Maybe somehow they would add their number in the var 'spaces' and the code would multiply &nbsp by that numvber?
Just use a loop:
var spaces = 2;
[..]
for(var i = 0; i < spaces; ++ i)
a[i].innerHTML += "&nbsp";
I would generate the string in a separate method, like:
function getSpaces(count) {
var spaces = "";
for(var i = 0; i < count; i++) {
spaces += "&nbsp";
}
return spaces;
}
and then
a[i].innerHTML = getSpaces(2); //etc
This way you set innerHTML and access the array only one time, and also don't have repeated code.
Avoid innerHTML if you can, since it deletes and recreates the entire content of the element. Prefer appendChild and createTextNode instead. For instance:
a[i].appendChild(document.createTextNode(new Array(spaces + 1).join("\u00A0")));
Why don't you just create a loop inside your if clause that adds an every time you go through the loop?

Javascript While loop integers

I have to create a while loop displaying the integers from 1-20 but only 5 integers per line.
I can't get the 5 integers per line part. What is the best way to do that?
Check if it's the next item after a multiple of 5 and if the current item is not the first item. If it is, also print out a newline. For example:
for(var i = 1; i <= 20; i++) {
print(i); // Or however you're outputting it
if(i % 5 === 1 && i > 1) {
print('\n');
}
}
Here's a solution that builds a string and displays an alert box with the result.
var i = 0, result = "";
while (i++ < 20) {
result += i + " ";
// check to see if we're at 5/10/15/20 to add a new-line
if (i % 5 === 0) {
result += "\n";
}
}
alert(result);
jsFiddle to test: http://jsfiddle.net/willslab/KUVkX/3/
You can do...
if ( ! (i % 5)) {
// Create new line.
}
jsFiddle.
See no while loops in previous answers =)
function generateLine(start, nElements, separator) {
var i = start;
var range = [];
while (range.length < nElements) range.push(i++);
return range.join(separator) + '\n';
}
function generate(start, end, elementsInLine, inlineSeparator) {
var lines = [];
while (start < end) {
lines.push( generateLine(start, elementsInLine, inlineSeparator));
start += elementsInLine;
}
return lines.join('');
}
console.log( generate(1, 20, 5, ' ') );

Categories