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

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.

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.

···

On Fri, Nov 28, 2008 at 06:30:09AM +0900, whisperjim wrote:

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.

I'm working through the following tutorial Learn to Program, by Chris Pine
(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 ..

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

    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.

        Hugh

···

On Fri, 28 Nov 2008, whisperjim wrote:

Cheating...

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

Todd

···

On Thu, Nov 27, 2008 at 3:30 PM, whisperjim <jgheal@googlemail.com> wrote:

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.

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

···

--
Posted via http://www.ruby-forum.com/\.

Nice

···

On Nov 27, 2008, at 6:22 PM, "Todd Benson" <caduceass@gmail.com> wrote:

On Thu, Nov 27, 2008 at 3:30 PM, whisperjim <jgheal@googlemail.com> > wrote:

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.

Cheating...

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

Todd

Although this looks cleaner I think..

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

···

On Nov 27, 2008, at 6:22 PM, "Todd Benson" <caduceass@gmail.com> wrote:

On Thu, Nov 27, 2008 at 3:30 PM, whisperjim <jgheal@googlemail.com> > wrote:

I'm working through the following tutorial Learn to Program, by Chris Pine
(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.

Cheating...

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

Todd

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

···

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

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

···

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.

I like that!

Todd

···

On Thu, Nov 27, 2008 at 9:15 PM, List.rb <list.rb@gmail.com> wrote:

Cheating...

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

Todd

Although this looks cleaner I think..

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