JavaScript check if a random number has not been used already - javascript

I need to get random numbers but can't use the same number more than once.
I wrote the following functions to create a random number and to check if it has not been used yet.
function randomRecep(){
return Math.floor((Math.random() * 3));
}
function assignTemp(tempArr){
console.log("Started assign function, tempArr has: "+tempArr);
var num = randomRecep();
for (var i = 0; i < tempArr.length; i++) {
console.log("num is: " + num + ". check for doubles. tampArr["+i+"] is: "+tempArr[i]);
if (num == tempArr[i]){
console.log("FOUND DOUBLE! random num = "+num+" IS ALREADY IN array:"+tempArr)
assignTemp(tempArr);
break;
}
}
tempArr.push(num);
console.log("pushed " + num + "into array. now is:" + tempArr);
return num;
}
following is a console output. it seems that the check is working but for some reason at the end of the check instead of just pushing the unique random number and returning its value, it seems that the program pushes also all the previous duplicate numbers and returns the first random number instead of the last one that passed the check. why is that?
Started assign function, tempArr has: -1,2,1
code.js:104 num is: 1. check for doubles. tampArr[0] is: -1
code.js:104 num is: 1. check for doubles. tampArr[1] is: 2
code.js:104 num is: 1. check for doubles. tampArr[2] is: 1
code.js:106 FOUND DOUBLE! random num = 1 IS ALREADY IN array:-1,2,1
code.js:101 Started assign function, tempArr has: -1,2,1
code.js:104 num is: 1. check for doubles. tampArr[0] is: -1
code.js:104 num is: 1. check for doubles. tampArr[1] is: 2
code.js:104 num is: 1. check for doubles. tampArr[2] is: 1
code.js:106 FOUND DOUBLE! random num = 1 IS ALREADY IN array:-1,2,1
code.js:101 Started assign function, tempArr has: -1,2,1
code.js:104 num is: 0. check for doubles. tampArr[0] is: -1
code.js:104 num is: 0. check for doubles. tampArr[1] is: 2
code.js:104 num is: 0. check for doubles. tampArr[2] is: 1
code.js:113 pushed 0into array. now is:-1,2,1,0
this result is good and the idea is that it would stop here. but the process continues on:
code.js:113 pushed 1into array. now is:-1,2,1,0,1
code.js:113 pushed 1into array. now is:-1,2,1,0,1,1
I found code which is much simpler that achieves the above goal. However I am trying to learn and I don't yet understand what went wrong at the end of my method. where is the flaw in the logic?

So the problem with your current code is that you use break, where return should be used here
if (num == tempArr[i]){
console.log("FOUND DOUBLE! random num = "+num+" IS ALREADY IN array:"+tempArr)
assignTemp(tempArr);
break; // <-- should be return instead
}
The reason for this is, that once a non-unique number is found, you restart searching the next numbers, but the break will exit the loop, and directly after the for loop, you add num to your array. So, it would first add a potentially new unique number, and then exit that loop, and return to exit your first loop and then add the non-unique number ;)
You could also rewrite your code in the following way (I do not know if you have any requirements to a certain JavaScript versions, or you are only allowed to use a for loop)
function randomRecep(){
return Math.floor((Math.random() * 3));
}
function assignTemp(tempArr){
const number = randomRecep();
if (tempArr.includes( number ) ) {
console.warn( `${number} exists in [${tempArr.join(', ')}]` );
return assignTemp(tempArr);
}
console.warn( `adding ${number} to [${tempArr.join(', ')}]` );
tempArr.push( number );
return tempArr;
}
const output = [];
// shouldn't call this more than the nr of output possibilities (and the pool here has 3 options)
assignTemp( output );
assignTemp( output );
assignTemp( output );
// we will always expect 0, 1, 2 in the output in some manner
console.log( output );

Related

A task in JavaScript

I need to create a sequence of numbers using while or for that consists of the sum of the symbols of the number.
For example, I have a sequence from 1 to 10. In console (if I've already written a code) will go just 1, 2,3,4,5,6,7,8,9,1. If I take it from 30 to 40 in the console would be 3,4,5,6,7,8,9,10,11,12,13.
I need to create a code that displays a sum that goes from 1 to 100. I don't know how to do it but in console I need to see:
1
2
3
4
5
5
6
7
8
9
1
2
3
4
etc.
I've got some code but I got only NaN. I don't know why. Could you explain this to me?
for (let i = '1'; i <= 99; i++) {
let a = Number(i[0]);
let b = Number(i[1])
let b1 = Boolean(b)
if (b1 == false) {
console.log ('b false', a)
}
else {
console.log ('b true', a + b)
}
}
I hope you get what I was speaking about.
Although I like the accepted answer however from question I gather you were asking something else, that is;
30 become 3+0=3
31 become 3+1=4
37 becomes 3+7=10
Why are we checking for boolean is beyond the scope of the question
Here is simple snnipet does exactly what you ask for
for (let i = 30; i <= 40; i++) {
let x=i.toString();
console.log( 'numbers from ' +i + ' are added together to become '+ (Number(x[0])+Number((x[1])||0)))
}
what er are doing is exactly what Maskin stated begin with for loop then in each increment convert it to string so we can split it, this takes care of NAN issue.
you don't need to call to string just do it once as in let x then simply call the split as x[0] and so on.
within second number we have created a self computation (x[1])||0) that is if there is second value if not then zero. following would work like charm
for (let i = 1; i <= 10; i++) {
let x=i.toString();
console.log( 'numbers from ' +i + ' are added together to become '+ (Number(x[0])+Number((x[1])||0)))
}
Did you observe what happens to ten
here is my real question and solution what if you Don't know the length of the digits in number or for what ever reason you are to go about staring from 100 on wards. We need some form of AI into the code
for (let i = 110; i <= 120; i++) {
let x= Array.from(String(i), Number);
console.log(
x.reduce(function(a, b){ return a + b;})
);
};
You simply make an array with Array.from function then use simple Array.reduce function to run custom functions that adds up all the values as sum, finally run that in console.
Nice, simple and AI
You got NaN because of "i[0]". You need to add toString() call.
for (let i = '1'; i <= 99; i++) {
let a = Number(i.toString()[0]);
let b = Number(i.toString()[1])
let b1 = Boolean(b)
if (b1 == false) {
console.log('b false', a)
} else {
console.log('b true', a + b)
}
}
So the way a for loop works is that you declare a variable to loop, then state the loop condition and then you ask what happens at the end of the loop, normally you increment (which means take the variable and add one to it).
When you say let i = '1', what you're actually doing, is creating a new string, which when you ask for i[0], it gives you the first character in the string.
You should look up the modulo operator. You want to add the number of units, which you can get by dividing by 10 and then casting to an int, to the number in the tens, which you get with the modulo.
As an aside, when you ask a question on StackOverflow, you should ask in a way that means people who have similar questions to you can find their answers.

Trouble with recursive functions

Can anyone explain this to me? I'm having trouble wrapping my head around this concept of having function within a function.
function factorialize(num) {
if (num === 0) {
return 1;
}
return num * factorialize(num-1);
}
factorialize(10);
This is not a loop right? Why does the function call itself continuously? How does it know when to stop? Wouldn't it just continue to factorialize negative numbers to infinity?
Appreciate the help and guidance as always.
This is not a loop right?
Nope, it is not. It is a recursive function, a function that calls itself until a certain condition is met. In this case, is when num is equals to 0.
Why does the function call itself continuously?
Because the function is called in the return value of this function. It will continue calling the function itself, until num equals 0. In which case the function will exit and return 1.
How does it know when to stop?
The condition if (num === 0). The variable num gets subtracted if num isn't equal to 0 as stated in the code return num * factorialize(num-1);. Notice that the function returns fresh function call but with the parameter num - 1. When num becomes 0. The function returns 1.
Wouldn't it just continue to factorialize negative numbers to
infinity?
Because we have this if (num === 0) condition. So the num parameter decreases each time the code return num * factorialize(num-1); gets called, and eventually the above condition gets fulfilled and the function exits.
We can break it down step by step:
factorialize(10) gets called.
num is not 10, so return num * factorialize(num - 1). In this case num is 10 and num - 1 is 9, so we are actually returning the following: 10 * factorialize(10 - 1).
factorialize(9) gets called, then repeat step (1) and (2) until you get factorialize(0).
When you reach factorialize(0), it will return 1. So the whole function effectively returns 10 * 9 * 8 * ... 1 * 1.
Makes sense?
Recursion is a technique for iterating over an operation by having a function call itself repeatedly until it arrives at a result. You can read about it here
Lets visualize:
factorialize(10)
10*factorialize(9)
9*factorialize(8)
8*factorialize(7)
7 *factorialize(6)
6 *factorialize(5)
5 *factorialize(4)
4 *factorialize(3)
3 *factorialize(2)
2 *factorialize(1)
1 *factorialize(0)
1 (if num==0 return 1)
1
2
6
24
120
720
5040
40320
362880
3628800
Hope this helps!
Each time the function "factorialize" runs your argument "num" get decremented by
1. So num will run from 10 to 1 and when 1 is returned it will reach its terminal case 0. It is only terminal because of your "if" clause ( your base case ) when num === 0, you return 1, and your recursive "factorizlize" is never reached, so it is never executed.
I am not really good with analogies. However, If it still doesn't make sense let me know.
Every iterative problem can be solved by using recursion. try to look at this code
var start = 1;
var end = 10;
var increment = 1;
document.write("loop output: ")
for(var num = start; num <= end; num = num + increment){
document.write(num);
document.write(" ");
}
document.write("\n function output:\n")
function iteration(num) {
//stop condition statement
if (num > end) {
return 1;
}
// inside code block
document.write(num);
document.write(" ");
//incremention
iteration(num+increment);
}
iteration(start);
It uses internal functional frame stack for recursion purpose. for more about recursion look here . little practice is need to understand this concept.Hope make sense. Happy Coding !

Multiplying Integers on a For Loop

Beginning JavaScript learner here...
I'm working through Adrian Neumann's Simple Programming Problems and my question is about number 6 in the elementary exercises.
Write a program that asks the user for a number n and gives him the possibility to choose between computing the sum and computing the product of 1,…,n.
// var myArray = []; // for testing
var mySum = 0;
var userNum = prompt("What is your number? ");
var userChoice = prompt("Would you like to add up (+) or multiply (*) all the numbers from 1 to your number? Please enter (+) or (*): ");
if (userChoice == "+") {
for (var i = userNum; i > 0; i--) {
mySum += +i;
}
console.log("Your answer is " + mySum);
} else if (userChoice == "*") {
for (var i = userNum; i > 0; i--) {
mySum *= +i;
// myArray.push(i); // for testing
}
console.log("Your answer is " + mySum);
// console.log(myArray); // for testing
}
When entering values for multiplication, the answer is always 0. Obviously, I thought 0 was being included in the iteration, so I setup an empty array myArray, and pushed all the numbers to the array using myArray.push(i);... 0 was never included as a value in the array.
Other than some obvious form-validation considerations, can anyone tell me what I'm missing? Why is my answer always 0?
Note: The sum section of the code seems to work brilliantly.
Please note I'm a beginniner to JavaScript, so if you'd like to comment, let me know WHY you changed the code the way you do, rather than simply spitting back code to me. That's a big help, thanks.
Well, you initialize mySum to 0 so in every iteration of the loop you'll multiplying i by zero and save the result (again, zero) back into mySum. For multiplication you'd have to start at one.
You didn't set mySum to 1 before multiplication. 0*i = 0.

Can you explain how this Factorial function works?

I understand that "a" solution is:
function Factorial(number)
{
if(number == 0 || number == 1){
return 1;
}
return number * Factorial(number -1);
}
I want to understand what exactly is going on. I understand what is going on all the way to the last part when number == 1.
If we were to take a simple example of say 3!
3 is not equal to 0 or 1 so we return 3 * Factorial(2)
2 is not equal to 0 or 1 so we return 2 * Factorial(1)
1 is equal to 1 so we return 1
How do we know when to stop? Is it the fact that we return 1 that tells the function to stop?
If that is the case, why does the function not stop when we first return 3 * Factorial(2)? Is it because it's returning a function so that it must continue until it no longer returns a function?
Thank you
I think you have to understand the logic of factorial.
So factorial is just products, indicated by an exclamation mark ie, if you write
0! = 1
1! = 1
2! = 2*1
3! = 3*2*1
4! = 4*3*2*1
5! = 5*4*3*2*1
Hope you find the pattern, so you can write the above factorials as:
0! = 1
1! = 1
2! = 2*1!
3! = 3*2!
4! = 4*3!
5! = 5*4!
So in your function you are using the similar logic.
Now in your function
if(number == 0 || number == 1)
{
return 1;
}
The above logic is to cover the first two cases i.e, 0! and 1! And
return number * Factorial(number -1);
is for the rest of the numbers.
So you are using the recursive technique of solving the factorial problem.
To understand recursion, lets take a number say 5 i.e., we want find the value of 5!.
Then first your function will check
if(number == 0 || number == 1)
which is not satisfied, then it moves to the next line ie,
return number * Factorial(number -1);
which gives
5*Factorial(5-1) which is equal to 5*Factorial(4)
Now on subsequent calls to your Factorial function it will return the value like below:
5*(4*Factorial(4-1)) which is equal to 5*(4*Factorial(3))
5*(4*(3*Factorial(3-1)) which is equal to 5*(4*(3*Factorial(2)))
5*(4*(3*(2*Factorial(2-1)))) which is equal to 5*(4*(3*(2*Factorial(1))))
Now when it returns factorial(1) then your condition
if(number == 0 || number == 1)
is satisfied and hence you get the result as:
5*4*3*2*1 = 120
On a side note:
Beware that factrial is used only for positive integers.
Recursion relies on what is called a base case:
if(number == 0 || number == 1){
return 1;
}
That if statement is called your base case. The base case defines when the recursion should stop. Note how you are returning 1 not returning the result of a call to the function again such as Factorial(number -1)
If the conditions for your base case are not met (i.e. if number is NOT 1 or 0) then you proceed to call the function again with number * Factorial(number - 1)
If that is the case, why does the function not stop when we first return 3 * Factorial(2)?
Your simple example of 3! can be elaborated like this :
return 3 * Factorial(2)
will then be replaced by
return 3 * (2 * Factorial(1))
which then will be replaced by
return 3 * (2 * 1) // = 6 Hence 6 is returned at last and recursion ends.
How do we know when to stop?
When all your Factorial(value) is replaced by a returned value we stop.
Is it the fact that we return 1 that tells the function to stop?
In a way, yes. Because it is the last returned value.
It is called recursion.
This function is called like this
var result = Factorial(3);
in Factorial function
First time
return 3*Factorial(2);
Now here return statement doesnt get executed insted Factorial is called again..
so second time
return 2*Factorial(1);
again in Factorial(1)
Third time
return 1;
So go to second
return 2*1;
Next to first
return 3*(2*1);
Finally
var result = 3*2*1 = 6.
The function is recursing (calling itself) - and taking one from "number" each time.
Eventually (as long as its a positive integer you call it with, otherwise you'll probably get an infinite loop) you'll always hit the condition (number == 1) so instead of recursing further, it'll return 1 rather than call the function again.
Then, once you have hit the bottom (1), it'll start to run the function and work back up the other way along the function call stack, using the previous result each time:
1 = 1
(2*1) = 2
(3*2) = 6
(4*6) = 24
etc
So the final return statement from the function will return the required result

ignoring empty strings when looping through an array in JavaScript

I am attempting to go through an array and add up all the numbers. I used console.log to show me what values the script was using as shown below. I keep trying different variations of things in the if() but nothing seems to be working properly.
var billycount = 0;
var billyTotalScore = billyScoreList.reduce(function(score, total) {
if(score === " ") {
billycount += 1;
}
return +total + +score;
});
console.log(billycount); //0
console.log(billyTotalScore); //30
console.log(billyScoreList); // ["12", " ", "18"]
console.log(billyAverageScore) //10
var billyAverageScore = billyTotalScore/(billyteamlist.length - billycount);
The answer to billyAverageScore should equal 15 (30/2).
I tried if(score === "0") which gives me the same answers as above and if (score !== true) which gives me a count of 2 and an average of 30. I think reduce() is treating the empty string as a 0. I want to be able to count all the empty strings so I can discount them from the length when finding the average.
I have been wrestling this forever and feel like I'm missing one key concept behind it. Any help would be great! Thanks!
UPDATE:
For anyone who stumbles across this, here is the code I got to work.
var billycount = 0;
var billyTotalScore = billyScoreList.reduce(function(total, score) {
if (score === " " || total === " ") {
billycount++;
}
return +total + +score;
});
var billyAverageScore = billyTotalScore/(billyteamlist.length - billycount);
When I was just checking if (score === " ") I was forgetting that score will never be equal to the first term in the array. I just added || total === " ". the only time this would break down would be if the first element was " " and the second element was 0. I would want to billycount++ for the first element but not for the second. I'll have to give that some more thought.
The callback function of reduce should be function(total, score) instead of function(score, total).
see MDN:
previousValue
The value previously returned in the last invocation of the callback, or initialValue, if supplied. (See below.)
currentValue
The current element being processed in the array.

Categories

Resources