Javascript How To Concatenate Separate Characters Into One String In Array? - javascript

I wrote a code for a "Heads or Tails" game below and:
var userInput = prompt("Enter maximum number output: ");
function coinFlip() {
return (Math.floor(Math.random() * 2) === 0) ? 'Heads' ; 'Tails';
}
for (var i = 0; i < 6; i++)
{
var result = [];
result["randomNum"] = (Math.floor(Math.random()*userInput);
result["coin"] = (coinFlip());
}
I'm trying to count the sum of total heads and sum of total tails each with the code:
var headsCount = 0;
var tailsCount = 0;
for (var j = 0; j < result["coin"].length; j++)
{
if (result["coin"] == 'Heads')
headsCount++;
else
tailsCount++;
}
The only problem is that it's counting each characters of 'Heads' and 'Tails' in the result["coin"] array as separate (such as 'H'-'e'-'a'-'d'-'s') and not into a full string (like "Heads"). Thus, instead of increment by 1 each time the loop above runs, it increments by +5.
I want it to increment by +1 only.
How do I make it so that the code reads the full string stored in result["coin"] and not character-by-character?
EDITED -- changed the <2 to *2

var result = []; is inside the for loop, so it is being overwritten with an empty array each time. So when you try to loop over the results, there's one one item in it; the last one. Pull the result array out of the loop so that you can add to it in each iteration.
It seems userInput should be the number of times to loop. Not sure why you're putting it in result["randomNum"]. result is an array, not an object, so it only has integer keys.
Instead of adding the result of the coin toss to result["coin"] I think you mean to add it to the array, so after tossing it six times it might look like this: ["Heads", "Heads", "Tails", "Heads", "Tails", "Tails"]. You can do this by calling result.push with the coin toss output.
To get one of two results randomly, compare the output of Math.random() against 0.5, which is half way between the limits. Numbers less than 0.5 can be considered heads, while numbers greater than or equal to 0.5 can be considered tails.
Putting it all together, this is what I think you were going for:
function coinFlip() {
return Math.random() < 0.5 ? 'Heads' : 'Tails';
}
var result = [];
var userInput = parseInt(prompt("Enter maximum number output: "), 10);
for (var i = 0; i < userInput; i++) {
result.push(coinFlip());
}
var headsCount = 0;
var tailsCount = 0;
for (var j = 0; j < result.length; j++) {
if (result[j] == 'Heads')
headsCount++;
else
tailsCount++;
}
console.log(headsCount, "heads and", tailsCount, "tails");
All that being said, there are definitely areas for improvement. You don't need to loop once to build the results, then loop a second time to read the results.
You can count the number of heads/tails as the coins are flipped. For example:
function isCoinFlipHeads() {
return Math.random() < 0.5;
}
var numFlips = parseInt(prompt("How many flips?"), 10);
var heads = 0;
var tails = 0;
for (var i = 0; i < numFlips; i++) {
isCoinFlipHeads() ? heads++ : tails++;
}
console.log(heads, "heads and", tails, "tails");

Related

Javascript print square using for loop and conditional statement only

Just started my uni course, struggling a little with javascript. I have been asked to display a square using any character, however, the solution must combine for loops and if statements.
This is what I have so far and I feel pretty close but I just can't get the second line to display. I know this can be done via two for loops, (one for iteration of the variable and another for spaces). But this is not how I have been asked to solve this problem.
Here is my code:
var size = 3;
let i;
for(i = 0; i < size; i++) {
print ("*");
if (size === i){
println ("");
}
}
For context, this is all taking place int he professors homemade learning environment.
You could use nested for loops and take a line break after each filled line.
function print(s) { document.getElementById('out').innerHTML += s; }
function println(s) { document.getElementById('out').innerHTML += s + '\n'; }
var size = 5,
i, j;
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
print("*");
}
println("");
}
<pre id="out"></pre>
Single loop with a check if i is unequal to zero and if the remainder is zero, then add a line break.
Using:
=== identity/strict equality operator checks the type and the value, for example if both are numbers and if the value is the same,
!== non-identity/strict inequality operator it is like above, but it checks the oposite of it,
% remainder operator, which returns a rest of a number which division returns an integer number.
&& logical AND operator, which check both sides and returns the last value if both a truthy (like any array, object, number not zero, a not empty string, true), or the first, if it is falsy (like undefined, null, 0, '' (empty string), false, the oposite of truthy).
function print(s) { document.getElementById('out').innerHTML += s; }
function println(s) { document.getElementById('out').innerHTML += s + '\n'; }
var size = 5,
i;
for (i = 0; i < size * size; i++) {
if (i !== 0 && i % size === 0) {
println("");
}
print("*");
}
<pre id="out"></pre>
Well the for loop is only iterating 3 times, printing the first line. If you want a square you'll have to print 9 stars total, right? So i'm assuming, is this is the approach you'd go for, you would need to iterate not until size, but until size * size.
I'm using console.log to 'print' the square:
var dimension = 10;
var edge = '*';
var inside = ' ';
var printLine;
for (var i = 1; i <= dimension; i++) {
if (i === 1 || i === dimension) {
printline = Array(dimension + 1).join(edge);
} else {
printline = edge + Array(dimension - 1).join(inside) + edge;
}
console.log(printline);
}
Note that in the following example, an array of length 11 gets you only 10 "a"s, since Array.join puts the argument between the array elements:
Array(11).join('a'); // create string with 10 as "aaaaaaaaaa"
You wanna make a square of * where the size is the number of * on its sides?
Let's split a task into 3 parts:
where you print top side like *****
where you print middle (left and right sides) like * *
where you print bottom (same as top)
Now let's code that, I kept the code as simple as possible, this can be done in fewer lines but I think this will be easier to understand for beginners:
var size = 5;
var i = 0;
// top
for (i = 0; i < size; i++)
console.log("*");
//middle
for (var j = 0; j < size - 2; j++){
console.log("\n"); // go to next row
// middle (2 on sides with size-2 in between)
console.log("*");
for (i = 0; i < size-2; i++)
console.log(" ");
console.log("*\n"); // goes to new row as well
}
// same as top
for (i = 0; i < size; i++)
console.log("*");
Full square is even simpler:
var size = 5;
var i = 0;
for (var i = 0; i < size; i++){ // iterates rows
for (var j = 0; j < size; j++) // iterates * in row
console.log("*");
console.log("\n") // moves to new row
}
In order to print a row, you print same sign X times. Well, to print X rows we can use just that 1 more time (only this time we are iterating over a different variable (j is * in a row, i is a number of rows).
After a row is made we go to go to next row with \n.
As for
it must contain if statement
Put this at the end:
if (youCanHandleTheTruth) console.log("It's a terrible practice to tell students their solution MUST CONTAIN CODEWORDS. If you need them to showcase something, write appropriate task that will require them to do so.");

Factorializing a number by creating an array and multiplying it

I am going through one of the FreeCodeCamp challenges.
" Return the factorial of the provided integer.
If the integer is represented with the letter n, a factorial is the
product of all positive integers less than or equal to n.
Factorials are often represented with the shorthand notation n!
For example: 5! = 1 * 2 * 3 * 4 * 5 = 120 "
I already know that the easiest way is to use recursion but by the moment I've discovered this fact I was already trying to solve the problem by creating an array, pushing numbers in it and multiplying them. However I got stuck on this step. I have created an array with the number of digits depending on the function factorialize argument, but I can't get the product of those digits. What did I do wrong:
function factorialize(num) {
var array = [];
var product;
for(i = 0; i<=num;i++) {
array.push(i);
for (j=0; j < array.length; j++) {
product *= array[j];
}
return product;
}
}
factorialize(5);
I think the easiest way would be to create a range and reduce that:
var n = 5;
function factorize(max) {
return [...Array(max).keys()].reduce((a,b) => a * (b + 1), 1);
}
console.log(factorize(n));
It looks like you missed a close parenthesis
function factorialize(num) {
var array = [];
var product = 1;
for(i = 0; i<=num;i++) {
array.push(i);
} //right here!!! <----
for (j=0; j < array.length; j++) {
product *= array[j];
}
return product;
}
factorialize(5);
but as stated in the comments, you should change i = 0 to i = 1 not just because it would change the final result(which it does for all num ) but because it also doesn't follow the factorial algorithm.
1) You need initial value 'product' variable
2) You should change i = 0 to 1. You multiply by 0 in the loop
3) You don't need nested loop
function factorialize(num) {
var array = [];
var product = 1;
for(var i = 1; i <= num; i++) {
array.push(i);
}
for (j=0; j < array.length; j++) {
product *= array[j];
}
return product;
}
You only need one loop for that,
from 1 to the maximum number, then you multiply them up,
just a little clean up from your code
fact variable will contain the string version of the individual numbers making up the sum
if m is 5 you'll fact will be 1*2*3*4*5
function factorialize(num) {
var product = 1;
var fact = ""
for (i = 1; i <= num; i++) {
product *= i;
fact += i + "*"
}
fact = fact.substring(0, fact.length - 1)
console.log(fact)
return product;
}
console.log(factorialize(5));

Validation for numeric data Javascript

I'm writing a program in Javascript that separates even and odd numbers, puts them into an array, adds the sum of numbers, and finds the average.
I'm having an issue not allowing zeros not to count. Because its adding to the array, and when the user types in 6+6, sum is 12, average is calculating to 4 because of the extra 0 in the array.
Is there anyway to not allow the zeros to count? Here is what I have so far..
var evenarray = [];
var oddarray = [];
var avgEven = 0;
var avgOdd = 0;
var isValid;
function numberFunction(){
do
{
var numbers = prompt("Please enter numbers. Enter empty string to exit.");
if(numbers % 2 == 0)
{
evenarray.push(numbers);
var sumEven = 0;
for (var i=0; i < evenarray.length; i++)
{
sumEven = sumEven + Number(evenarray[i]);
}
var avgEven = sumEven/evenarray.length;
//alert("even");
}
if(numbers % 2 !== 0)
{
oddarray.push(numbers);
var sumOdd = 0;
for (var i=0; i < oddarray.length; i++)
{
sumOdd = sumOdd + Number(oddarray[i]);
}
var avgOdd = sumOdd/oddarray.length;
//alert("odd");
}
//if(isNaN(numbers)){
//alert("Only numeric data only");
//}
}
while(numbers !== "");
Just do nothing when the number is actually 0:
if (numbers == 0)
{
}
else if(numbers % 2 == 0)
{
evenarray.push(numbers);
var sumEven = 0;
for (var i=0; i < evenarray.length; i++)
{
sumEven = sumEven + Number(evenarray[i]);
}
var avgEven = sumEven/evenarray.length;
}
else // only odds remain
{
oddarray.push(numbers);
var sumOdd = 0;
for (var i=0; i < oddarray.length; i++)
{
sumOdd = sumOdd + Number(oddarray[i]);
}
var avgOdd = sumOdd/oddarray.length;
}
You can do :
if(numbers % 2 == 0 && numbers !=0) ...
if(numbers % 2 != 0 && numbers !=0) ...
so that you don't do anything when numbers == 0;
It's a little strange to call your variable numbers instead of number.
your function should be,
function numberFunction(){
do
{
var numbers = prompt("Please enter numbers. Enter empty string to exit.");
if(numbers !=0 && !isNaN(numbers))
(numbers %2 == 0)? (evenarray.push(parseInt(numbers))) : (oddarray.push(parseInt(numbers)));
}while(numbers !== "");
for(var i = 0; i < evenarray.length; i++)
sumEven += evenarray[i];
for(var i = 0; i < oddarray.length; i++)
sumOdd += oddarray[i];
avgEven = sumEven / evenarray.length;
avgOdd = sumOdd / oddarray.length;
document.getElementById("even").innerHTML = evenarray.toString();
document.getElementById("sumEvenTotal").innerHTML = sumEven.toString(); //displays sum of even numbers.
document.getElementById("averageOdd").innerHTML = avgOdd; //displays average of odd numbers.
document.getElementById("averageEven").innerHTML = avgEven; //diplays average of even numbers.
document.getElementById("odd").innerHTML = oddarray.toString(); //displays all odd numbers that were entered.
document.getElementById("sumOddTotal").innerHTML = sumOdd.toString();
}
As you already have other answers with solutions to your particular issue, I would suggest a different approach. Think of the data you're manipulating: an array. Try to solve the issue only with data, no user input, no DOM manipulation; just data. This helps to separate concerns, and make your code easier to understand.
Since we're working with arrays, we can make use of some of the built-in JavaScript methods that are present in modern browsers, such as filter and reduce. These methods are in a way, alternatives to for loops, with some pre-defined behavior, and a callback function.
Now, let's think of the steps involved in solving your problem.
Get numbers from the user. We can represent this data as an array, as you were already doing.
We want all odd numbers, their sum and average.
We want all even numbers, their sum and average.
We display the data to the user.
In this solution I'm assuming you already have an array with the data, and will be focusing on points 2 and 3. Remember, think of data, user interaction shouldn't be mixed with your data logic. Instead of asking the user for a number on each loop, you could ask the user for a list of numbers directly; you avoid multiple prompts this way, and it lets you separate data and interaction nicely. Ideally you'd validate all user input to match your requirements.
// Helpers to work with numbers
var odd = function(x) {
return x % 2 === 0;
};
var even = function(x) {
return x % 2 !== 0;
};
var add = function(x, y) {
return x + y;
};
function solve(ns) {
// Solve the problem
// with odd or even numbers
var result = function(fn) {
var xs = ns.filter(fn); // odd or even
var sum = xs.reduce(add);
return {
numbers: xs,
sum: sum,
average: sum / xs.length
};
};
// Return an object
// with odd and even results
return {
odd: result(odd),
even: result(even)
};
}
var numbers = [1,2,3,4]; // from user input
var result = solve(numbers);
console.log(result.odd);
//^ {numbers: [2,4], sum: 6, average: 3}
console.log(result.even);
//^ {numbers: [1,2], sum: 4, average: 2}

Finding Products within large Digits

I have been working on a way to find products of 5 digits within a large number. For example, I have the number 158293846502992387489496092739449602783 And I want to take the first 5 digits (1,5,8,2,9) and multiply them, then the second, (5,8,2,9,3), multiply then, then the third... And so on. Then I want to find the largest of all of them I find, now I came up with the following code to solve this problem:
// I put the digit into a string so I can modify certain parts.
var digit = "158293846502992387489496092739449602783";
var digitLength = digit.length;
var max = 0;
var tempHolder;
var tempDigit = 0;
var tempArray = [];
for(var i = 0; i<=digitLength; i++){
tempHolder = digit.substring(i, i+5);
tempArray = tempHolder.split("");
for(var j = 0; j < 5; j++){
tempDigit += tempArray[j];
}
if(tempDigit > max){
max = tempDigit;
}
}
console.log(max);
It logs to the console A longer number than what I put into it, along with 10 undefined, no spaces. Can anyone figure out the problem here?

Javascript generate random unique number every time

Ok so i need to create four randomly generated numbers between 1-10 and they cannot be the same. so my thought is to add each number to an array but how can I check to see if the number is in the array, and if it is, re-generate the number and if it isnt add the new number to the array?
so basically it will go,
1.create new number and add to array
2.create second new number, check to see if it exist already, if it doesn't exist, add to array. If it does exist, re-create new number, check again etc...
3.same as above and so on.
You want what is called a 'random grab bag'. Consider you have a 'bag' of numbers, each number is only represented once in this bag. You take the numbers out, at random, for as many as you need.
The problem with some of the other solutions presented here is that they randomly generate the number, and check to see if it was already used. This will take longer and longer to complete (theoretically up to an infinite amount of time) because you are waiting for the random() function to return a value you don't already have (and it doesn't have to do that, it could give you 1-9 forever, but never return 10).
There are a lot of ways to implement a grab-bag type solution, each with varying degrees of cost (though, if done correctly, won't ever be infinite).
The most basic solution to your problem would be the following:
var grabBag = [1,2,3,4,5,6,7,8,9,10];
// randomize order of elements with a sort function that randomly returns -1/0/1
grabBag.sort(function(xx,yy){ return Math.floor(Math.random() * 3) - 1; })
function getNextRandom(){
return grabBag.shift();
};
var originalLength = grabBag.length;
for(var i = 0; i < originalLength; i++){
console.log(getNextRandom());
}
This is of course destructive to the original grabBag array. And I'm not sure how 'truly random' that sort is, but for many applications it could be 'good enough'.
An slightly different approach would be to store all the unused elements in an array, randomly select an index, and then remove the element at that index. The cost here is how frequently you are creating/destroying arrays each time you remove an element.
Here are a couple versions using Matt's grabBag technique:
function getRandoms(numPicks) {
var nums = [1,2,3,4,5,6,7,8,9,10];
var selections = [];
// randomly pick one from the array
for (var i = 0; i < numPicks; i++) {
var index = Math.floor(Math.random() * nums.length);
selections.push(nums[index]);
nums.splice(index, 1);
}
return(selections);
}
You can see it work here: http://jsfiddle.net/jfriend00/b3MF3/.
And, here's a version that lets you pass in the range you want to cover:
function getRandoms(numPicks, low, high) {
var len = high - low + 1;
var nums = new Array(len);
var selections = [], i;
// initialize the array
for (i = 0; i < len; i++) {
nums[i] = i + low;
}
// randomly pick one from the array
for (var i = 0; i < numPicks; i++) {
var index = Math.floor(Math.random() * nums.length);
selections.push(nums[index]);
nums.splice(index, 1);
}
return(selections);
}
And a fiddle for that one: http://jsfiddle.net/jfriend00/UXnGB/
Use an array to see if the number has already been generated.
var randomArr = [], trackingArr = [],
targetCount = 4, currentCount = 0,
min = 1, max = 10,
rnd;
while (currentCount < targetCount) {
rnd = Math.floor(Math.random() * (max - min + 1)) + min;
if (!trackingArr[rnd]) {
trackingArr[rnd] = rnd;
randomArr[currentCount] = rnd;
currentCount += 1;
}
}
alert(randomArr); // Will contain four unique, random numbers between 1 and 10.
Working example: http://jsfiddle.net/FishBasketGordo/J4Ly7/
var a = [];
for (var i = 0; i < 5; i++) {
var r = Math.floor(Math.random()*10) + 1;
if(!(r in a))
a.push(r);
else
i--;
}
That'll do it for you. But be careful. If you make the number of random numbers generated greater than the may number (10) you'll hit an infinite loop.
I'm using a recursive function. The test function pick 6 unique value between 1 and 9.
//test(1, 9, 6);
function test(min, max, nbValue){
var result = recursValue(min, max, nbValue, []);
alert(result);
}
function recursValue(min, max, nbValue, result){
var randomNum = Math.random() * (max-min);
randomNum = Math.round(randomNum) + min;
if(!in_array(randomNum, result)){
result.push(randomNum);
nbValue--;
}
if(nbValue>0){
recursValue(min, max, nbValue, result);
}
return result;
}
function in_array(value, my_array){
for(var i=0;i< my_array.length; i++){
if(my_array[i] == value){
console.log(my_array+" val "+value);
return true;
}
}
return false;
}
Here is a recursive function what are you looking for.
"howMany" parameter is count of how many unique numbers you want to generate.
"randomize" parameter is biggest number that function can generate.
for example : rand(4,8) function returns an array that has 4 number in it, and the numbers are between 0 and 7 ( because as you know, Math.random() function generates numbers starting from zero to [given number - 1])
var array = [];
var isMatch= false;
function rand(howMany, randomize){
if( array.length < howMany){
var r = Math.floor( Math.random() * randomize );
for( var i = 0; i < howMany; i++ ){
if( array[i] !== r ){
isMatch= false;
continue;
} else {
isMatch= true;
break;
}
}
if( isMatch == false ){
array.push(r);
ran(howMany, randomize);
}
ran(howMany, randomize);
return array;
}
}
In your answer earlier, you do have a small bug. Instead of
var originalLength = grabBag.length;
for(var i = 0; i < originalLength .length; i++){
console.log(getNextRandom());
}
I believe you meant:
var originalLength = grabBag.length;
for(var i = 0; i < originalLength; i++){
console.log(getNextRandom());
}
Thanks.

Categories

Resources