function subtraction(num1, num2){
var num3;
num3 = num1 - num2;
document.writeln("Difference "+ num3);
return (num3);
}
function division(num1, num2){
difference = parseFloat(subtraction());
var x;
while(difference > 0){
difference = num1-num2;
x = x + 1;
}
document.writeln("Quotient" + x);
}
Hi! I wanted to do a division function but the catch is I will not use "/". This is what I got and so far this prints out "undefined" and if I stated x = 0 it will print out "0".
I fixed some problems with your code:
function division(num1, num2){
var difference = num1-num2; // difference is now a local variable
var x = 0; // x should be initialized
while(difference > 0){
difference = difference-num2; // difference should change, not always be num1-num2
x = x + 1;
}
console.log("Quotient" + x);
console.log("Remainder" + (difference+num2));
}
http://jsbin.com/UQIqejo/1/edit
You still have some problems with the algorithm itself, as num2 being less than or equal to 0 will result in an infinite loop, but i expect finding those problems is part of the fun.
EDIT: Smaller version of the same code:
function divisionSmall(a,b) {
var x = 0;
while ((a-=b) > 0) x++;
console.log('Quotient', x);
console.log('Remainder', a+b);
}
EDIT2: Correct division:
function divisionSmall(a,b) {
var x = 0;
while ((a-=b) > 0) x++;
return [x, a+b];
}
function divisionCorrect(a,b) {
var ans;
if (b === 0) return ['INF', 0];
if ((a > 0) && (b > 0)) {
return divisionSmall(a,b);
}
if ((a > 0) && (b < 0)) {
ans = divisionSmall(a,-b);
return [-ans[0], ans[1]];
}
if ((a < 0) && (b > 0)) {
ans = divisionSmall(-a,b);
return [-ans[0] - 1, b-ans[1]];
}
if ((a < 0) && (b < 0)) {
ans = divisionSmall(-a,-b);
return [ans[0] + 1, -b-ans[1]];
}
}
console.log(divisionCorrect(11,3)); // 3, 2
console.log(divisionCorrect(11,-3)); // -3, 2
console.log(divisionCorrect(-11,3)); // -4, 1
console.log(divisionCorrect(-11,-3)); // 4, 1
There is still the challenge of doing the logic without ifs :). Good luck.
If your doing numbers their is a simpler way to do this using recursion:
function divide(num,denom) {
if (num < denom) return 0;
return (1 + divide(num - denom, denom));
}
For negative numbers you would have to extend this to track if numbers were less than 0. Also, while concise and neat, this breaks down for large numerators and small denominators as the max call stack size will be exceeded.
I believe your issue is with your while loop. If the subtraction method returns a negative number it will not compute.
User Math.abs to get absolute value.
<script>
function division(num1, num2){
var difference = Math.abs(parseFloat(subtraction(num1, num2)));
var x = 0;
while(difference > 0){
difference = difference-num2;
x = x + 1;
}
document.writeln("Quotient" + x);
}
function subtraction(num1, num2){
var num3;
num3 = num1 - num2;
document.writeln("Difference "+ num3); return (num3);
}
</script>
Related
Trying really hard to figure out how to solve this problem. The problem being finding nth number of Fibonacci with O(n) complexity using javascript.
I found a lot of great articles how to solve this using C++ or Python, but every time I try to implement the same logic I end up in a Maximum call stack size exceeded.
Example code in Python
MAX = 1000
# Create an array for memoization
f = [0] * MAX
# Returns n'th fuibonacci number using table f[]
def fib(n) :
# Base cases
if (n == 0) :
return 0
if (n == 1 or n == 2) :
f[n] = 1
return (f[n])
# If fib(n) is already computed
if (f[n]) :
return f[n]
if( n & 1) :
k = (n + 1) // 2
else :
k = n // 2
# Applyting above formula [Note value n&1 is 1
# if n is odd, else 0.
if((n & 1) ) :
f[n] = (fib(k) * fib(k) + fib(k-1) * fib(k-1))
else :
f[n] = (2*fib(k-1) + fib(k))*fib(k)
return f[n]
// # Driver code
// n = 9
// print(fib(n))
Then trying to port this to Javascript
const MAX = 1000;
let f = Array(MAX).fill(0);
let k;
const fib = (n) => {
if (n == 0) {
return 0;
}
if (n == 1 || n == 2) {
f[n] = 1;
return f[n]
}
if (f[n]) {
return f[n]
}
if (n & 1) {
k = Math.floor(((n + 1) / 2))
} else {
k = Math.floor(n / 2)
}
if ((n & 1)) {
f[n] = (fib(k) * fib(k) + fib(k-1) * fib(k-1))
} else {
f[n] = (2*fib(k-1) + fib(k))*fib(k)
}
return f[n]
}
console.log(fib(9))
That obviously doesn't work. In Javascript this ends up in an infinite loops. So how would you solve this using Javascript?
Thanks in advance
you can iterate from bottom to top (like tail recursion):
var fib_tail = function(n){
if(n == 0)
return 0;
if(n == 1 || n == 2)
return 1;
var prev_1 = 1, prev_2 = 1, current;
// O(n)
for(var i = 3; i <= n; i++)
{
current = prev_1 + prev_2;
prev_1 = prev_2;
prev_2 = current;
}
return current;
}
console.log(fib_tail(1000))
The problem is related to scope of the k variable. It must be inside of the function:
const fib = (n) => {
let k;
You can find far more good implementations here list
DEMO
fibonacci number in O(n) time and O(1) space complexity:
function fib(n) {
let prev = 0, next =1;
if(n < 0)
throw 'not a valid value';
if(n === prev || n === next)
return n;
while(n >= 2) {
[prev, next] = [next, prev+next];
n--;
}
return next;
}
Just use two variables and a loop that counts down the number provided.
function fib(n){
let [a, b] = [0, 1];
while (--n > 0) {
[a, b] = [b, a+b];
}
return b;
}
console.log(fib(10));
Here's a simpler way to go about it, using either iterative or recursive methods:
function FibSmartRecursive(n, a = 0, b = 1) {
return n > 1 ? FibSmartRecursive(n-1, b, a+b) : a;
}
function FibIterative(n) {
if (n < 2)
return n;
var a = 0, b = 1, c = 1;
while (--n > 1) {
a = b;
b = c;
c = a + b;
}
return c;
}
function FibMemoization(n, seenIt = {}) {//could use [] as well here
if (n < 2)
return n;
if (seenIt[n])
return seenIt[n];
return seenIt[n] = FibMemoization(n-1, seenIt) + FibMemoization(n-2, seenIt);
}
console.log(FibMemoization(25)); //75025
console.log(FibIterative(25)); //75025
console.log(FibSmartRecursive(25)); //75025
You can solve this problem without recursion using loops, runtime O(n):
function nthFibo(n) {
// Return the n-th number in the Fibonacci Sequence
const fibSeq = [0, 1]
if (n < 3) return seq[n - 1]
let i = 1
while (i < n - 1) {
seq.push(seq[i - 1] + seq[i])
i += 1
}
return seq.slice(-1)[0]
}
// Using Recursion
const fib = (n) => {
if (n <= 2) return 1;
return fib(n - 1) + fib(n - 2);
}
console.log(fib(4)) // 3
console.log(fib(10)) // 55
console.log(fib(28)) // 317811
console.log(fib(35)) // 9227465
https://www.codewars.com/kata/is-my-friend-cheating/train/javascript
My goal is to devise a function that finds number pairs (a, b) which satisfy the equation a * b == sum(1, 2, 3 ..., n-2, n-1, n) - a - b.
The following code finds all the pairs, but is too slow and times out. I have seen in the comments for this challenge that the algorithm needs to have O(n) complexity to pass. How is this done?
function removeNb (n) {
if(n===1) return null;
let sum = (n * (n+1))/2;
let retArr = [];
let a = n;
while( a !== 0){
let b = n;
while( b !== 0){
if(b != a && a*b == ((sum - b) - a) ){
retArr.push([a,b]);
}
b--;
}
a--;
}
retArr.sort( (a,b) => a[0] - b[0]);
return retArr;
}
Thanks to all for the assistance! Here is my final solution:
function removeNb (n) {
let retArr = [];
let a = 1;
let b = 0;
let sumN = (n * (n+1))/2;
while( a <= n){
b = parseInt((sumN - a) / (a + 1));
if( b < n && a*b == ((sumN - b) - a) )
retArr.push([a,b]);
a++;
}
return retArr;
}
I think my main issue was an (embarrassing) error with my algebra when I attempted to solve for b. Here are the proper steps for anyone wondering:
a*b = sum(1 to n) - a - b
ab + b = sumN - a
b(a + 1) = sumN - a
b = (sumN - a) / (a + 1)
You can solve for b and get: b = (sum - a)/(a + 1) (given a != -1)
Now iterate over a once -> O(n)
let n = 100;
let sumOfNum = n => {
return (n * (n + 1)) / 2;
};
let sum = sumOfNum(n);
let response = [];
for (let i = 1; i <= 26; i++) {
let s = (sum - i) / (i + 1);
if (s % 1 == 0 && s * i == sum - s - i && s <= n) {
response.push([s, i]);
}
}
// this is O(N) time complexity
Here's an implementation:
function removeNb(n){
var sum = (1 + n) * n / 2;
var candidates = [];
// O(n)
for(var y = n; y >= 1; y--){
x = (-y + sum) / (y + 1);
/*
* Since there are infinite real solutions,
* we only record the integer solutions that
* are 1 <= x <= n.
*/
if(x % 1 == 0 && 1 <= x && x <= n)
// Assuming .push is O(1)
candidates.push([x, y]);
}
// Output is guaranteed to be sorted because
// y is iterated from large to small.
return candidates;
}
console.log(removeNb(26));
console.log(removeNb(100));
https://jsfiddle.net/DerekL/anx2ox49/
From your question, it also states that
Within that sequence, he chooses two numbers, a and b.
However it does not mention that a and b are unique numbers, so a check is not included in the code.
As explained in other answers, it is possible to make a O(n) algorithm solving for b. Moreover, given the symmetry of solution -- if (a,b) is a solution, also (b,a) is -- it is also possible to save some iterations adding a couple of solutions at a time. To know how many iterations are required, let us note that b > a if and only if a < -1+sqrt(1+sum). To prove it:
(sum-a)/(a+1) > a ; sum-a > a^2+a ; sum > a^2+2a ; a^2+2a-sum < 0 ; a_1 < a < a_2
where a_1 and a_2 comes from 2-degree equation solution:
a_1 = -1-sqrt(1+sum) ; a_2 = -1+sqrt(1+sum)
Since a_1 < 0 and a > 0, finally we proved that b > a if and only if a < a_2.
Therefore we can avoid iterations after -1+sqrt(1+sum).
A working example:
function removeNb (n) {
if(n===1) return null;
let sum = (n * (n+1))/2;
let retArr = [];
for(let a=1;a<Math.round(Math.sqrt(1+sum));++a) {
if((sum-a)%(a+1)===0) {
let b=(sum-a)/(a+1);
if(a!==b && b<=n) retArr.push([a,b],[b,a]);
}
}
retArr.sort( (a,b) => a[0] - b[0]);
return retArr;
}
However, with this implementation we still need the final sort. To avoid it, we can note that b=(sum-a)/(a+1) is a decreasing function of a (derive it to prove). Therefore we can build retArr concatenating two arrays, one adding elements to the end (push), one adding elements at the beginning (unshift). A working example follows:
function removeNb (n) {
if(n===1) return null;
let sum = (n * (n+1))/2;
let retArr = [];
let retArr2 = [];
for(let a=1;a<Math.round(Math.sqrt(1+sum));++a) {
if((sum-a)%(a+1)===0) {
let b=(sum-a)/(a+1);
if(a!==b && b<=n) {
retArr.push([a,b]);
retArr2.unshift([b,a]); // b>a and b decreases with a
}
}
}
retArr=retArr.concat(retArr2); // the final array is ordered in the 1st component
return retArr;
}
As a non-native speaker, I would say that the phrase from the reference "all (a, b) which are the possible removed numbers in the sequence 1 to n" implies a!=b,
so I added this constraint.
for this program, i need the user to enter 20 numbers and for the highest to be displayed. i have done a similar one with 4, which i will display below, however there must be an easier way that going through it all? any advice would be great.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function maxNum(num1, num2, num3, num4){
var max = 0;
if((num1 >= num2) && (num1 >= num3)){
max = num1;
}
else if((num2 >= num1) && (num2 >= num3) && (num3 >= num4)){
max = num2;
}
else if((num3 >= num1) && (num3 >= num2) && (num3 >= num4)){
max = num3;
}
else{
max = num4;
}
return max;
}
var arr = [];
for(i=0;i<4;i++){
arr[i] = parseInt(prompt("Enter a number"));
}
document.write(maxNum.apply(this, arr));
</script>
</body>
</html>
function findMaxNum(arr) {
return Math.max.apply(null, arr);
}
var arr = [];
for (var i = 0; i < 4; i++) {
arr[i] = parseInt(prompt('Enter a number'), 10);
}
var maxNum = findMaxNum(arr);
Math.max usually works with a series of numbers: Math.max(1, 4, 10) // 10, but here we use apply on the function so that it accepts an array instead.
(Note, added the radix for parseInt)
DEMO
Assuming that all values passed into your function will be numbers you can use Math.max with the arguments special variable.
function getMax()
{
if (Object.prototype.toString.call(arguments[0]) === '[object Array]') {
return Math.max.apply(null, arguments[0]);
}
return Math.max.apply(null, arguments);
}
var myArr = [2,4,6,8,10,12,14,16,18,20];
getMax(1,2,4,5,6,7,8,10); // 10
getMax(myArr); // 20
The example above allows an array or a list of arguments to be passed through. This allows you to reuse where required.
Yes, with Math.max.apply. It takes an object (null) and an array with the values.
function getMax(array) {
var i,
max = +array[0]; // the first element with implicit casting to number
for (i = 1; i < array.length; i++) { // loop throu all elements
if (+array[i] > max) { // with cast to number
max = array[i];
}
}
return max;
}
var userInput = ['1', 'a', '4', '-', '1000', '20'].filter(Number);
document.write(userInput + '<br>');
document.write(Math.max.apply(null, userInput) + '<br>');
document.write(getMax(userInput) + '<br>');
I'm new to javascript and I'm having a hard time figuring out how to get this factorial function to work. Here's my code now.
var x = prompt("Enter a number"); {
function fact(x) {
if (x < 0) {
return ("Enter a positive integer");
}
else {
return (x * fact(x-1))
}
}
}
var result = fact(x)
document.write("The factorial of" + x + "is" + result);
Thanks for the help!
your base case is wrong for a recursive factorial. change it to
function fact(x) {
if (x <= 1) {
return 1
}
else {
return (x * fact(x-1))
}
}
Your definition of factorial is wrong. The traditional recursive definition of factorial is:
F(x) => x == 1 ? 1 : x * F(x-1)
Or you can use the iterative definition
F(x) => var i = 1; for (j = 1..x) i = i * j
In javascript, the recursive version would be:
function factorial (x) {
if (x == 1) return x;
return x * factorial(x-1);
}
The iterative version would be:
function factorial (x) {
var result = 1;
for (var y = 1; y <= x; y++) {
result = result * y;
}
return result;
}
You can add the negative number check in the above functions. But in my opinion that would obscure the purpose of the function (which is to implement the traditional definition of factorial). A better approach is to move the negative number if() check outside of the factorial function. The if (x < 0) check has its own purpose that is separate from calculating factorials: input validation.
In every recursive function, there exists a stopping condition (in your case its if(x<=1)) without which, the function would go to infinite recursion. You had not added that stopping condition. Following is the working updated program:
var x = prompt("Enter a number"); {
function fact(x) {
if (x < 0) {
return ("Enter a positive integer");
}
else if(x <=1){
return 1;
}
else {
return (x * fact(x-1))
}
}
}
var result = fact(x)
document.write("The factorial of " + x + " is " + result);
In addition to fixing the flawed algorithm, I recommend moving your prompt into its own function for separation of concerns.
I also like the idea of using a while statement for this as well as doing a parseInt on the input:
function fact(x) {
while (x > 1) {
return (x * fact(x-1));
}
return x;
}
function doFact() {
var x = parseInt(prompt("Enter a positive integer"));
if (x < 1) {
doFact();
} else {
var result = fact(x);
alert("The factorial of " + x + " is " + result);
}
}
doFact();
I've just began Javascript in college. One task is to define and call a function to find the maximum number from 3 numbers entered by the user. I know there is a max() function but we were told to do it manually using if and else if.
I'm going wrong somewhere as you can see. It's just telling me the max is 0 everytime.
function maxNum(num1, num2, num3){
var max = 0;
if(num1 > num2){
if(num1 > num3){
num1 = max;
}
else{
num3 = max;
}
}
else{
if(num2 > num3){
num2 = max;
}
}
return max;
}
for(i=0;i<3;i++){
parseInt(prompt("Enter a number"));
}
document.write(maxNum());
Or you can use ES6 syntax, to compute largest of three numbers in easier way,
const largest = a => F = b => G = c => ((a > b && a > c) ? a : (b > a && b > c) ? b : c)
console.time()
console.log(largest(53)(30907)(23333))
console.timeEnd()
One problem you have is that you do not save the number the user inputs. You prompt them, parse it as an int and then nothing. You have to pass the 3 numbers into maxNum()
Here is a working example that uses proper left hand assignment and saves the number. Also it is a good idea to use >= instead of > because the user can enter 2 of the same number
function maxNum(num1, num2, num3){
var max = 0;
if((num1 >= num2) && (num1 >= num3)){
max = num1;
}
else if((num2 >= num1) && (num2 >= num3)){
max = num2;
}
else{
max = num3;
}
return max;
}
var arr = [];
for(i=0;i<3;i++){
arr[i] = parseInt(prompt("Enter a number"));
}
document.write(maxNum.apply(this, arr));
easiest way:
function maxNum(num1, num2, num3){
var tmp = 0;
if(num1 < num2 && num3 < num2) {
tmp = num2;
} else if(num3 < num1){
tmp = num1;
} else {
tmp = num3;
}
return tmp;
}
var arr = [];
for(var i = 0; i < 3; i++) {
arr[i] = prompt("Enter a number");
}
console.log(maxNum.apply(this, arr));
First in javascript and most modern programming language assignment like a = b copies the value of b into the variable a. It is not equivalent to b = a (which copies the value of a into the variable b). It's common to write a = 1, but a syntax error in most languages to write 1 = a. Thus, you don't want to write num1 = max, but instead write max = num1.
Second, your logic is incorrect as it won't treat the case maxNum(1,2,3) correctly. (Work through the logic when num1 < num2 and num2 < num3. The following code would work:
function maxNum(num1, num2, num3){
var max = 0;
if(num1 > num2){
if(num1 > num3){
max = num1;
}
else{
max = num3;
}
}
else{
if(num2 > num3){
max = num2;
} else {
max = num3;
}
}
return max;
}
Granted, I would probably write something like
function max3num(num1, num2, num3) {
var max_so_far = num1;
if (num2 > max_so_far) {
max_so_far = num2;
}
if (num3 > max_so_far) {
max_so_far = num3;
}
return max_so_far;
}
as the logic is very clear and it will be easy to extend to a max function with a larger number of elements to compare if necessary. (Adding in a for loop could make it variadic fairly easily). It is straightforward to see the logic works, because we start with the first element being the maximum so far (max_so_far), then consider if the second element is larger -- if so we assign that as max_so_far, and keep continuing until we have compared all the elements to the max_so_far. After we have considered each element once, we then return the max_so_far which will now be the maximum of all of them.
No real need for a function here, just compare them as the come in!
var max = 0;
for(var i=0;i<3;i++){
var val = parseInt(prompt("Enter a number"));
max = max > val ? max : val;
}
alert(max);
The updated direct answer is this :
function maxNum(num1, num2, num3){
return [num1, num2, num3].sort(function (a, b) { return b - a })[0];
}
If written like this, it can easily be modified to take any amount of numbers by passing it an array of said numbers.
var numArray = [num1, num2, num3, num4, ...];
function maxNum(numArray){
return numArray.sort(function (a, b) { return b - a })[0];
}
The details :
Take an array :
[5,42,16]
Now sort it.
[5,42,16].sort()
But this wont work because javascript .sort requires a function to be passed in. This function tells it how to sort the array.
This will sort it highest to lowest, e.g. a is less then b.
function (a, b) { return b - a }
This will sort it lowest to highest, e.g. b is less then a.
function (a, b) { return a - b }
So we add it in :
[5,42,16].sort(function (a, b) { return b - a })
But this returns the sorted array, not the maximum number.
So we pick the first element in the array :
[5,42,16].sort(function (a, b) { return b - a })[0]
Lastly, you can pull out the sort function. This is mostly for demo purposes though.
var maxSorter = function (a, b) { return b - a };
function maxNum(numArray){
return numArray.sort(maxSorter)[0];
}
//Raihan
// program to find the largest among three numbers
// take input from the user using Prompt
let num1 = parseFloat(prompt("Enter first number: "));
let num2 = parseFloat(prompt("Enter second number: "));
let num3 = parseFloat(prompt("Enter third number: "));
let largest = Math.max(num1, num2, num3);
// display the result
document.write("The largest number is " + largest);
**//another way**
const num1 = parseFloat(prompt("Enter first number: "));
const num2 = parseFloat(prompt("Enter second number: "));
const num3 = parseFloat(prompt("Enter third number: "));
// check the condition
if(num1 >= num2 && num1 >= num3) {
document.write("Largest Number : " + num1)
}
else if (num2 >= num1 && num2 >= num3) {
document.write("Largest Number : " + num2)
}
else {
document.write("Largest Number : " + num3)
}