1

tl;dr I want to make an array from the division by 5 results:

20 => [5,5,5,5]
16 => [5,5,5,1]
7  => [5,2]

My current implementation is straightforward yet too large. How can I make it simpler and shorter?

  max_count = 5
  total_count = input_value

  count_array = []
  div = total_count / max_count
  mod = total_count % max_count
  div.times { count_array << max_count }
  count_array << mod unless mod == 0
2
  • 2
    16 => [5,5,5,1] Commented Nov 22, 2018 at 21:27
  • 1
    20.divmod(5) #=> [4, 0]. Contains the all the information you require i.e. the quotient and the remainder. Commented Nov 22, 2018 at 21:35

4 Answers 4

4
  1. You don't need total_count.
  2. div.times { count_array << max_count } is [max_count] * count_array
  3. Using splat, we can simplify it further

max_count = 5

[*[max_count] * (input_value / max_count), input_value % max_count] - [0]

Alternatively, using divmod

max_count = 5

n, mod = input_value.divmod(max_count)
[*[max_count] * n, mod] - [0]

Last line can also be written as:

(Array.new(n) { max_count } << mod) - [0]

or as Stefan suggested in the comment, using Numeric#nonzero?:

Array.new(n, max_count).push(*mod.nonzero?)
Sign up to request clarification or add additional context in comments.

3 Comments

...or ([max_count] * n).tap { |arr| arr << mod if mod > 0 }. rem may be a better name than mod.
I'd use Array.new(n, max_count).push(*mod.nonzero?)nonzero? returns the receiver if it's not zero or nil otherwise.
@Stefan that's really nice, I did not know about nonzero?, today I learned :) I'll edit and add it.
0

One option more:

d = 5
n = 24
Array.new(n/d){d}.tap{ |a| a << n%d if (n%d).nonzero? }
#=> [5, 5, 5, 5, 4]

Comments

0

You can try this as well.

max=5
num=48
q, r=num.divmod(max) # => [9, 3]
Array.new.fill(max, 0, q).push(r.nonzero?).compact
# => [5, 5, 5, 5, 5, 5, 5, 5, 5, 3]

2 Comments

This might result in an array ending with 0 (which the OP doesn't want)
Just realized that :P.Thanks @Stefan.
0

What about this?

[20].tap{|a| a.push(5, a.pop - 5) while a.last > 5} # => [5, 5, 5, 5]
[16].tap{|a| a.push(5, a.pop - 5) while a.last > 5} # => [5, 5, 5, 1]
[7] .tap{|a| a.push(5, a.pop - 5) while a.last > 5} # => [5, 2]

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.