Related
I am trying to write a script that will create numbers in Fibonacci order, I don't understand why this is not working.
var output = [];
var n = output.length;
var nextNum = output[n-1] + output[n-2];
function fibo (numQuantity) {
for (var i=1; i<numQuantity ; i++)
{
if (n>1){
output.push(nextNum);
console.log(output);
}
else if (n<2)
{output.push(1);
console.log(output);}
}
}
In your original code your n never changes as you only assigned it on start.
var output = [];
function fibo (numQuantity) {
for (var i=1; i<numQuantity ; i++)
{
var n = output.length;
var nextNum = output[n-1] + output[n-2];
if (n>1){
output.push(nextNum);
console.log(output);
}
else if (n<2)
{
output.push(1);
console.log(output);
}
}
}
fibo(10)
In Javascript numbers are passed by value not reference so they are not the same object in memory. So when the array length changes your n value stays at 0 because they are not the same object.
function fibo(numQuantity) {
let output = [0, 1];
if(numQuantity < 2) {
return output.slice(0, numQuantity);
}
for(let i = 2; i < numQuantity ; i++) {
const n = output.length
output.push(output[n - 1] + output[n - 2])
}
return output;
}
console.log(fibo(1))
console.log(fibo(2))
console.log(fibo(3))
console.log(fibo(4))
Check this fiddle: https://jsfiddle.net/37a4burz/
You need to add n++ to end of your code and change end condition.
Here is full code:
var output = [];
var n = output.length;
var nextNum = output[n-1] + output[n-2];
function fibo (numQuantity) {
for (var i=1; i<= numQuantity ; i++)
{
if (n==0) {
output.push(0);
console.log(output);
}
else if (n==1) {
output.push(1);
console.log(output);
}
else if (n>1) {
output.push(output[n-1] + output[n-2]);
console.log(output);
}
n++;
}
}
fibo(7);
function fib(n) {
const result = [0, 1];
for (var i = 2; i <= n; i++) {
const a = (i - 1);
const b = (i - 2);
result.push(a + b);
}
return result[n];
}
console.log(fib(8));
The output of the code above is 13. I don't understand the for loop part. In very first iteration i = 2, but after second iteration i = 3 so a = 2 and b = 1 and third iteration i = 4 so a = 3, b = 2, and so on... If it's going on final sequence will be :
[0, 1, 1, 3, 5, 7, 9, 11], which is incorrect. The correct sequence will be [0, 1, 1, 2, 3, 5, 8, 13]
You were not using the previous two numbers that are already in the array to > generate the new fibonacci number to be inserted into the array.
https://www.mathsisfun.com/numbers/fibonacci-sequence.html
Here I have used the sum of result[i-2] and result[i-1] to generate the new fibonacci number and pushed it into the array.
Also to generate n number of terms you need the condition to be i < n and not i <= n.
function fib(n) {
const result = [0, 1];
for (var i = 2; i < n; i++) {
result.push(result[i-2] + result[i-1]);
}
return result; // or result[n-1] if you want to get the nth term
}
console.log(fib(8));
Return result[n-1] if you want to get the nth term.
My solution for Fibonacci series:
const fibonacci = n =>
[...Array(n)].reduce(
(acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),
[]
)
This function is incorrect. It cat be checked by just adding the console.log call just before the function return:
function fib(n) {
const result = [0, 1];
for (var i = 2; i <= n; i++) {
const a = (i - 1);
const b = (i - 2);
result.push(a + b);
}
console.log(result);
return result[n];
}
console.log(fib(7));
As you can see, the sequence is wrong and (for n = 7) the return value is too.
The possible change would be as following:
function fib(n) {
const result = [0, 1];
for (var i = 2; i <= n; i++) {
const a = result[i - 1];
const b = result[i - 2];
result.push(a + b);
}
console.log(result);
return result[n];
}
console.log(fib(8));
This is the "classical" Fibonacci numbers; if you really want to use the first number of 0, not 1, then you should return result[n-1], since array indexes start from zero.
One approach you could take for fibonacci sequence is recursion:
var fibonacci = {
getSequenceNumber: function(n) {
//base case to end recursive calls
if (n === 0 || n === 1) {
return this.cache[n];
}
//if we already have it in the cache, use it
if (this.cache[n]) {
return this.cache[n];
}
//calculate and store in the cache for future use
else {
//since the function calls itself it's called 'recursive'
this.cache[n] = this.getSequenceNumber(n - 2) + this.getSequenceNumber(n - 1);
}
return this.cache[n];
},
cache: {
0: 0,
1: 1
}
}
//find the 7th number in the fibbonacci function
console.log(fibonacci.getSequenceNumber(7));
//see all the values we cached (preventing extra work)
console.log(fibonacci.cache);
//if you want to output the entire sequence as an array:
console.log(Object.values(fibonacci.cache));
The code above is also an example of a dynamic programming approach. You can see that I am storing each result in a cache object the first time it is calculated by the getSequenceNumber method. This way, the second time that getSequenceNumber is asked to find a given input, it doesn't have to do any actual work - just grab the value from cache and return it! This is an optimization technique that can be applied to functions like this where you may have to find the value of a particular input multiple times.
const fib = n => {
const array = Array(n);
for (i = 0; i < array.length; i++) {
if (i > 1) {
array[i] = array[i - 1] + array[i - 2];
} else {
array[i] = 1;
}
}
return array;
}
console.log(fib(5))
What you are doing wrong is adding the iterator index (i), whereas what you need to do is add the element in the result at that index.
function fib(n) {
const result = [0, 1];
for (let i = 2; i <= n; i++) {
const a = result[(i - 1)];
const b = result[(i - 2)];
result.push(a + b);
}
console.log("Result Array: " + result);
return result[n];
}
console.log("Fibonacci Series element at 8: " + fib(8));
There are two issues with the logic:
Variables a and b currently refer to i - 1 and i - 2. Instead they should refer to the elements of result array, i.e. result[i - 1] and result[i - 2].
If you need 8th element of the array, you need to call result[7]. So the returned value should be result[n - 1] instead of result[n].
function fib(n) {
const result = [0, 1];
for (var i = 2; i < n; i++) {
const a = result[i - 1];
const b = result[i - 2];
result.push(a + b);
}
console.log(result);
return result[n - 1];
}
console.log(fib(8));
simple solution for Fibonacci series:
function fib(n){
var arr = [];
for(var i = 0; i <n; i++ ){
if(i == 0 || i == 1){
arr.push(i);
} else {
var a = arr[i - 1];
var b = arr[i - 2];
arr.push(a + b);
}
}
return arr
}
console.log(fib(8))
This is certainly one of those "more than one way to clean chicken" type situations, this JavaScript method below works for me.
function fibCalc(n) {
var myArr = [];
for (var i = 0; i < n; i++) {
if(i < 2) {
myArr.push(i);
} else {
myArr.push(myArr[i-2] + myArr[i-1]);
}
}
return myArr;
}
fibCalc(8);
When called as above, this produces [0,1,1,2,3,5,8,13]
It allows me to have a sequence of fib numbers based on n.
function fib(n) {
const result = [0];
if (n > 1) {
result.push(1);
for (var i = 2; i < n; i++) {
const a = result[result.length - 1]
const b = result[result.length - 2];
result.push(a + b);
}
}
console.log(result);
}
i came up with this solution to get the n index fibonacci value.
function findFac(n){
if (n===1)
{
return [0, 1];
}
else
{
var s = findFac(n - 1);
s.push(s[s.length - 1] + s[s.length - 2]);
return s;
}
}
function findFac0(n){
var vv1 = findFac(n);
return vv1[n-1];
}
console.log(findFac0(10));
Here, you have it, with few argument check, without using exception handling
function fibonacci(limit){
if(typeof limit != "number"){return "Please enter a natural number";}
if(limit <=0){
return "limit should be at least 1";
}
else if(limit == 1){
return [0];
}
else{
var series = [0, 1];
for(var num=1; num<=limit-2; num++){
series.push(series[series.length-1]+series[series.length-2]);
}
return series;
}
}
I came up with this solution.
function fibonacci(n) {
if (n == 0) {
return [0];
}
if ( n == 1) {
return [0, 1];
} else {
let fibo = fibonacci(n-1);
let nextElement = fibo [n-1] + fibo [n-2];
fibo.push(nextElement);
return fibo;
}
}
console.log(fibonacci(10));
function fibonacciGenerator (n) {
var output = [];
if(n===1){
output=[0];
}else if(n===2){
output=[0,1];
}else{
output=[0,1];
for(var i=2; i<n; i++){
output.push(output[output.length-2] + output[output.length-1]);
}
}
return output;
}
output = fibonacciGenerator();
console.log(output);
function fibonacci(end) {
if (isNaN(end) === false && typeof (end) === "number") {
var one = 0, res, two = 1;
for (var i = 0; i < end; ++i) {
res = one + two;
one = two;
two = res;
console.log(res);
}
} else {
console.error("One of the parameters is not correct!")
}
}
fibonacci(5);
var input = parseInt(prompt(""));
var a =0;
var b=1;
var x;
for(i=0;i<=input;i++){
document.write(a+"<br>")
x = a+b;
a =b;
b= x;
}
I want to get a random digit from 0-9 and have it popped so it doesn't get repeated but I find that after the the second number is pushed it doesn't have it's number popped. Instead, some other number not yet selected is popped giving room for a repeat.
var yourNum = [],
oppNum = [],
choose = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
function chooseRandomNumber() {
return choose[Math.floor(Math.random() * choose.length)];
}
for (var i = 0; i < 4; i++) {
if (i === 0) {
yourNum.push(chooseRandomNumber());
if (yourNum[yourNum.length - 1] === 9) {
choose.pop();
} else {
choose.splice(yourNum[0], 1);
}
} else if (i === 1) {
yourNum.push(chooseRandomNumber());
if (yourNum[yourNum.length - 1] === 9) {
choose.pop();
} else {
choose.splice(yourNum[1], 1);
}
} else if (i === 2) {
yourNum.push(chooseRandomNumber());
if (yourNum[yourNum.length - 1] === 9) {
choose.pop();
} else {
choose.splice(yourNum[2], 1);
}
} else if (i === 3) {
yourNum.push(chooseRandomNumber());
if (yourNum[yourNum.length - 1] === 9) {
choose.pop();
} else {
choose.splice(yourNum[3], 1);
}
}
}
console.log(choose);
console.log(yourNum);
function getRand(min, max, result) {
result = result || [];
if(result.length == 4) {
return result;
}
var rand = Math.floor(Math.random()*max) + min;
if(result.indexOf(rand) === -1) {
result.push(rand);
}
return getRand(min, max, result);
}
var result = getRand(1,9);
console.log(result);
Your whole approach is way to complicated and unperformant.
A better approach:
//first we need a shuffle function
function shuffle(array){
for(var i = array.length, j, tmp; i--; ){
j = 0|(Math.random() * i);
tmp = array[j];
array[j] = array[i];
array[i] = tmp;
}
return array;
}
//now let's define a sequence of possible values
var numset = [0,1,2,3,4,5,6,7,8,9];
//shuffle the sequence and take the first 4 values
var fourRandomValues = shuffle(numset).slice(0,4);
console.log("four random values: " + fourRandomValues);
//doing this multiple times:
for(var values = []; values.length < 10;){
//shuffle again, and take the values that are now at the beginning of this sequence
values.push( shuffle(numset).slice(0,4) );
}
console.log("more random values: \n" + values.join("\n"));
Edit:
to address holi-java's approach by implementing sort of an Iterator, I'll add a way to do this with ES6 Iterators/Generators
Since Generators can be unlimited sequences we need to account for that. We do that by buffering a limited amount of values and returning them randomly; basically a shifiting frame of shuffled values.
function *shuffled(iterable, bufferSize = 256){
var buffer, numValues = 0, randomIndex;
if(Array.isArray(iterable) && iterable.length <= bufferSize){
//an optimization for (small) Arrays:
buffer = iterable.slice();
numValues = iterable.length;
}else{
buffer = Array( bufferSize )
for(var value of iterable){
//push value from the iterable to the buffer
buffer[numValues++] = value;
//buffer is full, yield a random value
if(numValues === bufferSize){
//choose a random value from the buffer
randomIndex = 0|(Math.random() * (numValues-1));
//yield it
yield buffer[randomIndex];
//overwrite the value with the last index
//that's cheaper than pop() and splice()
buffer[randomIndex] = buffer[--numValues];
}
}
}
//iterable doesn't provide any more values
//flush the buffer in a random order
while(numValues){
randomIndex = 0|(Math.random() * (numValues-1));
yield buffer[randomIndex];
buffer[randomIndex] = buffer[--numValues];
}
}
//every Array is a valid iterator
for(var v of shuffled([0,1,2,3,4,5,6,7,8,9]))
console.log(v);
That way we can shuffle a stream of values without first caching all the values in an array.
pro: memory efficient
possible problem: if the buffer's to small the result doesn't feel random anymore since values that are generated late in the sequence simply can not be shifted entirely to the start. You see some noise but it doesn't feel random anymore.
now let's take a jump into potentially infinite sequences:
// *shuffled again, for this snippet
function *shuffled(iterable, bufferSize = 256){
var buffer, numValues = 0, randomIndex;
if(Array.isArray(iterable) && iterable.length <= bufferSize){
buffer = iterable.slice();
numValues = iterable.length;
}else{
buffer = Array( bufferSize )
for(var value of iterable){
buffer[numValues++] = value;
if(numValues === bufferSize){
randomIndex = 0|(Math.random() * (numValues-1));
yield buffer[randomIndex];
buffer[randomIndex] = buffer[--numValues];
}
}
}
while(numValues){
randomIndex = 0|(Math.random() * (numValues-1));
yield buffer[randomIndex];
buffer[randomIndex] = buffer[--numValues];
}
}
//creates an infinite sequence of numbers
function *count(){
for(var index = 0; true;)
yield index++;
}
//like limits a iterator but for iterators
function *take(n, iterator){
for(var value of iterator){
if(n-- > 0) yield value;
else break;
}
}
//create an (infinite) counter and convert it into a generator of shuffled values
//with a bufferSize of 256 entries (play a bit with that value)
var shuffledSequence = shuffled(count(), 256);
//to convert that into an Array we take the first 1000 values generated from that generator
var array = [...take(1000, shuffledSequence)];
//and log it
console.log(array.toString());
what do you mean like this below:
function next() {
function all() {
return [].concat(Array(10).fill(null).map(function (_, index) {
return index;
}));
}
function random(start, end) {
return parseInt(Math.random() * (end + 1 - start)) + start;
}
var self = this;
self.all = self.all && self.all.length && self.all || all().sort(function(){
return random(-1, 1);
});
return self.all.shift();}
var results=Array(4).fill(null).map(next);
console.log(results);
my be this is better for browser to run.
var it = {
next: function () {
var self = this;
self._all = self._all && self._all.length && self._all || self.shuffle(self.all());
return self._all.shift();
},
all: function () {
return [0,1,2,3,4,5,6,7,8,9];
},
random: function (start, end) {
if (!end && end != 0) {
end = start;
start = 0;
}
return parseInt(Math.random() * (end + 1 - start)) + start;
},
shuffle: function (array) {
var self = this;
for (var i = array.length - 1; i > 0; --i) {
self.swap(array, i, self.random(i));
}
return array;
},
swap: function (array, i, j) {
var tmp = array[i];
array[i] = array[j];
array[j] = tmp;
},
reset: function () {
this._all = null;
}
};
for (var i = 0; i < 10; i++) {
var results=[];
for(var n=0;n<4;n++) results.push(it.next());
console.log("retain:"+it._all + '>>generated:' + results);
it.reset();
}
Edit
Takes four unique numbers out of the choose array. Is that what you're after?
var yourNum = [],
oppNum = [],
choose = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
function chooseRandomNumber() {
return choose[Math.floor(Math.random() * choose.length)];
}
var rand;
for (var i = 0; i < 4; i++) {
rand = chooseRandomNumber();
yourNum.push(rand);
choose.splice(choose.indexOf(rand), 1);
}
console.log(choose);
console.log(yourNum);
Old approach:
var start = 0, end = 9;
function generate(count) {
var nums = [],
random;
for (var i = 0; i < count; i++) {
while (!random || nums.indexOf(random) !== -1) {
random = Math.floor(Math.random() * (end + 1)) + start;
}
nums.push(random);
}
return nums;
}
console.log(
generate(4)
);
Demo:
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
var yourNums = [];
var choose = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (var i = 0; i < 4; i++) {
yourNums = yourNums.concat(choose.splice(getRandomInt(0, choose.length), 1))
}
console.log("yourNums is:")
console.log(yourNums);
console.log("===")
console.log("choose is:")
console.log(choose);
I'm trying to script a function that takes two numbers and returns the smallest common multiple that is also divisible by all the numbers between those numbers, what I've got only works for 1,1 through 1,12, but for some reason stops working at 1,13. Other set like 12,14 work but I can't figure out why or what the pattern is.
function smallestCommons(arr) {
arr.sort(function(a, b) {
return a-b;
});
var arr1 = [];
var arr2 = [];
for (var k = arr[0]; k<=arr[1]; k++) {
arr1.push(k);
}
function remainder(val1, val2) {
return val1%val2;
}
var b = arr1.reduce(function(a, b) {
return a*b;
});
var i = arr1[arr1.length-1]*arr1[arr1.length-2];
while (i<=b) {
for (var m = 0; m<arr1.length; m++) {
var a = remainder(i, arr1[m]);
arr2.push(a);
}
var answer = arr2.reduce(function(c, d) {
return c+d;
});
if (answer === 0) {
return i;
} else {
arr2 = [];
i++;
}
}
}
I guess you can do as follows in JavaScript; It can calculate the common LCM up to an 216 item array, such as [1,2,3,...,216] in less than 0.25 ms.
function gcd(a,b){
var t = 0;
a < b && (t = b, b = a, a = t); // swap them if a < b
t = a%b;
return t ? gcd(b,t) : b;
}
function lcm(a,b){
return a/gcd(a,b)*b;
}
var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13],
brr = Array(216).fill().map((_,i) => i+1), // limit before Infinity
result = arr.reduce(lcm);
console.log(result);
console.time("limit");
result = brr.reduce(lcm);
console.timeEnd("limit");
console.log(result);
A way is to keep multiplying the largest number in your range with an increasing number and check if all the others are divisible by that. If yes, return that or continue the loop.
Here is my solution in typescript...
function findLowestCommonMultipleBetween(start: number, end: number): number {
let numbers: number[] = [];
for (let i = start; i <= end; i++) {
numbers.push(i);
}
for (let i = 1; true; i++) {
let divisor = end * i;
if (numbers.every((number) => divisor % number == 0)) {
return divisor;
}
}
}
...but for larger ranges, this is a more efficient answer :)
As far as I can tell your algorithm is giving you a correct answer.
I am far from being a professional programmer so anyone who wants please give options to improve my code or its style :)
If you want to be able to check for the answer yourself you can check this fiddle:
https://jsfiddle.net/cowCrazy/Ld8khrx7/
function multiplyDict(arr) {
arr.sort(function (a, b) {
return a - b;
});
if (arr[0] === 1) {
arr[0] = 2;
}
var currentArr = [];
for (var i = arr[0]; i <= arr[1]; i++) {
currentArr.push(i);
}
var primeDivs = allPrimes(arr[1]);
var divsDict = {};
for (var j = currentArr[0]; j <= currentArr[currentArr.length -1]; j++){
divsDict[j] = [];
if (primeDivs.indexOf(j) > -1) {
divsDict[j].push(j);
} else {
var x = j;
for (var n = 2; n <= Math.floor(j / 2); n++) {
if (x % n === 0) {
divsDict[j].push(n);
x = x / n;
n--;
continue;
}
}
}
}
return divsDict;
}
function allPrimes(num) {
var primeArr = [];
var smallestDiv = 2;
loopi:
for (var i = 2; i <= num; i++) {
loopj:
for (var j = smallestDiv; j <= largestDiv(i); j++) {
if (i % j === 0) {
continue loopi;
}
}
primeArr.push(i);
}
return primeArr;
}
function largestDiv (a) {
return Math.floor(Math.sqrt(a));
}
multiplyDict([1,13]);
it gives a dictionary of the requested array and the divisors of each element.
from there you can go on your own to check that your algorithm is doing the right job or you can check it here:
https://jsfiddle.net/cowCrazy/kr04mas7/
I hope it helps
It is true! The result of [1, 13] is 360360. and after this we have [1, 14].
14 = 2 * 7 and we now 360360 is dividable to 2 and 7 so the answer is 360360 again.
[1, 15]: 15 = 3 * 5 and result is same.
[1, 16]: result is 720720.
[1, 17]: result is: 12252240
[1, 18]: 18 = 2 * 9 and result is 12252240 same as 17
[1, 19]: for my computer this process is so heavy and can not do this. But in a strong machine it will work. I promise. But your code is not good in performance.
To find the LCM in N numbers.
It is Compatible with ES6, and consider that is there is no control for boundaries in case that we need to find for large numbers.
var a = [10, 40, 50, 7];
console.log(GetMinMultiple(a));
function GetMinMultiple(data) {
var maxOf = data.reduce((max, p) => p > max ? p : max, 0);
var incremental = maxOf;
var found = false;
do {
for (var j = 0; j < data.length; j++) {
if (maxOf % data[j] !== 0) {
maxOf += incremental;
break;
}
else {
if (j === data.length - 1) {
found = true;
break;
}
}
}
} while (!found);
return maxOf;
}
https://jsfiddle.net/djp30gfz/
Here is my solution in Typescript
function greatestCommonDivider(x: number, y: number): number {
if (y === 0) {
return x;
}
return greatestCommonDivider(y, x % y);
}
function singleLowestCommonMultiply(x: number, y: number): number {
return (x * y) / greatestCommonDivider(x, y);
}
function lowestCommonMultiply(...numbers: number[]): number {
/**
* For each number, get it's lowest common multiply with next number.
*
* Then using new number, compute new lowest common multiply
*/
return numbers.reduce((a, b) => {
return singleLowestCommonMultiply(a, b);
});
}
lowestCommonMultiply(2, 3); // Outputs 6
lowestCommonMultiply(2, 3, 5); // Outputs 30
Playground - click here
I have the following code to find the prime numbers from 2 to 1000:
#!/usr/bin/env node
var primesarray = function(n) {
var nums = [];
for (var i = 0; i < n; i++) {
nums.push("1");
}
return nums;
};
var primes = function(arr) {
var i = 2;
var primes = [];
for (i = 2; i < arr.length - 1; i++) {
if (arr[i] === "1")
primes.push(i);
for (j = 2; Math.pow(i, j) < arr.length - 1; j++ ) {
arr[Math.pow(i,j)] = "0";
}
}
return primes;
};
// Print to console
var fmt = function(arr) {
return arr.join(",");
};
var k = 1000;
console.log("primes(" + k + ")");
console.log(fmt(primes(k)));
When I run the file, it just prints the first console.log line. I'm not seeing what's wrong here.
The function primes is written to expect an array, but you're passing it an integer.
Did you mean fmt(primes(primesarray(k)))?
(That does at least print a list of numbers, but I'm afraid many of them are not primes!)
You need to prime you array ;)
var arr = primesarray(k)
like this
var k = 1000;
var arr = primesarray(k)
console.log(primes(arr));
console.log(fmt(primes(arr)));
DEMO
Some actual solutions: http://www.codecademy.com/forum_questions/5033d10f77955e0002004142