3

I am attempting to take two values times and number and return an array of number repeated times times. Here is an example:

replicate(3, 5) # => [5, 5, 5]

Here is my attempt 1:

@array = []

def replicate(times, number)
  return [] if times <= 0
  @array << number 
  replicate(times - 1, number)
  @array
end

When I run each test case once in isolation, I pass everything. However, when I run them all at once, it fails; @array contains all the values for every test case and @array will look like this at the end of the entire test suite:

@array # => [5, 5, 5, 1, 1, 1, 1, 2, 2]

Here is implementation two:

def replicate(times, number)
  return [] if times <= 0
  array = []
  array << number 
  replicate(times - 1, number)
  array
end

This will return only one value because recursion will create a local copy for every run.

How can I return an array that will make the test cases pass? I can't use global or instance variables, or a local copy of an array. Is there something I can use in between?

1
  • Try passing array into your recursive function defination. Commented Jun 27, 2016 at 14:26

3 Answers 3

5

In this case there's no need to keep an accumulator either as an instance variable or an argument. All you need to do is concatenate the result from this call (which will be an array with a single element, i.e. [ number ]) with the result of subsequent calls:

def replicate(times, number)
  return [] if times <= 0
  [ number ] + replicate(times - 1, number)
end

If you wanted to use an accumulator, you could do it this way:

def replicate(times, number, accum=[])
  return accum if times <= 0
  replicate(times - 1, number, accum + [ number ])
end

(Note that you could use accum << number as well, but personally I prefer to treat data structures as immutable when writing recursive functions—because, well, it's a capital-F function and functions shouldn't have side-effects.)

Sign up to request clarification or add additional context in comments.

2 Comments

This is a better answer.
Thanks, @NicNilov. Your solution was good as well. Sorry someone downvoted it. :(
5

Pass your accumulator array to recursive calls:

def replicate(times, number, array=[])
   return [] if times <= 0
   array << number
   replicate(times - 1, number, array)
   array
end

replicate(3, 5)
=> [5, 5, 5]

2 Comments

This is a pattern frequently seen. Is there a name for this?
Accumulative recursion is one way to call it
0

Why not simply do :

[number]*times

Example :

$ irb
2.3.0 :001 > [1]*5
 => [1, 1, 1, 1, 1] 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.