patternrubyMinor
Find the lowest and second lowest values in an array of numbers
Viewed 0 times
thevaluesarraylowestnumberssecondfindand
Problem
Trying to find way to do this with only one pass through the array, so I won't run a sort on it and take arr[0..1]. Not sure how to make it look better:
def LowestSecondLowest(arr)
lowest,second_lowest = nil,nil
arr.each do |n|
if second_lowest.nil?
second_lowest=n
elsif lowest.nil?
if n>second_lowest
lowest=second_lowest
second_lowest=n
elsif nlowest && n<second_lowest
second_lowest=n
end
end
"#{lowest} #{second_lowest}"
endSolution
Because
Also I believe that in
With this in mind, I changed your code to obey these premises (and make it a bit more readable if I may say). Take a look.
If you want to test it
Array lets you put repeated elements of same value, I believe that the two lowest elements in [1, 2, 1] are [1, 1], not [1, 2]. This is the very same behavior one would face if sorting the array and getting the two first elements.Also I believe that in
[1] there is a lowest and no 2nd lowest (also, the very same behavior if sorting and getting the first two).With this in mind, I changed your code to obey these premises (and make it a bit more readable if I may say). Take a look.
def two_lowest arr
# if arr has no elements, there is no answer
# If arr has only one element, this is the lowest
if arr.size < 2 then
return arr.first, nil
end
lowest, second_lowest = nil, nil
arr.each do |n|
if lowest.nil? or n < lowest
# if we have no lowest or we found an element lower than current lowest,
# update our lowest and 2nd lowest
second_lowest = lowest
lowest = n
elsif second_lowest.nil? or n < second_lowest
# if we have no 2nd lowest or we found an element between lowest and 2nd
# lowest, update our 2nd lowest
second_lowest = n
end
end
return lowest, second_lowest
endIf you want to test it
tests = [
[],
[1],
[1, 1],
[1 ,2],
[1, 2, 1],
[1, 2, 3],
[1, 1, 2, 3],
[3, 2, 1, 1],
]
for test in tests
puts "In #{test}:"
puts "#{two_lowest test}"
puts
endCode Snippets
def two_lowest arr
# if arr has no elements, there is no answer
# If arr has only one element, this is the lowest
if arr.size < 2 then
return arr.first, nil
end
lowest, second_lowest = nil, nil
arr.each do |n|
if lowest.nil? or n < lowest
# if we have no lowest or we found an element lower than current lowest,
# update our lowest and 2nd lowest
second_lowest = lowest
lowest = n
elsif second_lowest.nil? or n < second_lowest
# if we have no 2nd lowest or we found an element between lowest and 2nd
# lowest, update our 2nd lowest
second_lowest = n
end
end
return lowest, second_lowest
endtests = [
[],
[1],
[1, 1],
[1 ,2],
[1, 2, 1],
[1, 2, 3],
[1, 1, 2, 3],
[3, 2, 1, 1],
]
for test in tests
puts "In #{test}:"
puts "#{two_lowest test}"
puts
endContext
StackExchange Code Review Q#156474, answer score: 3
Revisions (0)
No revisions yet.