Is there an efficient way to check if number belongs to Fibonacci sequence?
I've seen many examples with a loop that creates the sequence in an array and checks every time if newly generated number of the sequence is equal to the input number. Is there another way?
http://www.geeksforgeeks.org/check-number-fibonacci-number/
This link details that there is a special quality about fibonacci numbers that means that a number is Fibonacci if and only if one or both of (5*n2 + 4) or (5*n2 – 4) is a perfect square.
So,
function (num) {
if (isSquare(5*(num*num)-4) || isSquare(5*(num*num)+4)) {
return true;
} else { return false; }
}
Then isSquare would just be a simple checking function.
Edit: Worth noting that while this is a much more efficient and easy way to find fibonacci numbers, it does have an upper bound. At about the 70th Fibonacci number and above, you may see issues because the numbers are too large.
function isFibonacci(num, a = 0, b = 1) {
if(num === 0 || num === 1) {
return true;
}
let nextNumber = a+b;
if(nextNumber === num) {
return true;
}
else if(nextNumber > num) {
return false;
}
return isFibonacci(num, b, nextNumber);
}
function isPerfectSquare(n) {
return n > 0 && Math.sqrt(n) % 1 === 0;
};
//Equation modified from http://www.geeksforgeeks.org/check-number-fibonacci-number/
function isFibonacci(numberToCheck)
{
// numberToCheck is Fibinacci if one of 5*n*n + 4 or 5*n*n - 4 or both
// is a perferct square
return isPerfectSquare(5*numberToCheck*numberToCheck + 4) ||
isPerfectSquare(5*numberToCheck*numberToCheck - 4);
}
for(var i = 0; i<= 10000; ++i) {
console.log(i + " - " + isFibonacci(i));
}
This will most likely fail for larger numbers though.
def is_squared(number):
temp_root = math.sqrt(number);
temp_root = int(temp_root);
return (temp_root * temp_root == number);
def check_all_fibo(test_number_list):
result_fibo_list = [];
for item in test_number_list:
if item==0 or item == 1 or item == 2:
result_fibo_list.append(item);
continue;
if is_squared(5 * item * item - 4) or is_squared(5 * item * item + 4):
result_fibo_list.append(item);
return result_fibo_list;
this is a python implementation by me. But keep in mind, the formula only works when the fib is not too large.
The Fibonacci sequence is a series of numbers where a number is the addition of the last two numbers, starting with 0, and 1. Th following js function is explaining this.
function isFabonacci(n) {
if (n === 1 || n === 0) {
return true;
}
let firstPrevNumber = n - 1;
let secondPrevNumber = n - 2;
return (firstPrevNumber + secondPrevNumber === n);
}
// isFabonacci(2) -> false
// isFabonacci(3) -> true
Related
I need some help with a task which is about creating a function that only accepts integer numbers to then multiply each other until getting only one digit. The answer would be the times:
Example: function(39) - answer: 3
Because 3 * 9 = 27, 2 * 7 = 14, 1 * 4 = 4 and 4 has only one digit
Example2: function(999) - answer: 4
Because 9 * 9 * 9 = 729, 7 * 2 * 9 = 126, 1 * 2 * 6 = 12, and finally 1 * 2 = 2
Example3: function(4) - answer: 0
Because it has one digit already
So trying to figure out how to solve this after many failures, I ended up coding this:
function persistence(num) {
let div = parseInt(num.toString().split(""));
let t = 0;
if(Number.isInteger(num) == true){
if(div.length > 1){
for(let i=0; i<div.length; i++){
div = div.reduce((acc,number) => acc * number);
t += 1;
div = parseInt(div.toString().split(""))
if(div.length == 1){
return t } else {continue}
} return t
} else { return t }
} else { return false }
}
console.log(persistence(39),3);
console.log(persistence(4),0);
console.log(persistence(25),2);
console.log(persistence(999),4);
/*
output: 0 3
0 0
0 2
0 4
*/
It seems I could solve it, but the problem is I don't know why those 0s show up. Besides I'd like to receive some feedback and if it's possible to improve those codes or show another way to solve it.
Thanks for taking your time to read this.
///EDIT///
Thank you all for helping and teaching me new things, I could solve this problem with the following code:
function persistence(num){
let t = 0;
let div;
if(Number.isInteger(num) == true){
while(num >= 10){
div = (num + "").split("");
num = div.reduce((acc,val) => acc * val);
t+=1;
} return t
}
}
console.log(persistence(39));
console.log(persistence(4));
console.log(persistence(25));
console.log(persistence(999));
/*output: 3
0
2
4
*/
You've got a few issues here:
let div = parseInt(num.toString().split("")); You're casting an array to a number, assuming you're trying to extract the individual numbers into an array, you were close but no need for the parseInt.
function persistence(input, count = 0) {
var output = input;
while (output >= 10) {
var numbers = (output + '').split('');
output = numbers.reduce((acc, next) {
return Number(next) * acc;
}, 1);
count += 1;
}
return count;
};
For something that needs to continually check, you're better off using a recurssive function to check the conditions again and again, this way you won't need any sub loops.
Few es6 features you can utilise here to achieve the same result! Might be a little too far down the road for you to jump into es6 now but here's an example anyways using recursion!
function recursive(input, count = 0) {
// convert the number into an array for each number
const numbers = `${input}`.split('').map(n => Number(n));
// calculate the total of the values
const total = numbers.reduce((acc, next) => next * acc, 1);
// if there's more than 1 number left, total them up and send them back through
return numbers.length > 1 ? recursive(total, count += 1) : count;
};
console.log(recursive(39),3);
console.log(recursive(4),0);
console.log(recursive(25),2);
console.log(recursive(999),4);
function persistance (num) {
if (typeof num != 'number') throw 'isnt a number'
let persist = 0
while(num >= 10) {
let size = '' + num
size = size.length
// Get all number of num
const array = new Array(size).fill(0).map((x, i) => {
const a = num / Math.pow(10, i)
const b = parseInt(a, 10)
return b % 10
})
console.log('here', array)
// actualiser num
num = array.reduce((acc, current) => acc * current, 1)
persist++
}
return persist
}
console.log(persistance(39))
console.log(persistance(999))
console.log() can take many argument...
So for example, console.log("A", "B") will output "A" "B".
So all those zeros are the output of your persistence function... And the other number is just the number you provided as second argument.
So I guess you still have to "persist"... Because your function always returns 0.
A hint: You are making this comparison: div.length > 1...
But div is NOT an array... It is a number, stringified, splitted... And finally parsed as integer.
;) Good luck.
Side note, the calculation you are attempting is known as the Kaprekar's routine. So while learning JS with it... That history panel of the recreational mathematic wil not hurt you... And may be a good line in a job interview. ;)
My best hint
Use the console log within the function to help you degug it. Here is your unchanged code with just a couple of those.
function persistence(num) {
let div = parseInt(num.toString().split(""));
let t = 0;
console.log("div.length", div.length)
if (Number.isInteger(num) == true) {
if (div.length > 1) {
for (let i = 0; i < div.length; i++) {
div = div.reduce((acc, number) => acc * number);
t += 1;
div = parseInt(div.toString().split(""));
if (div.length == 1) {
console.log("return #1")
return t;
} else {
continue;
}
}
console.log("return #2")
return t;
} else {
console.log("return #3")
return t;
}
} else {
console.log("return #4")
return false;
}
}
console.log(persistence(39), 3);
console.log(persistence(4), 0);
console.log(persistence(25), 2);
console.log(persistence(999), 4);
I want to write a function that finds the next largest palindrome for a given positive integer. For example:
Input: 2
Output: 3 (every single digit integer is a palindrome)
Input: 180
Output: 181
Input: 17
Output: 22
My try
function nextPalindrome(num) {
let input = num;
let numToStringArray = input.toString().split('');
let reversedArray = numToStringArray.reverse();
if (numToStringArray.length < 2) {
return Number(numToStringArray) + 1;
} else {
while (numToStringArray !== reversedArray) {
// numToStringArray = num.toString().split('');
// reversedArray = numToStringArray.reverse();
num += 1;
}
return numToStringArray.join('');
}
}
As a beginner, I thought that the numToStringArray would constantly increment by 1 and check for whether the while-statement is true.
Unfortunately it doesn't. I commented out two lines in the while-statement because they seemed somewhat redundant to me. Thanks to everyone reading or even helping me out!
The reason your code doesn't work is because you don't have any code updating the conditions of your while loop. So if you enter it once, it will loop indefinitely. You need to do something inside of the while loop that might make the condition false the next time through the loop, like so:
function getReverse(num) {
// get the reverse of the number (in positive number form)
let reversedNum = +Math.abs(num).toString().split("").reverse().join("");
// keep negative numbers negative
if (num < 0) { reversedNum *= -1; }
return reversedNum;
}
function nextPalindrome(num) {
// if single digit, simply return the next highest integer
if (num >= -10 && num < 9) {
return num+1;
}
else {
while(num !== getReverse(num)) {
num += 1;
}
return num;
}
}
console.log(nextPalindrome(3));
console.log(nextPalindrome(17));
console.log(nextPalindrome(72));
console.log(nextPalindrome(180));
console.log(nextPalindrome(1005));
console.log(nextPalindrome(-150));
console.log(nextPalindrome(-10));
You could also solve this pretty cleanly using recursion, like so:
function getReverse(num) {
// get the reverse of the number (in positive number form)
let reversedNum = +Math.abs(num).toString().split("").reverse().join("");
// keep negative numbers negative
if (num < 0) { reversedNum *= -1; }
return reversedNum;
}
function nextPalindrome(num) {
// if single digit, simply return the next highest integer
if (num >= -10 && num < 9) {
return num+1;
}
else if(num === getReverse(num)) {
return num;
}
else {
// if not the same, recurse with n + 1
return nextPalindrome(num + 1)
}
}
console.log(nextPalindrome(3));
console.log(nextPalindrome(17));
console.log(nextPalindrome(72));
console.log(nextPalindrome(180));
console.log(nextPalindrome(1005));
console.log(nextPalindrome(-150));
console.log(nextPalindrome(-10));
Background - I took an online coding test and was presented with questions similar to this, I did rather poorly on it compared to the hidden grading criteria and I was hoping to get another pair of eyes to look at it and maybe help point out some of my mistakes.
Practice Test questions -
Task: Given an integer inject the number 5 into it to make the largest possible integer
Conditions: (-80000...80000) range needed to handle
Expected input: int
Expected output: int
Testcase: -999 -> -5999
80 -> 850
var lrgInt = function(num) {
var stringInt = num.toString();
for (let i = 0; i < stringInt.length; i++) {
if (stringInt.charAt(i) === "-") {
return parseInt([stringInt.slice(0, 1), '5', stringInt.slice(1)].join(''));
}else if (stringInt.charAt(i) < 5) {
return parseInt([stringInt.slice(0, i), '5', stringInt.slice(i)].join(''));
}
}
return parseInt([stringInt.slice(0, stringInt.length), '5', stringInt.slice(stringInt.length)].join(''));
};
Task: Determine the number of operations done on a number following the conditions to reduce it to 0.
Conditions:
- If the number is odd, subtract 1
- If the number is even, divide by 2
Expected input: int
Expected output: int
var operations = 0;
var numberOfSteps = function(num) {
if (num === 0){
return operations;
}else if (num % 2 == 0) {
operations++;
return numberOfSteps(num/2);
} else {
operations++;
return numberOfSteps(num-1);
}
};
For the second question, you could add one plus the result of recursion with the adjusted number without having a global counter.
function numberOfSteps(number) {
if (!number) return 0;
if (number % 2) return 1 + numberOfSteps(number - 1);
return 1 + numberOfSteps(number / 2);
}
console.log(numberOfSteps(5)); // 5 4 2 1 0
For the first question, we make the observation that if the number is positive, we want to inject the 5 before the first digit less than 5, but if it's negative then we want to inject it before the first digit greater than 5. For the second problem, we can just use a simple while loop.
function largestNum(num) {
if (num == 0) {
// this edge case is weird but I'm assuming this is what they want
return 50;
}
var negative = num < 0;
var numAsStr = Math.abs(num).toString();
var inj = -1;
for (var i = 0; i < numAsStr.length; i++) {
var cur = parseInt(numAsStr[i], 10);
if ((!negative && cur < 5) || (negative && cur > 5)) {
// we found a place to inject, break
inj = i;
break;
}
}
if (inj == -1) {
// didn't inject anywhere so inject at the end
inj = numAsStr.length;
}
return (
(negative ? -1 : 1) *
parseInt(numAsStr.substr(0, inj) + "5" + numAsStr.substr(inj))
);
}
function numSteps(num) {
var steps = 0;
while (num != 0) {
if (num % 2) {
// it's odd
num--;
} else {
num /= 2;
}
steps++;
}
return steps;
}
This is a function to display the sum of the input digits with iteration perspective:
function sumOfDigits(number) {
let strNumber = number.toString()
let output = 0;
for(i=0;i<strNumber.length;i++){
let tmp = parseInt(strNumber[i])
output = output + tmp
}
return output
}
// TEST CASES
console.log(sumOfDigits(512)); // 8
console.log(sumOfDigits(1542)); // 12
console.log(sumOfDigits(5)); // 5
console.log(sumOfDigits(21)); // 3
console.log(sumOfDigits(11111)); // 5
I am wondering how we write this function in a recursive way?
Using the modulo operator, you can get the remainder (which in the case of a divison by 10, is the last number) and then add the next iteration.
function sumOfDigits (n) {
if (n === 0) return 0
return (n % 10 + sumOfDigits(Math.floor(n / 10)))
}
console.log(sumOfDigits(512))
If you want to see a more detailed explanation, check https://www.geeksforgeeks.org/sum-digit-number-using-recursion/
I have not tested it, but you can try the following without casting to string
function sumOfDigits(number)
{
if (number === 0) {
return 0;
}
return (number % 10 + sumOfDigits(Math.floor(number / 10)));
}
Make sure that the input is indeed in number format
Here you go
function sumOfDigitsRecursive(number){
let strNumber = number.toString()
if(strNumber.length<=0)
return 0
return parseInt(strNumber[0])+sumOfDigitsRecursive(strNumber.slice(1,strNumber.length))
}
I want to sum even numbers from 1-100 using javascript recursive function, but the output just show me 0 for odd numbers and the number itself for odd numbers
function evenSum(n) {
if (n%2 === 1) {
return 0;
}
else if (n === 100) {
return 100;
}
return n + evenSum(n+1);
}
if (n%2 === 1) {
return 0;
}
That will stop the recursive chain at every second number. For every odd number it will stop directly (and return 0) for every even number it will stop at the second position. Instead, you just want the recursion to continue with the next chain:
if (n%2 === 1) {
return evenSum(n + 1);
}
Actually you can simplify (and speed up the code) if you just go to every second position:
function evenSum(n){
// Stop at 100
if(n >= 100) return 100;
// If it starts at an odd position, go on with the next even
if(n % 2 === 1) return evenSum(n + 1);
// Usually just take every second step:
return n + evenSum(n + 2);
}
That can be shortified to:
const evenSum = n => n >= 100 ? 100 : n % 2 ? evenSum(n + 1) : n + evenSum(n + 2);
You could use a recursion function which count down the values until you reach zero.
The exit condition is a check if the number is smaller or equal to zero, then return the sum otherwise decrement uneven value by one and even value by two and call the function again with the value and temporary sum.
function evenSum(n, s = 0) {
if (n <= 0) {
return s;
}
return evenSum(n - (n % 2 ? 1 : 2), s + n); // tail recursion
}
console.log(evenSum(100));
function evenSum(n) {
if (n <= 1)
return 0;
else
{
if(n%2 === 1)
return evenSum(n - 1);
else
return n + evenSum(n - 1);
}
}
Something like that (works for all numbers, not just 100):
function evenSum(n) {
if (n == 0) return 0; // recursive function needs to stop somewhere
var sum = evenSum(n - 1); // recursive call
if (n % 2 == 0) sum += n; // add current n if it's even
return sum; // return result
}
console.log(evenSum(100));
recursive sum of even number
one line condition
function addOddToN(n) {
return (n <= 2) ? 2 : (n%2 === 0) ? n + addOddToN(n - 1) : addOddToN(n - 1);
}
console.log( addOddToN(100) ); // 2550
console.log( addOddToN(5) ); // 6
console.log( addOddToN(4) ); // 6
console.log( addOddToN(10) ); // 30