0

Given a number, my code should return all the even numbers between 1 and the number, and print them in the following format:

22
4444
666666
etc...

This is the code so far:

def pattern(n)
  n == 1 ? "" : arr = (1..n).select {|i| i if i % 2 == 0}.each {|item| return (item.to_s * item)}
end

With any number greater than four, it will only return the following:

22

I think that this may have something to do with the return in the block. However, when using print or puts, this returns an individual array element as follows:

[2]

Ideas for a way around this so that I can achieve the desired output?

1
  • 3
    sometimes it's better to code over multiple lines. Commented Jul 31, 2016 at 5:12

3 Answers 3

2

This code fixes your issue:

def pattern(n)
  n == 1 ? "" : arr = (1..n).select {|i| i if i % 2 == 0}.map {|item| (item.to_s * item)}
end

Note that I'm using map instead of each, and I'm not using a return. The return meant that you didn't actually finish looping over the numbers... as soon as you got to 2 you returned from the function.

map is what you want if you want to build up a new array with the results.

EDIT

A little more cleanup:

def pattern(n)
  n == 1 ? "" : (1..n).select {|i| i.even?}.map {|item| item.to_s * item}
end

The arr = is unnecessary. Your block in a select should just return true or false... you could also use just i % 2 == 0 in there, but even? happens to exist. Also, the parentheses around item.to_s * item are unnecessary.

EDIT 2

Per comments below, if you want a single string, maybe this is what you're looking for (added .join("\n")):

def pattern(n)
  n == 1 ? "" : (1..n).select {|i| i.even?}.map {|item| item.to_s * item}.join("\n")
end

EDIT 3

When returning a string, you can also skip the n==1 special case, since joining an empty array will just return an empty string:

def pattern(n)
  (1..n).select {|i| i.even?}.map {|item| item.to_s * item}.join("\n")
end
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you this has definitely helped to understand my errors. However, I am still having the issue that the out puts comes out in the following format: ["22", "4444"]. I attempted to an each method to the new mapped array to produce the desired output but this has not helped either.
Maybe you want something like pattern(8).join("\n")?
or even [1,2,3,4,5,6].select(&:even?)
2

Your code doesn't work because it returns when it reaches the first value. See:

def pattern n
    return "" if n == 1

    (1..n).select { |i| 
        i if i % 2 == 0
    }.each { |item| 
        return (item.to_s * item) # You are returning here!
    }
end

As a suggestion, you could simplify your code to:

def pattern n
    (2..n).step(2) { |n| puts n.to_s * n }
end

or --even better IMO-- you return an array with all results and let the caller decide what to do with it:

def pattern n
    (2..n).step(2).map { |n| n.to_s * n }
end

6 Comments

Thanks this is definitely a much more efficient solution. However, any insight into why my code is behaving the way it is? I am a little confused about the way it is outputting the values.
You always return the first generated value, that's why the output is only "22".
You have a good approach but it doesn't fully answer the question. The OP wants to return an array as well as print the values. Downvote not mine but it's probably because of what I just said.
@CarySwoveland OP know how to print values, his problem is to find out why pattern is stopping at "22". I think I can just go to the problem instead of coding unnecessary things. But I understand your point.
Looks good. No need for "@edit" in answers. I suggest you write answers as though you are writing a book or blog. It may go through a few drafts. When editing you would not keep sections that have been revised, as it would just water down the text for no useful reason. Nor would you fill your text with the names of those who have suggested this and that improvement. Comments are a good place for such attributions: "Thanks for the suggestion. I've edited my answer to incorporated it." Keep it tight. Lastly, first answer the question, then suggest how the code could be improved.
|
0

Here is another way in which you can tackle the problem, by employing Integer#times:

def pattern n
  (2..n).each do |i|
    next if i.odd?            
    i.times { print i }
    puts
  end
end

pattern 8
#=>
# 22
# 4444
# 666666
# 88888888

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.