I'm pretty new to recursion and Im having trouble returning the value I want into an array. I have a simple function called countDown which needs to take in an argument of type integer in this case the parameter/argument is the letter (n). and I want to count backwards starting from the number (n) all the way to 1. so for example if I pass in the number 4 I would like to return [4, 3, 2, 1] and I need to do this recursively. I believe I have gotten close because in my code I simply put a console.log(n) and I can see now the numbers are printing out 4, 3, 2, 1 however I need to return these numbers in an array and I am pretty lost. I'm familiar with .push() but that doesn't seem to work and I have tried .concat() but I'm not able to get it to work either. Any help is much appreciated!
function countDown(n) {
if (n < 1) {
return [];
} else {
console.log(n);
let j = countDown(n - 1);
}
}
countDown(4);
You are indeed pretty close. There are going 2 things wrong in your snippet.
You do not return a value if n is not smaller than 1 (the else scenario).
You do log n, but don't add it to the result.
Without changing a lot, a solution might look like this:
function countDown(n) {
if (n < 1) {
return [];
} else {
// get the countdown of n - 1
const ns = countDown(n - 1);
// add the current n in front
ns.unshift(n);
// return the list
return ns;
}
}
console.log(countDown(4));
Make sure you return something in every case!
You're doing it for the base case (return []), but you need to return something that includes the recursive call in other cases (return // something that uses countDown(n-1)).
function countDown(n) {
if (n < 1) return [];
return [n, ...countDown(n-1)];
}
console.log(countDown(4));
You appear to be nearly there, but when using recursion state will need to be passed to the next iteration.
So below is an example where the arr parameter if left blank will create the initial array, and then the recursive part can just keep passing this down.
function countDown(n, arr) {
if (!arr) arr = [];
if (n < 1) {
return arr;
} else {
arr.push(n);
return countDown(n -1, arr);
}
}
console.log( countDown(4) );
Is this does what you want?
let arr = [];
function countDown(n) {
if (n < 1) {
return [];
} else {
arr.push(n);
countDown(n - 1);
}
}
countDown(4);
console.log(arr);
Try something like this
function countDown(n, a = []) {
if (n < 1) {
console.log(a);
return a;
} else {
a.push(n);
let j = countDown(n - 1,a);
}
}
countDown(4);
Related
I'm creating a function to sort through an array to return a boolean indicating whether or not the number 7 is anywhere in the array.
Reading my code out loud I feel like it should do exactly what I am asking it to do. Although I fully realize I am a beginner and I'm going to make mistakes. I cannot figure this one out.
If I input includesSeven([1, 7, 8, 10]); this should return true, however I am getting false as my return
function includesSeven(array) {
for (var i = 0; i <= array.length; i++) {
if (array[i] === 7) {
return true;
} else {
return false;
}
};
};
EDIT: I do apologize for the image and not the code.
My code for this:
function includesSeven(array){
for(var i = 0; i < array.length; i++){
if(array[i] == 7){
return true;
}
}
return false;
}
in your original code, you were essentially just checking the first number in the array, you should return false after the for loop has completed.
while iterating through the array, if it finds the number 7, itll return true. once its all completed, its safe to assume that the number 7 isnt in the array, so you can just return false.
function includesSeven (array) {
return array.includes(7);
}
// or short version
const includesSeven = (a) => a.includes(7);
you can use some if you want to finds the first item that returns true
arr = [1,2,3,4,5,6,7,8,9];
function includesSeven (array) {
return array.some(num => num === 7)
}
console.log(includesSeven(arr));
This should work
function myArray(array) {
for (var i=0; i < array.length; i++) {
if (i === 7) {
// 7, is found in the array list
console.log(i, ", is found in the array list")
return true;
} else {
return false;
}
}
myArray([1,2,3,4,5,6,7,8])
However, you can also use Javascript array methods like map(), forEach() etc to acheive the same results as using a for - loop with a Ternary operator instead of if-statement to shorten the code as;
function myArray(array) {
return array.map(value => value === 7)
}
myArray([1,2,3,4,5,6,7,8])
I've done an assignment, where a function's output is the last number of a fibonacci-array. Truth it, I got stuck hard on this one and I found the code in the second else if statement on stackoverflow. But I can't wrap my head around it, how this is working exactly.
Here is the code:
const fibonacci = function(input) {
let n = Number(input);
if (n === 1) {
return 1;
} else if (n < 1) {
return "OOPS";
} else if (n > 1) {
let array = new Array(n); // <---- Starting here
let filled = array.fill(1);
let reduced = filled.reduce((acc, _, i) => {
acc.push((i <=1) ? i : acc[i-2] + acc[i-1])
return acc;
},[]);
return reduced[n - 1] + reduced[n - 2];
}
}
My question: Why does reduced returns an Array instead of a single value? And since it returns an array - why won't the push'ed numbers get added to the initial array, which already has values in it? -> let's say input = 4 then filled = [1, 1, 1, 1].
const fibonacci = function(input) {
let n = Number(input);
if (n === 1) {
return 1;
} else if (n < 1) {
return "OOPS";
} else if (n > 1) {
let array = new Array(n); // <---- Starting here
let filled = array.fill(1);
let reduced = filled.reduce((acc, _, i) => {
acc.push((i <=1) ? i : acc[i-2] + acc[i-1])
return acc;
},[]); // <- reduce is initialized with an array (new array),
return reduced[n - 1] + reduced[n - 2];
}
}
as reduce is initialized with a new array, the function is reducing (adding new values to the new initialized array) and returning the same.
here how the reducers work
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
I am completing the hackerrank's 10 days of javascript challenge. The question:
write a function to take an array as an argument and then return the second largest element in the array.
I have written the code but my code is returning the largest element and not the second largest as asked.
function getSecondLargest(nums) {
// Complete the function
var largest=nums[0];
for(let i=1;i<nums.length;++i)
{
if(nums[i]>largest)
largest=nums[i];
}
var large=nums[0];
for(let j=1;j<nums.length;++j)
{
if(large<nums[j]&&large<largest)
large=nums[j];
}
return large;
}
When input array nums={2,3,6,6,5} the result is coming 6 while expected output is 5. Please help and point out the errors in the function code below.
should not initialize large with first value var large=nums[0]; because it may appear the biggest value and won't work
should use nums[j]<largest instead of large<largest as mentioned above
I think don't need second loop as all checks can be done in first loop, and you can assign prev largest to large whenever you change it:
function getSecondLargest(nums) {
var largest = nums[0];
var large;
for (let i = 1; i < nums.length; ++i) {
if (nums[i] > largest) {
large = largest;
largest = nums[i];
} else if (nums[i] > large || typeof large === 'undefined') {
large = nums[i]
}
}
return large;
}
console.log(getSecondLargest([5,1-2,3]))
console.log(getSecondLargest([-5,1,-2,3]))
GET SECOND LARGEST
first, I create new array with unique values.
let arr = [...new Set(nums)];
second, sort value using built-in function .sort().
note : by default .sort() always sorts asciibetically, but for some testcase, it doesn't work. So, I put (a, b) => { return a - b } to make sure it will work properly.
arr = arr.sort((a, b) => { return a -b });
third, get the value from arr
let result = arr[arr.length - 2] || arr[0];
finally, return the result
return result
function getSecondLargest(nums) {
let arr = [...new Set(nums)];
//Javascript's array member method .sort( always sorts asciibetically.
arr = arr.sort((a, b) => { return a - b });
let result = arr[arr.length - 2] || arr[0];
return result
}
Just one minor change:
Use nums[j]<largest instead of large<largest in the second for loop
function getSecondLargest(nums) {
// Complete the function
var largest=nums[0];
for(let i=1;i<nums.length;++i)
{
if(nums[i]>largest)
largest=nums[i];
}
var large;
//To ensure that the selected number is not the largest
for(let j=0;j<nums.length;++j)
{
if (nums[j] !== largest){
large = nums[j];
break;
}
}
for(let j=1;j<nums.length;++j)
{
if(large<nums[j]&&nums[j]!=largest)
large=nums[j];
else
console.log(large)
}
return large;
}
var secondLargest = getSecondLargest([6,3,6,6,5]);
console.log("Second largest number", secondLargest);
If you want to avoid using library functions like #ifaruki suggests, this line
if(large<nums[j]&&large<largest)
should read
if (large<nums[j] && nums[j] < largest)
Sorting and picking the second or second-to-last value fails when there are duplicates of the highest value in the input array.
Another easiest logic is to remove duplicates from the array and sort.
let givenArray = [2, 3, 6, 6, 5];
let uniqueArray = [...new Set(givenArray)];
console.log("The second largets element is", uniqueArray.sort()[uniqueArray.length - 2]);
I know you had your question answered, just thought I would provide my solution for any future users looking into this.
You can use reduce to go through the array while remembering the two largest numbers so far.
You just make a simple reduction function:
function twoMax(two_max, candidate)
{
if (candidate > two_max[0]) return [candidate,two_max[0]];
else if (candidate > two_max[1]) return [two_max[0],candidate];
else return two_max;
}
And then you use it for example like this:
let my_array = [0,1,5,7,0,8,12];
let two_largest = my_array.reduce(twoMax,[-Infinity,-Infinity]);
let second_largest = two_largest[1];
This solution doesn't require sorting and goes through the array only once.
If you want to avoid using **sort method. I think here's the easiest logic to do that, which will also work in arrays where there's duplicates of largest integer exists.
function getSecondLargest(arr) {
const largest = Math.max.apply(null, arr);
for (let i = 0; i < arr.length; i++) {
if (largest === arr[i]) {
arr[i] = -Infinity;
}
}
return Math.max.apply(null, arr);
}
console.log(getSecondLargest([5, 7, 11, 11, 11])); //7
Question
We have defined a function called countdown with one parameter (n). The function should use recursion to return an array containing the integers n through 1 based on the n parameter. If the function is called with a number less than 1, the function should return an empty array. For example, calling this function with n = 5 should return the array [5, 4, 3, 2, 1]. Your function must use recursion by calling itself and must not use loops of any kind.
function countdown(n, newArr = []){
if(n == 1){
return newArr;
}
newArr.push(n);
return countdown(n - 1)
}
console.log(countdown(5));
My Question
Is there a way to fix this code so that it works?
I can provide an alternative solution, but I do not understand it:
function countdown(n) {
if (n < 1) {
return [];
} else {
const arr = countdown(n - 1);
arr.unshift(n);
return arr;
}
}
The problem is that you do not pass on the array to the recursive call, so each recursive execution creates a new, empty array. As a consequence, it does not return the array that had a value pushed to it, but the new, empty one that is coming back from the recursive calls.
Secondly, you never push value 1 to the array. So it would be better to stop the recursion at 0 instead of 1.
So taking those two fixes, you get this:
function countdown(n, newArr=[]) {
if (n <= 0) {
return newArr;
}
newArr.push(n);
return countdown(n - 1, newArr)
}
console.log(countdown(5));
Your alternative solution is clean, because it does not need to pass an array as argument. It uses the returned array to add the next value to it (in front of it). It would have my preference.
To understand how it works, print out the intermediate values:
function countdown(n) {
if (n < 1) {
console.log("At the end of recursion. Creating and returning an empty array.");
return [];
} else {
const arr = countdown(n - 1);
console.log("Got the following array back from the recursive call:");
console.log(JSON.stringify(arr));
arr.unshift(n);
console.log("Prefixing it with " + n + " and returning the result:");
console.log(JSON.stringify(arr));
return arr;
}
}
var result = countdown(5);
yes, you can modify your solution like that
function countdown(n){
if(n == 0){
// stop the function at 0 so it will not be included in the array
return [];
}
// concat the value of n as an array with the value less than it
return [n].concat(countdown(n - 1))
}
console.log(countdown(5));
the problem in your solution is that your array initialized as an empty array every time so the final answer will be an empty array
You need to hand over the result array for the recursive call. And you need to check if no value is left, ten return the result array.
function countdown(n, result = []) {
if (n < 1) return result;
result.push(n);
return countdown(n - 1, result);
}
console.log(countdown(5));
As another approach, you could return an array and for the exit condition take the final value, otherwise take n and the spreaded result of the recursive call.
function countdown(n) {
if (n < 1) return [];
return [n, ...countdown(n - 1)];
}
console.log(countdown(5));
At this point we will create the countdown function which call itself and called recursion.
function countdown(n) {
if (n < 1) {
return [];
} else {
console.log(n, "before calling");
const arr = countdown(n - 1);
console.log(n, "after calling");
return arr;
}
}
console.log(countdown(5));
And now when we know that the "before calling" is place where n is decrease and the "after calling" is place where n is increase, based on that we can do this.
const arr = [];
function countdown(n) {
if (n < 1) {
return arr;
} else {
arr.push(n);
return countdown(n - 1);;
}
}
console.log(countdown(5));
I'm studing a solution of this lesson:
https://app.codility.com/programmers/lessons/4-counting_elements/perm_check/
I headed up of this solution made my a github user.
https://github.com/daraosn/codility/tree/master/02-CountingElements/02-PermCheck/javascript
I did understand everything of the code below:
function solution(A) {
var N = A.length;
var sum = (N * (N+1)) / 2;
var tap = [];
for (var i in A) {
sum-=A[i];
if(tap[A[i]]) {
return 0;
}
tap[A[i]] = true;
}
return +(sum==0);
}
with exception of these code lines below:
if(tap[A[i]]) {
return 0;
}
tap[A[i]] = true;
What is its purppose? I didn't understand.
I did a test deleting these code lines from the answer in the
codility interface and it returned 75% right instead of 100% when I had these lines
function solution(A) {
const set = new Set(A)
const max = Math.max(...A)
return set.size === max && set.size === A.length ? 1:0
}
That section checks to see if the number being iterated over has been found before, and per the instructions, duplicates are forbidden:
A permutation is a sequence containing each element from 1 to N once, and only once.
On every normal iteration, the current number being iterated over is assigned to a property of tap:
tap[A[i]] = true;
Then, on subsequent iterations, that test checks to see if the new number being iterated over has already been used:
if(tap[A[i]]) {
return 0;
}
This helps to invalidate inputs like [2, 2, 2], while permitting inputs like [1, 2, 3].
That said, there are two major red flags with this. First, for..in shouldn't be used to iterate over arrays. Instead:
for (const num of A) {
// use num
}
Also, sparse arrays are a very bad idea - it would make much more sense to use an object:
var tap = {};
or a Set:
var tap = new Set();
for (const num of A) {
sum -= num;
if (tap.has(num)) {
return 0;
}
tap.add(num);
}
return +(sum == 0);
Array solution is not so proper way such above explaining. But I will put the solution(O(n)) in case you want :)
const solution = A => ~~(A.sort((a,b) => a-b).every((a,i) => a === i+1));