Javascript codewars : Tribonacci Sequence - javascript

function tribonacci(signature, n) {
var myArray = [];
var lenArray = 0;
var i = 0;
var outPut = 0;
var x = 0;
if (n > 0) {
while (i < 3) {
myArray.push(signature[i]);
i++;
}
lenArray = myArray.length - 1;
i = 0;
while (lenArray < n) {
while (x < 3) {
var v = x + i;
outPut += myArray[v];
x++;
}
i++;
lenArray = myArray.length - 1;
myArray.push(outPut);
}
return myArray;
} else {
return [];
};
}
console.log(tribonacci([1, 1, 1], 10));
First, I tried to push first 3 items into "myArray".
Second, in the "while" loop, while it's less than "n" (number of items needed to be in the array), add the last 3 items in "myArray" until "myArray" reaches the needed "n" amount.
e.g. tribonacci([1,1,1],10)
Return should be [1,1,1,3,5,9,17,31,57,105]
Adding the last 3 items continuously until it reaches 10 items in an array.
Instead I get as result:
[1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3]
I have no idea why it's stuck on 3s.
I tried "i++" below the 2nd "while" loop so that it can start adding the last 3 items every time "myArray" grows by one, but that doesn't seem to be the issue. Is the "outPut" being stuck on 3?

var v = x + i; uses x to calculate the correct index.
After adding those 3 numbers, x needs to be reset.
Also, outPut is reused in the next iteration, but it keeps adding values, so your output will get to high. This needs to be reset to 0 after the 3-loop.
Add outPut = x = 0 after pushing outPut into myArray
function tribonacci(signature, n) {
var myArray = [];
var lenArray = 0;
var i = 0;
var outPut = 0;
var x = 0;
if (n > 0) {
while (i < 3) {
myArray.push(signature[i]);
i++;
}
lenArray = myArray.length - 1;
i = 0;
while (lenArray < n) {
while (x < 3) {
var v = x + i;
outPut += myArray[v];
x++;
}
i++;
lenArray = myArray.length - 1;
myArray.push(outPut);
outPut = x = 0
}
return myArray;
} else {
return [];
};
}
console.log(tribonacci([1, 1, 1], 10));
[
1,
1,
1,
3,
5,
9,
17,
31,
57,
105,
193,
355
]
Some bonus-tips to improve the readabilty:
Use (...) spread operator to replace the first while:
var myArray = [ ...signature ];
Use myArray.length - 1 instead off defining a variable with the same value
Use myArray[x + i] instead off defining another varible
Return on n < 0 to you don't need to intent that much
Applying those will give:
function tribonacci(signature, n) {
var myArray = [ ...signature ];
var i = 0;
var x = 0;
var outPut = 0;
if (n < 0) {
return [];
}
while ((myArray.length - 1) < n) {
while (x < 3) {
outPut += myArray[x + i];
x++;
}
i++;
myArray.push(outPut);
outPut = x = 0;
}
return myArray;
}

Hey there are you doing this for homework on while loops? If so refer to #0stone0 's answer which solves it right!
If on the other hand you want to dive into JS a little more, I'd suggest you a more coincise solution with some cool Array function:
function tribonacci(signature, size) {
const output = signature;
while(output.length < size) {
output.push(output.slice(-3).sum());
}
return output;
}
console.log({ result: tribonacci([1, 1, 1], 10) });
Some version of JS don't include the Array.sum function which would be something like this:
Array.prototype.sum = function() {
return this.reduce((sum, curr) => sum + curr, 0);
}

Related

Javascript/ variable place/ what is wrong with the code

I want to write a Generator for Fibonacci numbers in Javascript;
0,1,1,2,5,7,12..... (to make the sequence you have to add the last two numbers)
But I have this problem when I assign the the output.length to a variable the code is not working, if I write it down straight instead of "newNumber" the code down is however working, but I don't understand what is wrong with the first one. Is it something wrong with the place of the variables?
function fibonacciGenerator(n) {
var output = [];
var lastNumber = output[output.length - 1];
var nPrev = output[output.length - 2];
var newNumber = lastNumber + nPrev;
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(newNumber);
}
}
return output
}
console.log(fibonacciGenerator(5));
function fibonacciGen(n) {
const output = [0, 1];
// Return an empty array if n is less than 1
if (n < 1) {
return [];
}
// If n is 1 or 2, we can return the array now
if (n <2) {
return output;
}
// Loop through the remaining numbers in the sequence
for (let i = 2; i < n; i++) {
// Calculate the next number in the sequence
let lastNumber = output[output.length - 1];
let nPrev = output[output.length - 2];
let newNumber = lastNumber + nPrev;
// Add the new number to the output array
output.push(newNumber);
}
// Return the output array
return output;
}
console.log(fibonacciGen(5));
you have to declare your logic of next term in loop because first time length of output is zero
function fibonacciGenerator (n) {
var output =[];
if (n < 1) {
return [];
}
if (n===1){
output=[0];
}
else if (n===2){
output=[0,1];
}
else{
output=[0,1];
for( var i = 2; i < n; i++){
var lastNumber=output[output.length-1];
var nPrev=output[output.length-2];
var newNumber=lastNumber+nPrev;
output.push(newNumber);
}
}
return output
}

Mergesort is shaving off values in an array

I seem to have a basic mergesort working for small arrays but at larger n values it seems to be breaking & shaving off values. I'm testing using a helper function (largetest).
I've added conditionals for everything, verified the slices to be correct (to my understanding)
The helper function can assist in creating a large array, spotting points of difference (uncomment the console log), and verifying the lengths.
I've been running this on quokka.js in vscode.
var mergeSort = function(array) {
if (array.length === 1) {
return array;
}
const half = Math.floor(array.length / 2);
let left = array.slice(0, half);
let right = array.slice(half);
var joined = joinArrays(mergeSort(left), mergeSort(right));
return joined;
};
const joinArrays = (array1, array2) => {
var pointer1 = 0;
var pointer2 = 0;
let results = [];
while (array1[pointer1] && array2[pointer2]) {
if (array1[pointer1] <= array2[pointer2]) {
results.push(array1[pointer1]);
pointer1++;
} else if (array1[pointer1] > array2[pointer2]) {
results.push(array2[pointer2]);
pointer2++;
}
}
if (array1[pointer1]) {
results = results.concat(array1.slice(pointer1));
} else if (array2[pointer2]) {
results = results.concat(array2.slice(pointer2));
}
return results;
}
var a = mergeSort([4, 7, 4, 3, 9, 1, 2]);
console.log(a);
var a = mergeSort([48, 56, 2, 34, 98, 75, 42, 21, 3])
console.log(a);
var a = mergeSort([5, 6, 98324, 234, 34, 23, 42520, 234, 4323, 32])
console.log(a);
var a = mergeSort([4, 4, 4, 5, 7, 8, 9, 9, 1, 2, 3, ])
console.log(a);
function largeTest () {
var input = [];
var sorted;
var n = 10;
for (var i = 0; i < n; i++) {
var number = Math.floor(Math.random() * n);
input.push(number);
}
sorted = input.sort(function (a, b) {
return a - b;
});
var result = mergeSort(input);
console.log(result.length, sorted.length) //Why is it shaving numbers?
for (var i = 0; i < n; i++) {
if (result[i] !== sorted[i]) {
//console.log(i, 'result:', result[i], 'sorted:', sorted[i])
}
}
console.log('complete')
}
largeTest()
The heart of the problem lies in this line:
while (array1[pointer1] && array2[pointer2])
You should loop over both arrays and this loop does that as long as array values are not null, undefined or 0. It works because reading an array element beyond the end of the array returns undefined in javascript, hence tests false. The small arrays in your tests do not contain null values, so the code works, but larger arrays filled with pseudo-random data probably do, each causing the end of the corresponding slice to get shaved off.
You can fix this by testing the array length instead of the array contents:
const joinArrays = (array1, array2) => {
var pointer1 = 0, len1 = array1.length;
var pointer2 = 0, len2 = array2.length;
let results = [];
while (pointer1 < len1 && pointer2 < len2) {
if (array1[pointer1] <= array2[pointer2]) {
results.push(array1[pointer1]);
pointer1++;
} else {
results.push(array2[pointer2]);
pointer2++;
}
}
if (pointer1 < len1) {
results = results.concat(array1.slice(pointer1));
} else if (pointer2 < len2) {
results = results.concat(array2.slice(pointer2));
}
return results;
}
Your joinArrays() function looks awfully complicated for something as simple as merging two orders arrays. Try substituting a merge() function like this for your joinArrays() function:
function merge( left, right, compare = defaultComparer ) {
const merged = [];
let i = 0;
let j = 0;
let k = 0;
// ------------------------------------------------------
// while we have both a left and right item, just compare
// them and pick the lowest to put in the merged array
// ------------------------------------------------------
while ( i < left.length && j < right.length ) {
const cc = compare( left[i], right[j] );
merged[k++] = cc > 0 ? right[j++] : left[i++] ;
}
// ------------------------------------------------------
// if we only have left items... it's easy
// ------------------------------------------------------
while ( i < left.length ) {
merged[k++] = left[i++];
}
// ------------------------------------------------------
// if we only have right items... it's easy
// ------------------------------------------------------
while ( j < right.length ) {
merged[k++] = right[j++];
}
// ------------------------------------------------------
// return the merged array
// ------------------------------------------------------
return merged;
}
function defaultComparer( a, b ) {
return a < b ? -1
: a > b ? +1
: 0
;
}

Find element that appears odd number of times

I'm trying to solve this exercise of finding the number that appears an odd number of times in an array. I have this so far but the output ends up being an integer that appears an even number of times. For example, the number 2 appears 3 times and the number 4 appears 6 times, but the output is 4 because it counts it as appearing 5 times. How can it be that it returns the first set that it finds as odd? Any help is appreciated!
function oddInt(array) {
var count = 0;
var element = 0;
for(var i = 0; i < array.length; i++) {
var tempInt = array[i];
var tempCount = 0;
for(var j = 0; j <array.length; j++) {
if(array[j]===tempInt) {
tempCount++;
if(tempCount % 2 !== 0 && tempCount > count) {
count = tempCount;
element = array[j];
}
}
}
}
return element;
}
oddInt([1,2,2,2,4,4,4,4,4,4,5,5]);
function findOdd(numbers) {
var count = 0;
for(var i = 0; i<numbers.length; i++){
for(var j = 0; j<numbers.length; j++){
if(numbers[i] == numbers[j]){
count++;
}
}
if(count % 2 != 0 ){
return numbers[i];
}
}
};
console.log(findOdd([20,1,-1,2,-2,3,3,5,5,1,2,4,20,4,-1,-2,5])); //5
console.log(findOdd([1,1,1,1,1,1,10,1,1,1,1])); //10
First find the frequencies, then find which ones are odd:
const data = [1,2,2,2,4,4,4,4,4,4,5,5]
const freq = data.reduce(
(o, k) => ({ ...o, [k]: (o[k] || 0) + 1 }),
{})
const oddFreq = Object.keys(freq).filter(k => freq[k] % 2)
// => ["1", "2"]
If we are sure only one number will appear odd number of times, We can XOR the numbers and find number occurring odd number of times in n Comparisons.XOR of two bits is 1 if they are different else it will be 0. Truth table is below.
A B A^B
0 0 0
0 1 1
1 0 1
1 1 0
So when we do XOR of all the numbers, final number will be the number appearing odd number of times.
Let's take a number and XOR it with the same number(Appearing two times). Result will be 0 as all the bits will be same. Now let's do XOR of result with same number. Now result will be that number because all the bits of previous result are 0 and only the set bits of same number will be set in the result. Now expanding it to an array of n numbers, numbers appearing even number of times will give result 0. The odd appearance of the number result in that number in the final result.
func oddInt(numbers: [Int]) -> Int {
var result = 0
for aNumber in numbers {
result = result ^ aNumber
}
return result
}
Here is a solution with O(N) or O(N*log(N))
function findOdd(A) {
var count = {};
for (var i = 0; i < A.length; i++) {
var num = A[i];
if (count[num]) {
count[num] = count[num] + 1;
} else {
count[num] = 1;
}
}
var r = 0;
for (var prop in count) {
if (count[prop] % 2 != 0) {
r = prop;
}
}
return parseInt(r); // since object properies are strings
}
#using python
a=array('i',[1,1,2,3,3])
ans=0
for i in a:
ans^=i
print('The element that occurs odd number of times:',ans)
List item
output:
The element that occurs odd number of times: 2
Xor(^)operator when odd number of 1's are there,we can get a 1 in the output
Refer Xor Truth table:
https://www.electronicshub.org/wp-content/uploads/2015/07/TRUTH-TABLE-1.jpg
function oddInt(array) {
// first: let's count occurences of all the elements in the array
var hash = {}; // object to serve as counter for all the items in the array (the items will be the keys, the counts will be the values)
array.forEach(function(e) { // for each item e in the array
if(hash[e]) hash[e]++; // if we already encountered this item, then increments the counter
else hash[e] = 1; // otherwise start a new counter (initialized with 1)
});
// second: we select only the numbers that occured an odd number of times
var result = []; // the result array
for(var e in hash) { // for each key e in the hash (the key are the items of the array)
if(hash[e] % 2) // if the count of that item is an odd number
result.push(+e); // then push the item into the result array (since they are keys are strings we have to cast them into numbers using unary +)
}
return result;
}
console.log(oddInt([1, 2, 2, 2, 4, 4, 4, 4, 4, 4, 5, 5]));
Return only the first:
function oddInt(array) {
var hash = {};
array.forEach(function(e) {
if(hash[e]) hash[e]++;
else hash[e] = 1;
});
for(var e in hash) { // for each item e in the hash
if(hash[e] % 2) // if this number occured an odd number of times
return +e; // return it and stop looking for others
}
// default return value here
}
console.log(oddInt([1, 2, 2, 2, 4, 4, 4, 4, 4, 4, 5, 5]));
That happens because you are setting the element variable each time it finds an odd number, so you are setting it when it find one, three and five 4.
Let's check the code step by step:
function oddInt(array) {
// Set the variables. The count and the element, that is going to be the output
var count = 0;
var element = 0;
// Start looking the array
for(var i = 0; i < array.length; i++) {
// Get the number to look for and restart the tempCount variable
var tempInt = array[i];
var tempCount = 0;
console.log("");
console.log(" * Looking for number", tempInt);
// Start looking the array again for the number to look for
for(var j = 0; j <array.length; j++) {
// If the current number is the same as the one that we are looking for, sum it up
console.log("Current number at position", j, "is", array[j]);
if(array[j]===tempInt) {
tempCount++;
console.log("Number found. Current count is", tempCount);
// Then, if currently there are an odd number of elements, save the number
// Note that you are calling this altough you don't have looped throgh all the array, so the console will log 3 and 5 for the number '4'
if(tempCount % 2 !== 0 && tempCount > count) {
console.log("Odd count found:", tempCount);
count = tempCount;
element = array[j];
}
}
}
}
return element;
}
oddInt([1,2,2,2,4,4,4,4,4,4,5,5]);
What we want to do is to check for the count AFTER looping all the array, this way:
function oddInt(array) {
// Set the variables. The count and the element, that is going to be the output
var count = 0;
var element = 0;
// Start looking the array
for(var i = 0; i < array.length; i++) {
// Get the number to look for and restart the tempCount variable
var tempInt = array[i];
var tempCount = 0;
console.log("");
console.log(" * Looking for number", tempInt);
// Start looking the array again for the number to look for
for(var j = 0; j <array.length; j++) {
// If the current number is the same as the one that we are looking for, sum it up
console.log("Current number at position", j, "is", array[j]);
if(array[j]===tempInt) {
tempCount++;
console.log("Number found. Current count is", tempCount);
}
}
// After getting all the numbers, then we check the count
if(tempCount % 2 !== 0 && tempCount > count) {
console.log("Odd count found:", tempCount);
count = tempCount;
element = tempInt;
}
}
return element;
}
oddInt([1,2,2,2,4,4,4,4,4,4,5,5]);
By the way, this is only for you to understand where was the problem and learn from it, although this is not the most optimized way of doing this, as you may notice that you are looking for, let's say, number 2 three times, when you already got the output that you want the first time. If performance is part of the homework, then you should think another way :P
This is because your condition if(tempCount % 2 !== 0 && tempCount > count) is true when the 5th 4 is checked. This updates the count and element variables.
When the 6th 4 is checked, the condition is false.
To fix, move the condition outside the innermost loop so that it's checked only after all the numbers in the array are counted.
function oddInt(array, minCount, returnOne) {
minCount = minCount || 1;
var itemCount = array.reduce(function(a, b) {
a[b] = (a[b] || 0) + 1;
return a;
}, {});
/*
itemCount: {
"1": 1,
"2": 3,
"4": 6,
"5": 2,
"7": 3
}
*/
var values = Object.keys(itemCount).filter(function(k) {
return itemCount[k] % 2 !== 0 && itemCount[k]>=minCount;
});
return returnOne?values[0]:values;
}
var input = [1, 2, 2, 2, 4, 4, 4, 4, 4, 4, 5, 5, 7, 7, 7];
console.log(oddInt(input, 3, true));
console.log(oddInt(input, 1, true));
console.log(oddInt(input, 2, false));
"A" is the array to be checked.
function findOdd(A) {
var num;
var count =0;
for(i=0;i<A.length;i++){
num = A[i]
for(a=0;a,a<A.length;a++){
if(A[a]==num){
count++;
}
} if(count%2!=0){
return num;
}
}
}
function oddOne (sorted) {
let temp = sorted[0];
let count = 0;
for (var i = 0; i < sorted.length; i++) {
if (temp === sorted[i]) {
count++;
if (i === sorted.length - 1) {
return sorted[i];
}
} else {
if (count % 2 !== 0) {
return temp;
}
count = 1;
temp = sorted[i];
}
}
}
function oddInt(array) {
let result = 0;
for (let element of array) {
result ^= element
}
return result
}
var oddNumberTimes = (arr) => {
let hashMap = {};
for (let i = 0; i < arr.length; i++) {
hashMap[arr[i]] = hashMap[arr[i]] + 1 || 1;
}
for (let el in hashMap) {
if (hashMap[el] % 2 !== 0) {
return el;
}
}
return -1;
};
You can use bitwise XOR:
function oddInt(array) {
return array.reduce(function(c, v) {
return c ^ v;
}, 0);
}
console.log(oddInt([20, 1, -1, 2, -2, 3, 3, 5, 5, 1, 2, 4, 20, 4, -1, -2, 5]) == 5);
console.log(oddInt([1, 1, 1, 1, 1, 1, 10, 1, 1, 1, 1]) == 10);
Had to implement a solution for a similar problem and here it is:
function findtheOddInt(A) {
let uniqueValues = [...new Set(A)]; // Get the unique values from array A
const odds = [];
uniqueValues.forEach(element => {
const count = A.reduce((acc, cur) => cur === element ? acc + 1: acc, 0) // count the occurrences of the element in the array A
if (count % 2 === 1) {
odds.push(element);
}
});
return odds[0]; // Only the first odd occurring element
}
var arr=[1,2,2,2,2,3,4,3,3,3,4,5,5,9,9,10];
var arr1=[];
for(let i=0;i
{
var count=0;
for(let j=0;j<arr.length;j++)
{
if(arr[i]==arr[j])
{
count++;
}
}
if(count%2 != 0 )
{
arr1.push(arr[i]);
}
}
console.log(arr1);

Javascript least common multiple algorithm

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

How can I loop an array from certain position in clockwise and counterclockwise?

I have this array:
var array = [0,1,2,3,4,5,6,7,8,9,10];
To Loop in a Clockwise Direction ( Start 8, then 9, then 10, then 0.....) I'm doing this way:
var start = 8;
for(i = 0; i < array.length; i++){
index = (start+i)%array.length;
....
}
1) To Clockwise Direction, there's a better way?
2) To Loop in a CounterClockwise Direction (Start 2, then 1, then 0, then 10...), what should I do?
To do it similar to what you did, decrease the index from the starting index and add the length before trimming:
var start = 8;
for(i = 0; i < array.length; i++) {
index = (start - i + array.length) % array.length;
// ....
}
Regarding "how to do it better", I'd create a simple helper function:
function getIndexInRange(index, length) {
var trim = index % length;
var nonNegative = trim + length;
return nonNegative % length;
}
Then it all becomes clearer:
var start = 8;
for(i = 0; i < array.length; i++) {
var index = getIndexInRange(start + i, array.length);
// ....
}
for(i = 0; i < array.length; i++) {
var index = getIndexInRange(start - i, array.length);
// ....
}
Now you can even iterate the array multiple times if you want, and it still works:
for(i = 0; i < array.length * 5; i++) {
var index = getIndexInRange(start - i, array.length);
// ....
}
var array = [0,1,2,3,4,5,6,7,8,9,10];
function clockwise(start){
for (var i = 0; i < array.length; i++){
console.log((start+i)%array.length);
}
}
function counterClockwise(start){
for (var i = array.length; i > 0; i--){
console.log((start+i)%array.length);
}
}
console.log('clockwise start from ');
clockwise(8);
console.log('clockwise End ');
console.log('counterClockwise start from ');
counterClockwise(2);
console.log('counterClockwise End ');
Consider using a single function for both directions:
var array = [0,1,2,3,4,5,6,7,8,9,10];
function iterateByClockRotation(start, array, direction){
var len = array.length, current = start;
while (len--) {
current = array.indexOf(current);
if (current < 0) current = ((direction === "clockwise")? 0 : array.length-1);
console.log(array[current]); // the current value
(direction === "clockwise")? current++ : current--;
}
}
iterateByClockRotation(8, array, "clockwise");
The output for 'clockwise' direction:
8
9
10
0
1
2
3
4
5
6
7
iterateByClockRotation(2, array, "anticlockwise");
The output for 'anticlockwise' direction:
2
1
0
10
9
8
7
6
5
4
3
I created a jsbin here.
http://jsbin.com/tucusal/edit?html,js,console
You can even create a function that takes direction input and then traverses array in that direction.
var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var start = 8;
clockwise = 1;
anti_clockwise = -1;
direction = clockwise;
traverse(array, start, anti_clockwise);
function traverse(array, start, direction) {
var count = array.length;
for (i = start; count > 0; i += direction) {
var index = array[(array.length + i) % array.length];
count--;
console.log(index);
}
}
you can use Array.prototype.slice to change start of array:
Array.prototype.enhancedForEach = function(callback, start = 0, clockwise = true) {
var array = this;
start %= array.length;
array.slice(start)
.concat(array.slice(0, start))
.forEach((v, i, arr) => {
var index = clockwise ? i : arr.length - i - 1;
callback(arr[index], index, arr);
});
}
array = Array.from({
length: 20
}, (v, i) => i);
array.enhancedForEach(v => console.log(v), 4);
array.enhancedForEach(v => console.log(v), 0, false);
http://stackoverflow.com/posts/37981887/edit#

Categories