Programming Noob Chris Pine Tutorial sorting without use of array.sort method


#1

I’m working through the following tutorial
http://pine.fm/LearnToProgram/
(recommended by the official Ruby site)
as a starting point and I’ve got to chapter 7 and struggling with the
following assignment…

" Let’s write a program which asks us to type in as many words as we
want (one word per line, continuing until we just press Enter on an
empty line), and which then repeats the words back to us in
alphabetical order. OK? "

Now I’m supposed to do this without any .sort method and the chapters
I’ve covered so far (1 ~ 7) have not covered method creation,
Classes,Blocks or Procs, so the challenge is to solve the assignment
without using them.

Now I’ve written a program but I think the basic ‘mental model’ is
flawed, I say this because of the results I’m getting.

If I use the following input [ q w e r t y ] I end up with [ e q r t w
w ] and the input [ z x c v b ] end up as [ b b b b b ].

If my mental model is o.k, then my code must be wrong, but I’m stumped
at to where.

concept - store words in 1st array (words_array). Find the

‘smallest’ word alphabetically by selecting the last word (call it
wordCheck) and compare with the first word, second word and so on…
and exchange the value of wordCheck with the other word (1st/2nd…
word) if the other word value happens to be less. Start the checking
again with the first word, second word… and so on until a counter
has been reached (counter equal to current length of first unsorted
array). Once the counter has been reached, put the value of wordCheck
into a second array (sortedWords_array) and delete wordCheck value
from first unsorted array (words_array) and repeat until words_array
is empty.

puts ‘Type in as many words as you want and once you’ve had enough,
just ‘enter’ a clear line.’

words_array = [] # create 1st array called words_array to store users
unsorted values

loop do
input = gets.downcase.chomp # take the user input, remove the
‘enter’ off the tail and lower the case and call …
break if input.empty? # … it ‘input’ , break from the loop if
‘input’ is equal to empty
words_array << input # push ‘input’ to the words_array

end

wordCheck = words_array.last # wordCheck is equal to the last ‘input’
stored in the words_array
rotateCounter = 0
sortedWords_array = [] # create 2nd array to contain ‘sorted’ values

until words_array.length == 0 # exit once no words left in the first
unsorted array

while rotateCounter <= words_array.length # exit if rotate counter
greater than words contained within first array
if words_array[0] >= wordCheck # continue if first word in 1st array
greater or equal to wordCheck value

  words_array.push words_array.shift # rotate the first unsorted

array
rotateCounter = rotateCounter + 1 # add 1 to counter

else wordCheck = words_array[0] # replace current value (wordCheck)

with ‘smaller’ word
rotateCounter = 0 # reset counter to zero
end

end

sortedWords_array.push wordCheck # add wordCheck value to 2nd array

until wordCheck = words_array.last # rotate first array until a
matching …
words_array.push words_array.shift # … value found at the back of
the first array
end
words_array.pop # remove the last value contained within the
1st
array
rotateCounter = 0 # reset rotate counter
wordCheck = words_array.last # replace current value of wordCheck
with new last word from 1st array
end
puts sortedWords_array # print values within 2nd array, which should
be in low to high alphabetical order

Guidance greatly appreciated.


#2

Hi,

so If I’m correct what you are looking for is mistake in your sort
code,
right? (because - to be honest, I don’t really understand why (except
make
it an excercise for you) you do not look in google for sorting
algorithms.
One you described looks similar to Bubble sort. There are many others,
bubble
sort is most easies one and very slow but easy to implement.)

Regards

V.


#3

On Fri, 28 Nov 2008, whisperjim wrote:

Now I’m supposed to do this without any .sort method and the chapters
If my mental model is o.k, then my code must be wrong, but I’m stumped
into a second array (sortedWords_array) and delete wordCheck value
loop do
rotateCounter = 0
words_array.push words_array.shift # rotate the first unsorted
sortedWords_array.push wordCheck # add wordCheck value to 2nd array

until wordCheck = words_array.last # rotate first array until a
matching …

That line doesn’t do what you think it does. Took me a while to spot,
with
lots of printing stuff out.
Here’s a clue:

exit once no words left in the first unsorted array

be in low to high alphabetical order

Guidance greatly appreciated.

    Hugh

#4

On Thu, Nov 27, 2008 at 3:30 PM, whisperjim removed_email_address@domain.invalid
wrote:

Now I’m supposed to do this without any .sort method and the chapters
If my mental model is o.k, then my code must be wrong, but I’m stumped
into a second array (sortedWords_array) and delete wordCheck value
loop do
rotateCounter = 0
words_array.push words_array.shift # rotate the first unsorted
sortedWords_array.push wordCheck # add wordCheck value to 2nd array
with new last word from 1st array
end
puts sortedWords_array # print values within 2nd array, which should
be in low to high alphabetical order

Guidance greatly appreciated.

Cheating…

a = my_word_array
sorted = []
while !a.empty?; sorted << a.delete(a.min); end

Todd


#5

On Nov 27, 2008, at 6:22 PM, “Todd B.” removed_email_address@domain.invalid wrote:

empty line), and which then repeats the words back to us in
If I use the following input [ q w e r t y ] I end up with [ e q r
on…
puts 'Type in as many words as you want and once you’ve had enough,
if
‘sorted’ values
greater or equal to wordCheck value
rotateCounter = 0 # reset counter to zero
words_array.push words_array.shift # … value found
end

Todd

Nice


#6

On Nov 27, 2008, at 6:22 PM, “Todd B.” removed_email_address@domain.invalid wrote:

empty line), and which then repeats the words back to us in
If I use the following input [ q w e r t y ] I end up with [ e q r
on…
puts 'Type in as many words as you want and once you’ve had enough,
if
‘sorted’ values
greater or equal to wordCheck value
rotateCounter = 0 # reset counter to zero
words_array.push words_array.shift # … value found
end

Todd

Although this looks cleaner I think…

sorted << a.delete(a.min) until a.empty?


#7

On Fri, Nov 28, 2008 at 5:29 PM, William J. removed_email_address@domain.invalid
wrote:

On Nov 27, 5:22 pm, Todd B. removed_email_address@domain.invalid wrote:

Cheating…

a = my_word_array
sorted = []
while !a.empty?; sorted << a.delete(a.min); end

Fails when there are duplicates.

Absolutely. But, read the question again. It’s ambiguous if words
can be duplicated or not in the result. I thought about this for a
little while, and that’s why I said “Cheating…”

Todd


#8

On Nov 27, 5:22 pm, Todd B. removed_email_address@domain.invalid wrote:

Cheating…

a = my_word_array
sorted = []
while !a.empty?; sorted << a.delete(a.min); end

Fails when there are duplicates.

a = %w(one two three two four)
sorted = []
while !a.empty?; sorted << a.delete(a.min); end
p sorted

Try this:

ary = %w(bubble sort is so cute and quaint and
slow and it’s so simple that even I can remember
the algorithm)
swapped = true
while swapped do
swapped = false
(ary.size-1).times{|i|
if ary[i] > ary[i+1]
ary[i,2] = ary[i,2].reverse
swapped = true
end
}
end
p ary


#9

On Thu, Nov 27, 2008 at 9:15 PM, List.rb removed_email_address@domain.invalid wrote:

sorted << a.delete(a.min) until a.empty?

I like that!

Todd


#10

whisperjim wrote:

until wordCheck = words_array.last # rotate first array until a
matching …
words_array.push words_array.shift # … value found at the back of
the first array
end

your original code worked fine for me except you just have to add
another = after wordCheck to compare rather than to assign