I have an array of numbers that represent number of times some processing needs to be done some entities:
array = [20, 30, 10, 7, 8, 5]
and a number that represents the total number of times processing was actually done:
amount_processed = 80
I'd like to build a hash whose keys are the numbers in the array and whose values represent the number of times that was successfully processed of the 80. For instance:
hash = {}
index = 0
until amount_processed <= 0 || index == array.count
mapped_amount = [array[index],amount_processed].min
hash[array[index]] = mapped_amount
amount_processed -= mapped_amount
index += 1
end
The output in this case would be:
{20 => 20, 30 => 30, 10 => 10, 7 => 7, 8 => 8, 5 => 5}
If the amount_processed = 65
, I would get:
{20 => 20, 30 => 30, 10 => 10, 7 => 5}
I want to map the amount_processed
such that it always preferences a mapping where all of the given keys are used up. For example, for an amount_processed = 65
, the output should be:
{20 => 20, 30 => 30, 10 => 10, 5 => 5} # skipped 7 and 8 entirely
Where there are different possible outputs, either is valid, I'm indifferent. I.e., if amount_processed = 60
, EITHER of the 2 below would be valid
{20 => 20, 30 => 30, 10 => 10}
{30 => 30, 10 => 10, 7 => 7, 8 => 8, 5 => 5}
My code to successfully achieve the above outcomes is below
hash = {}
index = 0
size = array.size
until amount_processed <= 0
if index == size * 2
hash["notes"] = "attempting to go beyond 2nd iteration, i.e., there is still amount_processed left but nothing more in the array to map it to"
return hash
elsif index >= size
# we've already looped through everything to find something that fully matches, and still have leftover amounts to be mapped, so now start over, and just go in order to fill in whatever's available
pseudo_index = index - size # allows us to map to original array once index is on second iteration
# was that particular one skipped or not
if hash[array[pseudo_index]].present?
# it wasn't skipped in earlier go around, so skip it NOW
else
mapped_amount = [array[pseudo_index],amount_processed].min
hash[array[pseudo_index]] = mapped_amount
amount_processed -= mapped_amount
end
else
if amount_processed < array[index]
# we don't want a partial map, so just don't, unless it's last resort
else
mapped_amount = [array[index],amount_processed].min
hash[array[index]] = mapped_amount
amount_processed -= mapped_amount
end
end
index += 1
end
return hash
Will my code always work, for any array/amount_processed
combo to create a hash that first matches as many arrays that are "fully complete" as and then creates matches that are not fully complete?