Finding Fibonacci bugs keep returning undefined - javascript

I am trying to solve the fibonacci in recrusive way and I think i got a bug in my code.I can't figurer out where it is.
Example:
fib(4) === 3
function fib(n, array = [0, 1], count = 0) {
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
}
array.push(array[count] + array[count + 1]);
console.log(array)
if (n === array.length-1) {
return array.pop()
}
fib(n, array, count + 1);
}
let ans=fib(2)
console.log(ans)

you can do by this way using recursion
var i = 0, a = 0, b = 1, c = 0;
var out = "";
function fibonacci(n){
i = 0;
if(i < n){
out += a + ",";
c = a + b;
a = b;
b = c;
i++;
console.log(out);
fibonacci(n - i);
}
}
fibonacci(10);

Related

How to make this fib sequence faster?

var fibonacci = function(n) {
let cache = {};
let value;
if (n in cache) {
value = cache[n];
} else {
if (n == 0 || n == 1) {
value = n;
} else {
value = fibonacci(n - 1) + fibonacci(n - 2);
cache[n] = value;
}enter code here
}
return value;
};
fibonacci(60)
codewar wont accept this fib sequence its too slow how to make it faster
Put the cache outside of the function, otherwise it won't do anything (subsequent calls of fibonacci, including the recursive calls, won't be able to see prior cached numbers):
let cache = {};
var fibonacci = function(n) {
let value;
if (n in cache) {
value = cache[n];
} else {
if (n == 0 || n == 1) {
value = n;
} else {
value = fibonacci(n - 1) + fibonacci(n - 2);
cache[n] = value;
}
}
return value;
};
console.log(fibonacci(60))
To clean up the code some more, you can immediately return instead, to cut down on indentation and to avoid unnecessary reassignment:
const cache = {};
const fibonacci = function(n) {
if (n in cache) {
return cache[n];
}
if (n <= 1) {
return n;
}
const value = fibonacci(n - 1) + fibonacci(n - 2);
cache[n] = value;
return value;
};
console.log(fibonacci(60))
Keep in mind that this fibonacci will still only be accurate up to a certain point. Once the return value is larger than Number.MAX_SAFE_INTEGER (9007199254740991), it will be inaccurate. If that's a possibility, use and return BigInts instead.
Using two recursion results in very bad perofrmance (good for understanding recursion). You need to use loops and array beside memoization for good performance. After all heavy computation blocks main thread in JavaScript hence not a good choice for heavy computation applications.
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...
const cache = [1, 1]
function fibonacci(n) {
if (n <= cache.length) {
return cache[n - 1]
}
for (let i = cache.length; i < n; i++) {
cache[i] = cache[i - 1] + cache[i - 2]
}
return cache[n - 1]
}
To avoid using global you can use closure:
function fibonacci(m) {
const cache = [1, 1]
return (function (n) {
if (n <= cache.length) {
return cache[n - 1]
}
for (let i = cache.length; i < n; i++) {
cache[i] = cache[i - 1] + cache[i - 2]
}
return cache[n - 1]
})(m)
}
This is an example of dynamic programming using recursion and memoization.
Using a loop instead of recursion is faster, and if you use array destructuring it's more readable.
a = fn-1 and b = fn-2
function fibonacci(n) {
if (n === 0) return 0;
if (n === 1) return 1;
let [a, b] = [0, 1];
for (var i = 2; i <= n; i++) {
[a, b] = [b, a + b];
}
return b;
}

How to display the numbers in console, without for loop?

the task is to create a recursion, displaying Fibonacci numbers. I need to display the number chain of Fibonacci numbers in the console, without (for) loop.
I have optimised the recursion and displayed the numbers with a (for) loop.
"use strict";
var arr = []
let skkak = function(n)
{
if (n <= 1)
{
return n;
}
if(!isNaN(arr[n])){
return arr[n];
}
else
{
let result = skkak(n - 1) + skkak(n - 2)
arr[n] = result;
return result;
}
}
for(let i=12; i > 0; i--)
{
console.log(skkak(i));
}
no errors
This version is using while (not recursive)
"use strict";
var arr = []
let skkak = function(n)
{
if (n <= 1)
{
return n;
}
if(!isNaN(arr[n])){
return arr[n];
}
else
{
let result = skkak(n - 1) + skkak(n - 2)
arr[n] = result;
return result;
}
}
let i = 12;
while(i > 0)
{
console.log(skkak(i));
i--;
}
Recursive approach
fibonacci = (n) =>
{
if (n===1)
{
return [0, 1];
}
else
{
let s = fibonacci(n - 1);
s.push(s[s.length - 1] + s[s.length - 2]);
return s;
}
};
console.log(fibonacci(5)); // [0,1,1,2,3,5]

heap's algorithm - JavaScript

I have an alright understanding of how Heap's Algorithm works, but I can't figure out how to add each unique permutation into an array and return it based on the recursive nature of the algo.
why is it only adding the same permutation but the console log prints out the different ones?
var swap = function (array, pos1, pos2) {
var temp = array[pos1];
array[pos1] = array[pos2];
array[pos2] = temp;
};
var heapsPermute = function (array, n, results = []) {
n = n || array.length;
if (n === 1) {
results.push(array);
console.log(array);
} else {
for (var i = 1; i <= n; i += 1) {
heapsPermute(array, n - 1, results);
if (n % 2) {
var j = 1;
} else {
var j = i;
}
swap(array, j - 1, n - 1);
}
}
return results;
};
console.log(heapsPermute(['a', 'b', 'c', 'd']));
You need to add a copy of the array, instead of the array and it's object reference.
results.push(array.slice());
// ^^^^^^^^
var swap = function (array, pos1, pos2) {
var temp = array[pos1];
array[pos1] = array[pos2];
array[pos2] = temp;
};
var heapsPermute = function (array, n, results = []) {
n = n || array.length;
if (n === 1) {
results.push(array.slice());
} else {
for (var i = 1; i <= n; i += 1) {
heapsPermute(array, n - 1, results);
if (n % 2) {
var j = 1;
} else {
var j = i;
}
swap(array, j - 1, n - 1);
}
}
return results;
};
console.log(heapsPermute(['a', 'b', 'c', 'd']).map(a => a.join(' ')));
.as-console-wrapper { max-height: 100% !important; top: 0; }

count the type of number in an array - functional javascript

This is a program I came up with that counts the type of numbers i.e whether its positive, negative or zero. Is it possible to write this code in functional javascript using any of array methods like reduce, map, filter? Prefer the output to be in array format.
var array= [-1,1,0,2,3,4,5,6,7,8,9,0];
var positive_count = 0, negative_count = 0;
var zero_count = 0;
for (var i = 0; i < 10; ++i)
{
if (array[i] > 0)
positive_count += 1;
else if(array[i] < 0)
negative_count += 1
else
zero_count+= 1;
}
console.log (positive_count + "," + negative_count+ "," + zero_count);
http://plnkr.co/edit/CpHg1gMX0Oao4PQVd08g?p=preview
You can use reduce to do this:
Working Example
var count = array.reduce(function(a, b){
if (b < 0) {
a.negative = ++a.negative || 1;
}
if (b === 0) {
a.zero = ++a.zero || 1;
}
if (b > 0) {
a.positive = ++a.positive || 1;
}
return a;
}, {});
MDN Docs on reduce
You could also use .filter and get the lengths:
var z = array.filter(function(e) {
return e === 0;
}).length;
var p = array.filter(function(e) {
return e > 0;
}).length;
var n = array.filter(function(e) {
return e < 0;
}).length;
neelmeg. In your script for loop you iterate over the array only while i < 10, but your array contains 12 elements so your result will be wrong.
Yes, it is possible to perform this in a more functional way using reduce ...
const ary = [-1,1,0,2,3,4,5,6,7,8,9,0]
const result = ary.reduce((acc, v) => {
return v > 0
? [(acc[0] + 1), acc[1], acc[2]]
: v < 0
? [acc[0], (acc[1] + 1), acc[2]]
: [acc[0], acc[1], (acc[2] + 1)]
}, [0, 0, 0])
console.log(result)
This will return an array in the form [+ numCount, - numCount, zero count]
=> [ 9, 1, 2 ]

Get smallest and highest number to the right and left to my value

Please let me know if there is a faster, more elegant way to get this result:
I have an array of numbers, and once set a value i should get smallest and highest number to the right and left to my value.
For example if I have: [1,2,3,4,6,7,8,9] and a value is 5,
my numbers will be:1, 4,6,9
if value is 4
my numbers will be 1,4,4,9
My horrible code is:
var arr = [1, 8, 2, 3, 9, 5, 4, 6, 7];
var result1 = [];
var result2 = [];
var goal = 5;
for (a = 0; a < arr.length; a++) {
if (arr[a] < goal) {
result1.push(arr[a])
} else if (arr[a] === goal) {
result1.push(arr[a]);
result2.push(arr[a]);
} else {
result2.push(arr[a]);
}
};
var count1 = result1[0];
for (x = 0; x < result1.length; x++) {
if (result1[x] < count1) {
count1 = result1[x]
}
};
var count11 = result1[0];
for (xx = 0; xx < result1.length; xx++) {
if (result1[xx] > count11) {
count11 = result1[xx]
}
};
var count2 = result2[0];
for (y = 0; y < result2.length; y++) {
if (result2[y] > count2) {
count2 = result2[y]
}
};
var count22 = result2[0];
for (yy = 0; yy < result2.length; yy++) {
if (result2[yy] < count22) {
count22 = result2[yy]
}
};
console.log(count1 + ' ' + count11 + ' ' + count22 + ' ' + count2)
You can simplify your code a lot by using a few mighty methods: Array::filter and Math.min/max:
var arr = [1, 8, 2, 3, 9, 5, 4, 6, 7];
var goal = 5;
var result1 = arr.filter(function(x) { return x <= goal });
var result2 = arr.filter(function(x) { return x >= goal });
var count1 = Math.min.apply(Math, result1);
var count11 = Math.max.apply(Math, result1);
var count2 = Math.min.apply(Math, result2);
var count22 = Math.max.apply(Math, result2);
Assuming the array is sorted always,
var array = [1, 2, 3, 4, 6, 7, 8, 9],
number = 5,
pivot, small, large;
for (var i = 0, len = array.length; i < len; i += 1) {
if (array[i] >= number) {
pivot = i;
break;
}
}
if (pivot > 0) {
small = [array[0], array[pivot - 1]];
large = [array[pivot], array[len - 1]];
console.log(small, large);
} else {
console.log("Not possible");
}
Well I came up with the following solution. Considering that array is always sorted
function GetVals(arr, pivot){
return arr.reduce(function(t,v,i,arr){
if (v < pivot) {
if (typeof t.LMin == "undefined" || t.LMin > v)
t.LMin = v;
if (typeof t.LMax == "undefined" || t.LMax < v)
t.LMax = v;
} else if (v > pivot) {
if (typeof t.RMin == "undefined" || t.RMin > v)
t.RMin = v;
if (typeof t.RMax == "undefined" || t.RMax < v)
t.RMax = v;
}
return t;
}, {});
}
The returned result will have 4 properties, LMin LMax for left min and max and RMin RMax for right min maxes respectively.
if LMin and LMax are equal, this means there is only 1 value from the left (the same rule for the right)
if LMin and LMax are undefined, this means that there are no values from the left less than pivot.
EDIT
Although I realize the question has been answered and another response selected, I at least wanted to update my code to a tested version. FWIW, it works, and does not rely on nor assume a sorted array.
function minmax(valueArray, targetValue) {
var i = 0;
var minBelow;
var maxBelow;
var minAbove;
var maxAbove;
while (i < valueArray.length) {
var currentValue = valueArray[i];
if (currentValue < targetValue) {
if (currentValue < minBelow || !minBelow) {
minBelow = currentValue;
}
if (currentValue > maxBelow || !maxBelow) {
maxBelow = currentValue;
}
}
if (currentValue > targetValue) {
if (currentValue < minAbove || !minAbove) {
minAbove = currentValue;
}
if (currentValue > maxAbove || !maxAbove) {
maxAbove = currentValue;
}
}
i++;
}
return {
minBelow: minBelow,
maxBelow: maxBelow,
minAbove: minAbove,
maxAbove: maxAbove
};
}
function test() {
alert('In test');
var foo = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var bar = minmax(foo, 5);
alert(bar.minBelow + ","+ bar.maxBelow + "," + bar.minAbove + "," + bar.maxAbove);
}

Categories

Resources