** more spoilers **
2006/6/29, Justin C. [email protected]:
#if you can use Array#min:
list = [“aword”, “cword”, “gword”, “zword”, “dword”, “qword”, “pword”]
unsorted = []
sorted = []
sorted << list.min #add the smallest to sorted
unsorted = list - sorted #add the rest to unsorted
This setup code above is superfluous.
until unsorted.empty? #when unsorted is empty, we are done
sorted << unsorted.min #put the smallest value into sorted
unsorted.delete(unsorted.min) #take it out of unsorted
end
p sorted #all sorted!
You can do
list = [“aword”, “cword”, “gword”, “zword”, “dword”, “qword”, “pword”]
unsorted = list.dup
sorted = []
until unsorted.empty? #when unsorted is empty, we are done
sorted << unsorted.min #put the smallest value into sorted
unsorted.delete(unsorted.min) #take it out of unsorted
end
p sorted
#if you can’t use Array#min:
Here’s a shorter version using inject (of course):
require ‘enumerator’
unsorted = list.dup
sorted = []
until unsorted.empty?
min, pos = unsorted.
to_enum(:each_with_index).
inject {|(minel, minidx), (el, idx)| el < minel ? [el, idx] :
[minel, minidx]}
unsorted.delete_at pos
sorted << min
end
p sorted
This is the more verbose but equivalent version:
unsorted = list.dup
sorted = []
until unsorted.empty?
min = pos = nil
unsorted.each_with_index do |el, idx|
if min.nil? || el < min
min = el
pos = idx
end
end
unsorted.delete_at pos
sorted << min
end
p sorted
You can save one comparison op per loop if you do
unsorted = list.dup
sorted = []
until unsorted.empty?
unsorted is not empty, so there is an element at pos 0!
min = unsorted[0]
pos = 0
unsorted.each_with_index do |el, idx|
if el < min
min = el
pos = idx
end
end
unsorted.delete_at pos
sorted << min
end
p sorted
Kind regards
robert