How i put together two functions, both with a recursion inside - javascript

I am a beginner and this my first post here(plus I'm not a native English speaker), so please forgive me if my code and/or my English are bad.Given two numbers I want to write a JavaScript function to find if the second one is a power of the first one, and then determine that power (ex: 2,8 the output must be 3). I wrote two functions, both working, but I can't put them together.
This is the first one to check if the second number is a power of the first one.
function checkNumbers(x,y){
if (y%x !==0){
return "this numbers are not valid"
}
else if(x===y) {
return "correct!"
}
else {
y=y/x
return checkNumbers(x,y)
}
}
checkNumbers(2,8) // will give the first answer
checkNumbers(2,18) // will give the second answer
The second function will give you the integral logarithm:
count =1;
function findGrade(x,y) {
if(y/x===1)
return "the grade is " + count;
count++;
y = y/x;
return findGrade(x,y)
}
findGrade(2,8) // output 3
findGrade(2,16) // output 4
How can I put them together into one function? I think i need a closure, but I didn't find the way to make that work.

checkNumbers should return a Boolean value, not a message. Then findGrade can check that result to see whether it should compute the logarithm. Something like this:
function checkNumbers(x,y){
if (y%x !==0){
return false
}
else if(x===y) {
return true
}
// the rest of your function remains the same.
function findGrade(x,y) {
// First, check to see whether y is a power of x
if checkNumbers(x,y) {
// your original findGrade function goes here
}
else
return -1; // Use this as a failure code.
Does this work for you?
Another possibility is to combine the functions entirely: try to find the logarithm (what you call "grade"); if it works, you get your answer; if it fails (at y%x !== 0), then you report the failure.

The solution is, in fact, pretty simple.
You could do the following:
function findGrade(x, y, count = 1) {
// If the numbers are not valid, throw an error. The execution is interrupted.
if(y % x != 0) throw "Invalid inputs";
// If the inputs are different, continue the execution and add 1 to count.
if(x != y) return findGrade(x, y/x, ++count);
// If none of the above are true, you have your result!
return count;
}
Tests:
console.log(findGrade(2, 8)); // Outputs 3
console.log(findGrade(2, 16)); // Outputs 4
console.log(findGrade(2, 3)); // Error: Invalid inputs
console.log(findGrade(3, 3486784401)); // Outputs 20
Please let me know if you need any further help.

I'm not sure if my method is different, but I have implemented it below. In real world application I would do some more typechecking on inputs and check if there is a third argument: if not default to 0 (First Iteration default the count to 0), but this is the general idea. You can run the snippet below.
// Arguments
// 1: Base of Exponent
// 2: test Number
// 3: count by reference
function checkPower (base, test, count) {
let division = test/base
// base case
if (division === 1) {
count++
return count
} else if (division < 1) {
console.log("not a power")
return;
}
// iteration step
count++
return checkPower(base, division, count++)
}
// Test Cases
let test = checkPower(2, 32, 0)
if (test) {
console.log(test) // 5
}
test = checkPower(2, 1024, 0)
if (test) {
console.log(test) // 10
}
test = checkPower(2, 9, 0)
if (test) {
console.log(test) // "not a power"
}

Related

Cannot complete the cycle of functions in my javascript code when manipulating the DOM

Being a beginner, I am trying to get my function to run my game code again after checking the answer and then running the level it was on. I have a function to calculate the sum of two numbers, and then I have another function to check the sum adds up to the correct answer and then runs the game again. I can get it to work out the sum, and say if it is correct of not, but I cannot seem to get it to run the game again.
In the function, I had tried creating a variable that gets elements by their class name, so it returns an array like object, to which I then used a for of loop to iterate through to check if an elements attribute is identical to a string and if so to then assign the string to the index of the loop. I would prefer to try run an if else if statement to return the sum of the numbers and then the string, so the other function I call this function in, can see the level but because its not a global variable it cannot see it, so I have been trying to go about storing the attribute data as a level with another variable but I cannot seem to get my head round it and how to get it right.
The function to check the sum of the two numbers and then the level
function calculateAnswer(operand1, operand2) {
operand1 = parseInt(document.getElementById("player-number").value);
operand2 = parseInt(document.getElementById("computer-number").innerText);
let levels = document.getElementsByClassName("levels");
for (level of levels) {
level.addEventListener('submit', function(gameType) {
if (this.getAttribute("data-entry").innerText === "level-one") {
gameType = "level-one";
} else if (this.getAttribute("data-entry") === "level-two") {
return [operand1 + operand2, "level-two"]
} else if (this.getAttribute("data-entry") === "level-three") {
return [operand1 + operand2, "level-three"]
}
})
}
return [operand1 + operand2, levels];
}
The function to then calculate if the answer is correct and run the gam again
function checkAnswer() {
let goalTarget = parseInt(document.getElementById("num-target").innerHTML);
let calculatedAnswer = calculateAnswer();
let isCorrect = goalTarget === calculatedAnswer[0];
if (isCorrect) {
alert("Well done, you got it right :D");
playerScore();
} else {
alert(`Sorry, that is incorrect, your total adds up to ${calculatedAnswer[0]}, try again`);
computerScore();
}
runGame(calculatedAnswer[1]);
}

LeetCode two sum not working as expected with a hash graph

I am trying to come up with an efficient solution to the two sum function on leetCode. From what I understand this code SHOULD work, but it keeps on returning undefined
var twoSum = function(nums, target) {
let hashGraph = {}
let slow = 0
let fast = nums.length - 1
while(slow < Math.abs(nums.length / 2)) {
if(nums[slow] + nums[fast] == target) {
return [slow, fast]
} else if(!hashGraph[target - nums[slow]] === undefined) {
let answer = [slow, hashGraph[target - nums[slow]]].sort()
return answer
} else if(!hashGraph[target - nums[fast]] === undefined) {
return [hashGraph[target - nums[fast]], fast].sort()
} else {
hashGraph[nums[slow]] = slow
hashGraph[nums[fast]] = fast
slow++
fast--
}
}
};
essentially I am storing the values at each index inside of a hash graph and assigning the values at that location to the index that the number was found. When I iterate through I am checking if the complement for the number at the current index exists in the hash table. If it does I return the current index and the value of the found index (which is the value in the array that the number was discovered on)
For the first test case I am given the array [2,7,11,15] and a target of 9
what SHOULD happen here is that the while loop's else case is hit and the graph is populated as follows:
{
2: 0,
15: 3
}
Then on the second iteration the second condition is hit where it checks if
hashGraph[target - nums[slow]] is valid. Given the target of 9 and the input of 7 I am essentially asking it if hashGraph[9-2] or hashGraph[2] exists. Indeed it does, however when visualizing the execution with python tutor's Javascript execution visualizer it fails this check and reaches the else clause.
This is what is stumping me. hashGraph[2] does exist. I can replicate the same thing and get the correct result if I use the following:
let hash = {
2: 0,
15: 3
}
let arr = [7]
console.log(hash[9 - arr[0]])
If that code gets me the correct result then why does my if condition fail?

Count each character in string using recursion

i have tried to make a function count each character in a string using recursion, for 2 days now. I tried to write some pseudo-code, but i can't really implement it.
Pseudocode:
write a function that takes text as a parameter
set a counter, for each element
set a result, using key,value for each character in element
base case: if we only have 1 string, then return the character and string
else return function-1 until the last element is hit.
var tekst = "We have to count strings";
function countStrings(tekst) {
var count = 0
var result = {}
if (count > tekst.lentgh) {
count++
return result
} else {
return countStrings(tekst-1)
}
}
console.log(countStrings(tekst))
Consider using this logic:
var tekst = "We have to count strings";
function countStrings(tekst) {
if (tekst.length == 0) {
return 0;
}
return 1 + countStrings(tekst.substring(1));
}
console.log(countStrings(tekst))
The approach here is, at each step of the recursion, to return 1 plus whatever the length of the substring from the next character onwards is. That is, we recurse down the input string, one character at a time, building out the length. The base case here occurs when the input to countStrings() happens to be empty string. In this case, we just return 0, and stop the recursive calls.
I decided to attempt this problem and this is what I came up with. Definitely a challenging problem so don't feel bad if you didn't get it:
var countStrings = function(tekst) {
if (tekst.length === 0) return {};
var obj = countStrings(tekst.slice(1));
if (obj[tekst[0]]) {
obj[tekst[0]] += 1;
} else {
obj[tekst[0]] = 1;
}
return obj;
};

The following code only produces an output true. How to debug it?

I have the following code to generate prime numbers. However, instead of generating prime number, it generates the entire list on numbers from 2 to the number that is fed into the function. How to resolve this?
var i = 2;
var primeCheck = function(number){
while(i<number){
if(number%i===0)
{
break;
}
i++;
}
if (i===number)
{
return true;
}
};
var primeGen = function(limit){
for(k=2; k<=limit; k++)
{
if(primeCheck(k)){
console.log(k);
}
}
};
primeGen(10);
EDIT: I realized that I was quite unclear with my question. So I updated it. My guess is that the "return true" is causing this nuisance. Therefore I had asked my previous question based on that.
If you want to return something you have to return instead of alert; break. I would consider refactoring this though. First of all, you should never have a function that performs such a simple task rely on an outside variable. Keep it modular.
function isPrime(num) {
for (var i = 2; i < num; i++) {
if (num % i === 0) {
return false;
}
}
return num > 1
}
This will return true if the number is prime and false otherwise. This is useful because you now have the flexibility to do multiple things with it. If you want to return true or false, it does that. If you want to output something else like "prime" or "not prime" it's very easy to wrap further.
function isPrimeText(num) {
return isPrime(num) ? "Prime" : "Not Prime"
}
Your if condition that returns the alert runs with primecheck() without parameters. Correct it to:
if (primeCheck(11)) {
alert("prime");
}
Also, remove the last line with the call to primeCheck(11).
Just use primeCheck(11) in your condition where you want to put alert
There is some error in your logic, when I try with primeCheck(12) it does not gives intended result.
var i = 2;
var primeCheck = function(number){
while(i<Math.floor(Math.sqrt(number))){
if(number%i===0)
{
alert("Not a prime");
break;
}
i++;
}
if (i===Math.floor(Math.sqrt(number)))
{
return true;
}
};
//now check for prime or not prime
if(primeCheck(11))
{
alert("prime");
}
if(!primeCheck(12))
{
alert("not prime");
}

How to use a Math.random function in association with an IF statement

I am trying to output different messages based upon the output of a function that uses the math.random function to generate a number between 1 and 4.
function roll()
{
return Math.floor(Math.random()*4+1)
}
When a button is pressed the function is called and a global variable 'a' is assigned to the result of the roll function.
var a;
function buttonPressed() {
roll()
a = roll()
answertq = (x*y);
The following code essentially means that if the answer the user provides in the answer box is correct then depending upon the result of the roll function output a different message as below.
if (parseInt(document.getElementById("inputVal").value) == answertq)
{
if (a=1)
{
window.alert("Very good!");
}
else if (a=2)
{
window.alert("Excellent!");
}
else if (a=3)
{
window.alert("Correct, Nice work");
}
else if (a=4)
{
window.alert("Correct - Keep up the good work");
}
}
Except that when I do this I always get the first response ("Very good!") every time the question is correct. Meaning that there is something wrong with the roll function in that it keeps assigning 1 to the global variable 'a' or something else I have not spotted. Any help would be much appreciated. I have provided two screenshots of the problem below.
[1] http://imgur.com/riFktIH "Example One"
[2] http://imgur.com/YjcmuRx "Example Two"
Except that when I do this I always get the first response ("Very
good!") every time the question is correct.
The reason is because you are not comparing the values you are assigning. == is for comparison and = is for assignment.
Try this:
if (a==1)
{
window.alert("Very good!");
}
else if (a==2)
{
window.alert("Excellent!");
}
else if (a==3)
{
window.alert("Correct, Nice work");
}
else if (a==4)
{
window.alert("Correct - Keep up the good work");
}
You need to compare a==1 not assign a=1
Why don't you use an array for your messages?
That way you can use the random number as an index for the array.
var msg = [
"Very good!",
"Excellent!",
"Correct, Nice work",
"Correct - Keep up the good work"
];
function randomMsg (){
var random = Math.floor(Math.random() * 4);
alert(msg[random]);
}
edit: arrays are zero based so no "+1"
All of your if statements are using the assignment operator "=" not the comparison operator "==":
if (parseInt(document.getElementById("inputVal").value) == answertq) {
if (a==1) {
window.alert("Very good!");
}
etc...

Categories