How can I make a symmetric histogram like this? - javascript

I'd like to write a JavaScript program that displays a symmetric histogram like this image:
The program should ask the user to enter the number of bars to print and the character to use to draw the bars. The count of characters in the bar needs to be displayed on the right-side of each bar.
The example showed is when I entered # as the character and 13 as the number.
Here's my code:
var symbol = prompt("Enter the symbol");
var number = prompt("Enter the number");
var currentNum = 1;
let text = "";
let symbolNum = symbol;
while (currentNum <= number) {
text += "<br>" + symbolNum + " " + currentNum;
symbolNum += symbol;
currentNum++;
}
document.write(text + "<br>");
And at last, I only can output the following:
I'd like to know what I can do in order to reverse the loop?

Try this
function SymmetricHistogram(){
const size = 10;
let numberX = 0;
let numberY = 0;
for(let i = size; i>=-size; i--) {
for(let j=size; j>=Math.abs(i); j--){
process.stdout.write("#");
}
numberX <=size ? console.log(numberX++) : console.log(--numberY);
}
}
SymmetricHistogram();
Or try the below
https://onecompiler.com/javascript/3x58bqr3h

Two different way for the same result. Not realy clean, but work.
var symbol = prompt("Enter the symbol");
var number = prompt("Enter the number");
var currentNum = 1;
let textTOP = "";
let textBOTTOM = "";
let symbolNum = symbol;
while (currentNum <= number) {
textTOP += "<br>" + symbolNum + " " + currentNum;
if (currentNum < number)
textBOTTOM = "<br>" + symbolNum + " " + currentNum + textBOTTOM;
symbolNum += symbol;
currentNum++;
}
document.write(textTOP + textBOTTOM + "<br>");
var symbol = '#';
var number = 13;
var currentNum = 1;
let text = "";
while (currentNum < number * 2) {
if (currentNum <= number) {
let num = currentNum;
text += "<br>" + symbol.repeat(num) + " " + num;
} else {
let num = Math.abs(number * 2 - currentNum);
text += "<br>" + symbol.repeat(num) + " " + num;
}
currentNum++;
}
document.write(text + "<br>");

Related

Function title var

I have written a code that finds two strings and in return it should tell me if these two strings are existing:
function searchTwoString(data, str1, str2) {
var strX = str1 + " " + strValueX + "\r\n";
var strY = str2 + " " + strValueY;
var strValueX;
var strValueY;
for (var i = 0; i < data.length; i++) {
if (data[i] === str1) {
var strValueX = " exist";
continue;
} else if (data[i] === str2) {
var strValueY = " exist";
break;
}
}
return strX + strY;
}
Achieved result:
str1 undefined
str2 undefined
Expected result:
str1 exist
str2 exist
it tells me my strvalueX & strvalueY are undefined isn't it i have already gave the values in the if statement?
thanks to those who will help out
Here is an answer to your question with comment.
Hope you understand what I'm talking about.
function searchTwoString(data, str1, str2) {
var strX;// = str1 + " " + strValueX + "\r\n";
var strY;// = str2 + " " + strValueY;
var strValueX;
var strValueY;
for (var i = 0; i < data.length; i++) {
if (data[i] === str1) {
// var strValueX = " exist";
// do not define again
strValueX = " exist";
continue;
} else if (data[i] === str2) {
// var strValueY = " exist";
// do not define again
strValueY = " exist";
break;
}
}
// define the value here after strValueX and strValueY is set
strX = str1 + " " + strValueX + "\r\n";
strY = str2 + " " + strValueY;
return strX + strY;
}
The order of your statements is off. In lines 2 and 3, you are using strValueX and strValueY before they are defined. Lines 2 and 3 should be moved to before the return so that they will have the updated values.
I believe there is also a shadowing problem, as in the if statements you are creating new variables with the var keyword (e.g. var strValueX = " exist";). You will want to remove var from the if statements so that it updates the values of the outer variables.

.innerHTML is showing up as undefined

ok so I understand this is a very basic JS logic but I am trying to replace any document.write() with .innerHTML and I tried it with the code below
function writeTimesTable(num) {
for(let i = 1; i < 10; i++ ) {
let writeString = i + " * " + num + " = ";
writeString = writeString + (i * num);
writeString = writeString + "<br />";
document.write(writeString);
}
}
function newTable() {
for(let i = 1; i <= 10; i++ ) {
let para = document.getElementById("paragraph");
para.innerHTML = writeTimesTable(i)
}
}
I have a div element with the ID of paragraph already. I keep getting undefined when I look at the div#paragraph and the rest of my code outputs under my script tag but not in the div element. What am I doing wrong?
Your function writeTimesTable() needs to return a value. Your writeString string, needs to be concatenated as well, you can do that with += like seen below:
function writeTimesTable(num) {
let writeString = "";
for(let i = 1; i < 10; i++ ) {
writeString += i + " * " + num + " = ";
writeString += writeString + (i * num);
writeString += writeString + "<br />";
}
return writeString
}
Using para.innerHTML = writeTimesTable(i) probably isn't intended, as it will just display the last loop, so you might also want to use += here as well:
para.innerHTML += writeTimesTable(i)
You normally want to avoid document.write because it literally writes out to the document.
I have also taken the liberty of doing the DOM creation off-page during the loop, and just add it to the actual DOM at the end. This means you aren't constantly re-drawing the page while you loop.
This is better than changing your innerHTML = to innerHTML +=, which you would need to do if you wanted to avoid overwriting each previous iteration of the loop.
function writeTimesTable(num) {
for(let i = 1; i < 10; i++ ) {
let writeString = i + " * " + num + " = ";
writeString = writeString + (i * num);
writeString = writeString + "<br />";
return writeString;
}
}
function newTable() {
const inner = document.createElement('div');
for(let i = 1; i <= 10; i++ ) {
const item = document.createElement('div');
item.innerHTML = writeTimesTable(i);
inner.appendChild(item);
}
let para = document.getElementById("paragraph");
para.appendChild(inner);
}
newTable();
<div id="paragraph"></div>
Your newTable() function with the 10 loops is useless. You're doing 10 times the same stuff over a single DOM element.
Don't use document.write...
I'd do it like:
function newTable( num ) {
var HTML = "";
for (var i=1; i <= num; i++) {
HTML += i +" * "+ num +" = "+ (i*num) +"<br>";
}
return HTML; // Return the concatenated HTML
}
document.getElementById("paragraph").innerHTML = newTable(10);
<p id="paragraph">asdasdasd</p>
Or in a super uselessly cryptic ES6 way:
const newTable = n =>
Array(n).fill().map((_,i) =>
`${i+=1} * ${n} = ${i*n}<br>`
).join('');
document.getElementById("paragraph").innerHTML = newTable(10);
<p id="paragraph">asdasdasd</p>

How can I save best guess (higher/lower)

for example my toGuess number is 50 and my best lower guess is 48 but I guess 47 and it changes my best lower guess to that 47.
What I mean by this is that I want it not go lower anymore
Same thing with the higher guess
I want it to save/lock my best guess to the closest
'use strict'
var toGuess = Math.floor(Math.random() * (100 + 1));
console.log("To Guess: " + toGuess);
var guess = undefined;
var amount = 0;
var bestHigher = 100;
var bestLower = 0;
var hint = document.getElementById('hint');
var numbers = document.getElementById('numbers');
var lower = document.getElementById('lower');
var higher = document.getElementById('higher');
function GuessDone() {
var put = document.getElementById('number').value;
guess = Number(put);
console.log("Guess: " + guess);
document.getElementById('form').reset();
amount = amount + 1;
console.log("Guesses " + amount);
var numberDif = Number(toGuess) - Number(put);
var bestLower = Number(put) > toGuess;
var bestHigher = Number(put) < toGuess;
if (numberDif > bestLower) {
bestLower = Number(put);
console.log("Lower " + bestLower);
}
if (numberDif < bestHigher) {
bestHigher = Number(put);
console.log("Higher " + bestHigher);
}
if (guess > toGuess) {
hint.innerHTML = "You need to guess lower";
higher.innerHTML = "Best guess above " + bestHigher;
} else if (guess < toGuess) {
hint.innerHTML = "You need to guess higher";
lower.innerHTML = "Best guess below " + bestLower;
} else {
hint.innerHTML = "Congratz, " + toGuess + " was right! Guesses " + amount;
var print = "";
var i;
for (i = 0; i <= toGuess; i++) {
print += i + "<br>";
}
numbers.innerHTML = print;
}
return false;
EDIT
This is my html
<form id="form">
<label for="number">Guess number between 0-100: </label>
<input id="number" type="text" name="number">
<button type="submit">Guess</button>
</form>
<p id="lower"></p>
<p id="higher"></p>
<p id="hint"></p>
<p id="numbers"></p>
<script src="numbergame.js"></script>
FIDDLE
https://jsfiddle.net/d3761nbj/2/

Reversing my encrypt method

I created minor encrypt method to convert a small string based on distance between characters, but can't for the life of me figure out how to reverse it without knowing the distance between each character from the initial conversion. See image for example how it works imgur.com/Ine4sBo.png
I've already made the encrypt method here (Javascript):
var all = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.#-?").split('');
var position;
//var oKey = "P";
function encrypt() // Encrypt Fixed
{
var sEncode = ("HI-MOM").split('');
var oKey = "P";
for (var i = 0; i < sEncode.length; i++) {
if (all.indexOf(oKey) < all.indexOf(sEncode[i])) {
position = all.indexOf(sEncode[i]) - all.indexOf(oKey);
output.value += "oKey: " + oKey + " distance to sEncode[" + i + "]: " + sEncode[i] + " Count: " + position + " Final Char: " + all[position-1] + "\n";
oKey = sEncode[i];
}
else {
position = all.length - all.indexOf(oKey) + all.indexOf(sEncode[i]);
output.value += "oKey: " + oKey + " distance to sEncode[" + i + "]: " + sEncode[i] + " Count: " + position + " Final Char: " + all[position-1] + "\n";
oKey = sEncode[i];
}
}
}
However, it's the decrypt() method that's killing me.
From what I can tell, your encrypt function can be reduced to this:
var all = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.#-?").split('');
function encrypt(str)
{
var sEncode = str.split('');
var result = '';
var oKey = "P";
for(var i = 0; i < sEncode.length; i++)
{
result += all[(all.indexOf(sEncode[i]) - all.indexOf(oKey) + all.length - 1) % all.length];
oKey = sEncode[i];
}
return result;
}
(I got rid of the if clause by adding all.length either way, and removing it again with the remainder operator if necessary.)
From there, all you need to do is flip the operands (- all.indexOf(oKey) - 1 becomes + all.indexOf(oKey) + 1 (and since we have no more subtractions, adding all.length is no longer necessary)) and reverse the order (so oKey gets assigned the transformed value instead of the original one):
var all = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.#-?").split('');
function decrypt(str)
{
var sEncode = str.split('');
var result = '';
var oKey = "P";
for(var i = 0; i < sEncode.length; i++)
{
oKey = all[(all.indexOf(sEncode[i]) + all.indexOf(oKey) + 1) % all.length];
result += oKey;
}
return result;
}

i cannot get my javascript number-sorter to work

i am making a number sorter that alerts the number of different numbers (e.g. 11223 would be returned as number of ones = 2, number of twos = 2, number of threes = 1 ect. ect.)
here is the code
<html>
<body>
<textarea width="100" height="50" id="text" onBlur="sort();"></textarea>
<script>
var text = document.getElementById("text").value;
var no1 = 0
var no2 = 0
var no3 = 0
var no4 = 0
var no5 = 0
var no6 = 0
var no7 = 0
var no8 = 0
var no9 = 0
var no0 = 0
var other = 0
var split = text.split("");
function sort() {
for (i = 1; i < split; i++) {
if (string[i]===1) {
no1++;
return no1;
}
else if (string[i]===2) {
no2++;
return no2;
}
else if (string[i]===3) {
no3++;
return no3;
}
else if (string[i]===4) {
no4++;
return no4;
}
else if (string[i]===5) {
no5++;
return no5;
}
else if (string[i]===6) {
no6++;
return no6;
}
else if (string[i]===7) {
no7++;
return no7;
}
else if (string[i]===8) {
no8++;
return no8;
}
else if (string[i]===9) {
no9++;
return no9;
}
else if (string[i]===0) {
no0++;
return no0;
}
else {
other++;
return other;
}
}
alert("number of ones = " + no1 + ", number of twos = " + no2 + ", number of threes = " + no3 + ", number of fours = " + no4 + ", number of fives = " + no5 + ", number of sixes = " + no6 + ", number of sevens = " + no7 + ", number of eights = " + no8 + ", number of nines = " + no9 + ", number of zeros = " + no0 + ", number of other characters = " + other + ".");
}
</script>
</body>
</html>
when i enter a value and click away from the text field it returns 0 for all the variables
please help
Your code was not very easy to maintain, so I made my own version, try it out:
function sort() {
var text = document.getElementById("text").value;
// will contain a list of chars with their associated count
var charCounter = {};
for (var i = 0, l=text.length; i < l; i++) {
var char = text[i];
// if char is a number
if(!isNaN(parseInt(char))){
if(charCounter[char]){ charCounter[char]++; }
else { charCounter[char] = 1; }
// if char is not a number
} else {
if(charCounter['other characters']){ charCounter['other characters']++; }
else { charCounter['other characters'] = 1; }
}
}
outputList(charCounter);
}
function outputList(obj){
var keys = Object.keys(obj);
var output = '';
for(var i=0, l=keys.length; i<l; i++){
output += 'Number of ' + keys[i] + ' : ' + obj[keys[i]] + '.\n';
}
alert(output);
}
JS Fiddle Demo
A simpler solution is to use an array of words for the number names and use it for keys on an object that accumulates the count of occurrences of each digit, e.g.
function countDigits(n) {
// Array of number names
var words = ['zeros','ones','twos','threes','fours',
'fives','sixes','sevens','eights','nines'];
// Split number into digits
var nums = String(n).split('');
var counts = {};
// Count how many of each digit
nums.forEach(function(n){
if (!(counts.hasOwnProperty(words[n]))) counts[words[n]] = 0;
++counts[words[n]];
});
// Write to output
words.forEach(function(w){
console.log('Number of ' + w + ' = ' + (counts[w] || 0) + '\n');
});
}
countDigits(1012023405);
/*
Number of zeros = 3
Number of ones = 2
Number of twos = 2
Number of threes = 1
Number of fours = 1
Number of fives = 1
Number of sixes = 0
Number of sevens = 0
Number of eights = 0
Number of nines = 0
*/
Or a slightly different formulation:
function countDigits(n) {
// Array of number names
var words = ['zeros','ones','twos','threes','fours',
'fives','sixes','sevens','eights','nines'];
var counts = [];
// Split number into digits and count
String(n).split('').forEach(function(n) {
counts[n] = counts[n]? counts[n] + 1 : 1;
});
// Write to output
for (var i=0; i<10; i++) {
console.log('Number of ' + words[i] + ' = ' + (counts[i] || 0) + '\n');
}
}

Categories

Resources