G'day:
I'll move on from this topic soon, rest assured. Having come up with a CFML answer for my quiz question ("Weekend quiz: my answer (CFML version)"), I decided to stretch myself (albeit slightly) and work out how to do it in Ruby too.
For the sake of completeness, here it is.
This is the same logic as the CFML one. Observations:
That's quite nice-looking code too.
Anyway, that's all I have to say on that. I had better crack on with some work.
If you know Ruby and see how I've messed things up, or could have done better: please let me know! I'm definitely a newbie when it comes to Ruby.
--
Adam
I'll move on from this topic soon, rest assured. Having come up with a CFML answer for my quiz question ("Weekend quiz: my answer (CFML version)"), I decided to stretch myself (albeit slightly) and work out how to do it in Ruby too.
For the sake of completeness, here it is.
# getSubseries.rb
def getSubseries(series, threshold)
working = []
series.inject [] do |reduction, current|
working.push current
working.shift while working.inject(0, &:+) > threshold
workingIsBetterForLength = working.length > reduction.length
workingIsBetterForTotal = working.length == reduction.length && working.inject(0, &:+)> reduction.inject(0, &:+)
workingIsBetterForLength || workingIsBetterForTotal ? working.clone : reduction
end
end
This is the same logic as the CFML one. Observations:
- the reduction / folding operation on Ruby is called inject for some reason.
- this indecipherable mess -
working.inject(0, &:+)
- is shorthand for this:array.inject{|sum,x| sum + x }
IE: the Ruby equivalent of.sum()
. Ruby has no inbuilt method for summing arrays.
I have no idea what it means (and, lazily, I have not checked yet), or how that works. - Of my own code, I like this version the best. It's clearer code IMO.
- I like how Ruby method calls don't need parentheses, too.
# getSubseriesTest.rb
load "getSubseries.rb"
result = getSubseries [], 0
puts "Should return an array\n" unless result.is_a? Array
result = getSubseries [100], 100
puts "Should return elements if there are any within the threshold\n" unless result == [100]
result = getSubseries [100,100], 500
puts "Should return a multi-element subseries\n" unless result == [100,100]
result = getSubseries [100,100,100,100,100,100], 500
puts "Total of elements should not be greater than threshold\n" unless result.inject(0){|sum,x| sum + x } <= 500
result = getSubseries [600,100,100,100,600,100,100,100,100,600], 500
puts "Should return a subsequent larger subseries\n" unless result == [100,100,100,100]
result = getSubseries [600,100,100,100,600,200,100,100,100,100,100,600], 500
puts "Should return a longer adjacent subseries\n" unless result == [100,100,100,100,100]
result = getSubseries [600,700,800,900], 500
puts "Should work when threshold is less than all items\n" unless result == []
result = getSubseries [600,700,800,900], 1000
puts "Should work when threshold is greater than all items\n" unless result == [900]
result = getSubseries [600,700,800,900], 5000
puts "Should work when threshold is greater than sum of all items\n" unless result == [600,700,800,900]
result = getSubseries [100,50,50,50,50,50,500,100,60,60,60,60,60,500], 500
unless result == [100,60,60,60,60,60] then
puts "Should return subseries with highest tally when there are two equal-length subseries (second subseries is higher)\n"
end
result = getSubseries [100,60,60,60,60,60,500,100,50,50,50,50,50,500], 500
unless result == [100,60,60,60,60,60]
puts "Should return subseries with highest tally when there are two equal-length subseries (first subseries is higher)\n"
end
That's quite nice-looking code too.
Anyway, that's all I have to say on that. I had better crack on with some work.
If you know Ruby and see how I've messed things up, or could have done better: please let me know! I'm definitely a newbie when it comes to Ruby.
--
Adam