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

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
whisperjim (Guest)
on 2008-11-27 22:35
(Received via mailing list)
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.
Vladimir Fekete (Guest)
on 2008-11-28 00:13
(Received via mailing list)
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.
Hugh Sasse (Guest)
on 2008-11-28 00:14
(Received via mailing list)
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
Todd Benson (Guest)
on 2008-11-28 00:28
(Received via mailing list)
On Thu, Nov 27, 2008 at 3:30 PM, whisperjim <jgheal@googlemail.com>
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
310dc6cf5003e3957f2dc018e16556fd?d=identicon&s=25 List R. (listx300108u79872)
on 2008-11-28 04:18
(Received via mailing list)
On Nov 27, 2008, at 6:22 PM, "Todd Benson" <caduceass@gmail.com> 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
310dc6cf5003e3957f2dc018e16556fd?d=identicon&s=25 List R. (listx300108u79872)
on 2008-11-28 04:21
(Received via mailing list)
On Nov 27, 2008, at 6:22 PM, "Todd Benson" <caduceass@gmail.com> 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?
William James (Guest)
on 2008-11-29 00:35
(Received via mailing list)
On Nov 27, 5:22 pm, Todd Benson <caduce...@gmail.com> 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
Todd Benson (Guest)
on 2008-11-29 10:29
(Received via mailing list)
On Fri, Nov 28, 2008 at 5:29 PM, William James <w_a_x_man@yahoo.com>
wrote:
> On Nov 27, 5:22 pm, Todd Benson <caduce...@gmail.com> 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
Todd Benson (Guest)
on 2008-11-29 18:21
(Received via mailing list)
On Thu, Nov 27, 2008 at 9:15 PM, List.rb <list.rb@gmail.com> wrote:
>
> sorted << a.delete(a.min) until a.empty?

I like that!

Todd
D7f9a6f8d95b16bdc68b9cfcc957a21f?d=identicon&s=25 Sam H. (showes06)
on 2009-08-31 04:12
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
This topic is locked and can not be replied to.