my objective is to use recursion to get sigma notation working. top limit is n(input variable) bottom limit is i=1, and the function is (-i)^(i-1). i got it working with iteration but i cant get the recursion to work.
<!DOCTYPE html>
<head><title>Recursion</title></head>
<body>
<h1>Recursion</h1>
<script = "text/javascript">
var num
var i;
var n;
var total;
total = 0;
i=0;
var b;
b=0;
function formula(n)
{
(Math.pow((-i),(i-1)))
}
function recursion(n)
{
i=i+1;
if ((n-i) == 0)
{
document.writeln("done");
}
else
{
total = total + recursion(formula(n-i));
return total;
//total = total + (Math.pow((-i),(i-1)) + recursion(n-i));
}
}
num = window.prompt("pick a number");
recursion(num);
document.writeln(recursion(num));
//document.writeln(total);
</script>
</body>
</html>
Please avoid any global variables, that makes it very hard to read. Also, indent your code properly; and don't mix the output (document.write) into the computation. If you don't understand the recursion, just use a loop:
var total = 0;
for (var i=1; i<=n; i++)
total += formula(i);
return total; // the result
The same thing, done with recursion:
function sumFormulaUpTo (n) {
if (n <= 0) // the abort condition
return 0;
else
return sumFormulaUpTo(n-1) + formula(n);
}
sumFormulaUpTo(100);
You notice: there is no total variable, only the result of the recursively called function is used.
With an end recursion (more like the loop), it would look like this:
function sumFormulaFromTo(total, i, n) {
if ( i > n )
return total;
else {
var newtotal = total + formula(i);
return sumFormulaFromTo(newtotal, i+1, n);
}
}
sumFormulaFromTo(0, 1, 100);
If you had total and n declared statically outside the function, it would look more like yours. Yet, you forgot to return the result once the end condition is met (you just output something, but return undefined), and you somehow called the recursion with the result of formula - no idea where you got that from. This causes an infinite loop, according to #cbayram.
Related
I am attempting to have someone input there credit card number and validate if it is a valid number by doing the Luhn Check. I want to be able to check it if they input the whole card number as one big string or if they put spaces in it. In my function validate though I keep getting an error message that there is an illegal return statement for my total variable. Here is my current code.
<script type="text/javascript">
function validate(numbers) {
var sum;
var sum1;
var total;
for (i = 0; i < numbers.length; i++) {
if (numbers.length % 2 == 0) {
sum += numbers[i];
}
else
if ((numbers[i] * 2) >= 10) {
sum1 += numbers[i] - 9;
}
else
sum1 += numbers[i];
}
total = sum + sum1;
return total;
}
function cardnumber() {
var cardnumber = document.getElementById("input").value;
var numbers = cardnumber.split(" ");
var out = "";
for (i = 0; i < numbers.length; i++) {
out += validate(numbers[i]);
if (out % 10 == 0)
return true;
}
}
function getOutput() {
if (cardnumber()) {
alert("You card is valid.");
}
}
</script>
<body>
<h1>I will validate a credit card number</h1>
Card Type:
<input type="radio" id="c1" value="Visa">Visa</input>
Card number: <textarea id="input" style="vertical-align: middle;"></textarea></br>
<input type="button" value="Submit" onclick="getOutput()" /></br></br>
</body>
Your function validate is missing an opening curly brace after the for loop. This made your return statement outside of your function and since a return statement is invalid outside of a function it was an invalid return statement.
function validate(numbers){
var sum;
var sum1;
var total;
for (i=0; i<numbers.length; i++) { // this previous curly brace `{` was missing
if (numbers.length%2==0){
sum += numbers[i];
}
else
if ((numbers[i]*2)>=10){
sum1 += numbers[i] -9;
}
else
sum1 +=numbers[i];
}
total = sum + sum1;
return total;
}
EDIT WITH MORE CORRECTIONS:
There is quite a bit more wrong with the formatting of you functions you also need to include opening and closing curly braces around your other else statements. I would suggest getting a code editor like VS Code and downloading an extension similar to Bracket pair colorizer 2. It will highlight paired brackets together. This will help you with your formatting.
function validate(numbers){
var sum;
var sum1;
var total;
for (i=0; i<numbers.length; i++) {
if (numbers.length%2==0){
sum += numbers[i];
}
else {
if ((numbers[i] * 2) >= 10) {
sum1 += numbers[i] - 9;
}
else {
sum1 += numbers[i];
}
}
}
total = sum + sum1;
return total;
}
function cardnumber(){
var cardnumber= document.getElementById("input").value;
var numbers = cardnumber.split(" ");
var out ="";
for (i = 0; i < numbers.length; i++) {
out += validate(numbers[i]);
}
if (out %10==0)
return true;
}
function getOutput() {
if (cardnumber()) {
alert("You card is valid.");
}
}
These are all the changed lines (the left is new code and the right side is the old code):
Tips for completion
validate function
So, currently if you console.log your numbers are strings when they pass into the validate function. This is fine when they are sent into validate, but when you add the numbers at index i (i.e. numbers[i]) you should use parseInt(numbers[i], 10) to turn them into numbers, so for example sum += parseInt(numbers[i], 10); the same applies when adding to sum1. The other thing to note is that saying var sum will make sum equal the undefined value. When you add a number or string to an undefined value some unexpected things will probably happen, so since you need your sums and totals to be numbers you should instead initialize your sums and totals at 0. Like so:
var sum = 0;
var sum1 = 0;
var total = 0;
The only other thing wrong with your validate function is that your are checking if numbers.length%2==0 which instead you should be checking if i%2==0. You may have to think about why for a moment, but one thing you may notice is the length of numbers never changes during the iteration of the loop where as i does change at each step.
cardnumber function
Your out variable needs to be initialized to zero. Your cardnumber can instead be split by spaces and then joined by the empty string. This handles if the user accidentally types multiple spaces. Then since you join your split array you no longer would need a for loop.
var numbers = cardnumber.split(" ").join('');
var out =0;
out += validate(numbers);
Lines that need changing somehow
Here's a difference of the lines of the old code that where incorrect and need to be changed somehow. I'm not giving you the completed code, but hopefully this will be sufficient to help you figure out the rest on your own (I feel I shouldn't give you all of the solution due to some degree of academic integrity. I would feel I robbed you the opportunity to learn more if I don't at least let you think through and type it out on your own.). If you are wondering what needs to be changed on a specific line that is highlighted red all of it should be above, so best of luck.
My program is supposed to take in an unknown amount of numbers and calculate the average to see if its >49 or <50. The problem occurs in the for loop. My sum isn't adding each mark and returns an undefined value. I have no idea why this is happening because the actual marks passes through the loop perfectly fine
var passingAverage = function ()
{
var sum;
var marks = arguments;
var average;
var i;
for (i =0; i<marks.length; i++)
{
sum += marks.length[i];
}
average = (sum/i);
if (average > 49)
{
return ("true");
}
else if (average < 50)
{
return ("false");
}
};
console.log('passingAverage(75,42,98) returns: ' + passingAverage(75,42,98));
console.log('passingAverage(34,93,77,89,49) returns: ' + passingAverage(34,93,77,89,49));
console.log('passingAverage(33,61) returns: ' + passingAverage(33,61));
console.log("\n");
I think you need to initalise sum. change var sum to var sum = 0;
sum += marks.length[i];
this is not the true way of calling an array elements
replace sum += marks.length[i]; with sum += marks[i]; , then the true sum gonna be calculated , and your average has a true value
be aware of the initial value of sum when you are defining it , it must be var sum = 0;
I've got the running code here: https://jsfiddle.net/bwcpps1v/
var passingAverage = function ()
{
var sum = 0;
var marks = Array.from(arguments);
var average;
var i;
for (i =0; i<marks.length; i++)
{
sum += marks[i];
}
average = (sum/marks.length);
if (average > 49)
{
return true;
} else if (average < 50) {
return false;
}
};
console.log('passingAverage(75,42,98) returns: ' + passingAverage(75,42,98));
console.log('passingAverage(34,93,77,89,49) returns: ' + passingAverage(34,93,77,89,49));
console.log('passingAverage(33,61) returns: ' + passingAverage(33,61));
A few observations:
You need to get better at debugging. Learn about Chrome Dev tools as a start to debugging JS. Step through your source watching key vars and you would have caught the earliest error faster.
Spend some time with a linter and also, indenting your code right using an IDE or decent text editor - it makes it easier to read and debug.
I would like to sum the given factorials numbers in javascript
'1! + 2! + 3! + ... + n!'
You may use factorial function :
Iterative function:
function sFact(num)
{
var rval=1;
for (var i = 2; i <= num; i++)
rval = rval * i;
return rval;
}
Recursive
function rFact(num)
{
if (num === 0)
{ return 1; }
else
{ return num * rFact( num - 1 ); }
}
I copied these function from this link.
Now what can you do is.
Suppose n value is 6.
var n = 6;
var sum = 0;
for(var i=1;i<=n;i++)
{
sum = sum + rFact(i);//Here you can use one of factorial funciton. I am using recursive function
}
document.print("The answer is "+ sum );
The naïve solution would be to actually calculate every factorial and add them together, which has a complexity of O(n²). However, if you're clever, you can design an algorithm that solves the same problem with a complexity of O(n). Take a look at the pattern of the following example that calculates the sum of the factorials of 1 through 4.
1!+2!+3!+4! =
1+1*2+1*2*3+1*2*3*4
Notice how you're reusing results from previous calculations multiple times? This can be taken advantage of. You can calculate the sum of all the factorials up to n with a program something like this.
function sumFactorials(n) {
var sum = 0;
var prod = 1;
for(var i=1; i<=n; i++) {
prod *= i;
sum += prod;
}
return sum;
}
I am writing a function that raises a value to another value without using the exponent operator. I understand the syntax of these kinds of loops as being that initialised values go before the first semicolon, a condition goes between the first and the second semicolon, and after the second semicolon is the looping operations.
I am confused because I think this code should be broken, but it appears to return the correct value. When I put result *= base after count++ inside the parenthesis, then the code does not return the correct value. Why is this?
//Power function
function power(base, exponent) {
var result = 1
var count = 0
for (; count < exponent; count++)
result *= base
return result;
}
print(power(5, 2));
The blank ; just acts as a placeholder in this case. Because you declared count = 0 above this for loop, this ; is just there so that declaration isn't overwritten:
var count = 0;
for(/*var count=0*/; count < 4; count++){
document.write(count);
}
P.S. I commented out var count = 0 because that is essentially what the code is representing (because you called that earlier).
It is possible to do what you want in javascript. I think the only problem is that you didn't use brackets. This will work.
//Power function
function power(base, exponent){
var result = 1;
var count = 0;
for (; count < exponent; count++, result *= base) {}
return result;
}
document.write(power(5, 2));
//returns 25
But this won't because even if you don't indent return, it will be executed in the for loop and return during the first iteration. I ran in this issue when I tried your code snipplet so I think it is your issue :
//Power function
function power(base, exponent){
var result = 1;
var count = 0;
for (; count < exponent; count++, result *= base) //notice the missing brackets
return result;
}
document.write(power(5, 2));
//returns 25
function averageCalculator (numvalues) {
for(i=0, i <= numvalues, i++>) {
var score = prompt("input the score")
result1 += score;
}
alert(result1 / 3);
}
this function is later triggered by a button with onclick="averageCalculator (2)
<input type="button" value="Click for the average" onclick="averageCalculator (2)">
any ideas why its not working? it should prompt you for 2 values and then alert you with the average. not sure whats wrong.
Your code has multiple issues. The for loop is not well formatted and you need to terminate statements with a semi-colon. Also you need to declare variables. And your loop will run numvalues+1 times which is why i removed the = in your loop. Also if you want to calculate an average you want to divide by numvalues.
function averageCalculator (numvalues) {
var result1 = 0;
for(i=0; i < numvalues; i++) {
var score = prompt("input the score");
result1 += score;
}
alert(result1 / numvalues);
}
On top of the invalid syntax you will run into a common "problem" with javascript here. The inputs are treated as strings and instead of being added they will be concatenated. Providing 2 and 2 as scores will result in 11. 2 concatenated with 2 = 22 / 2 = 11. You need to cast the value to a number explicitly before adding them together:
function averageCalculator (numvalues) {
var result1 = 0;
for(i=0; i < numvalues; i++) {
var score = prompt("input the score");
result1 += Number(score);
}
alert(result1 / numvalues);
}
Above code will correctly return 2
The syntax of your for-loop is wrong:
for(i=0, i <= numvalues, i++>) {
should be
for(i=0; i <= numvalues; i++) {
Tip: Also, it's better to use
for(var i=0; i <= numvalues; i++) {
since then i will be a local variable instead of a global one.
Try like this
for(var i=0; i <= numvalues; i++){}
An alternative solution (using a functional programming libary, like Underscore.js):
function averageCalculator(numValues) {
var numbers = _.map(_.range(numValues), function(element) {
return +prompt('input the score');
});
var result = _.reduce(numbers, function(memo, number) {
return memo + number;
}, memo);
alert(result / 3);
}
While a little bit more complicated (and less efficient), you'll get rid of loops altogether.
EDIT
The +prompt('input the score') does effectivly the same as Number(prompt('input the score')).