Forum: Ruby Chris Pine tutorial assistance chapter 7 sort data without use of .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.
27e6171a66f1d99938f15d77f643e32f?d=identicon&s=25 unknown (Guest)
on 2008-11-25 00:05
(Received via mailing list)
I'm learning to progam and came accross Chris Pine's Ruby Tutorial.

I've got to the Array and Iterators chapter (
http://pine.fm/LearnToProgram/?Chapter=07
).

and 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? "

****** HOWEVER I'm not allowed to use the .sort method ********

The covered chapters (1 ~ 7) have not covered method creation,
Classes, Blocks or Procs, so the challenge is to solve the assignment
without using them ( which is dandy since I don't know what they are
and I want to solve this assignment before I move forward to discover
what they are).

This is what I've come up with so far, however when run.... It's not
working - surprise surprise.

Could someone initially give me an idea of what is going wrong rather
than rectify my code.

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

words_array = []

loop do
   input = gets.downcase.chomp
   break if input.empty?
   words_array << input

end

wordCheck = words_array.last
rotateCounter = 0
sortedWords_array = []
until words_array.length == 0
  while rotateCounter <= words_array.length
    if words_array[0] >= wordCheck

      words_array.push words_array.shift
      rotateCounter = rotateCounter + 1

    else wordCheck = words_array[0]
      rotateCounter = 0
    end

  end
  sortedWords_array.push wordCheck

  until wordCheck = words_array.last
    words_array.push words_array.shift
  end
  words_array.pop
  rotateCounter = 0
  wordCheck = words_array.last
end
puts sortedWords_array

# Any help greatly appreciated
703fbc991fd63e0e1db54dca9ea31b53?d=identicon&s=25 Robert Dober (Guest)
on 2008-11-25 00:19
(Received via mailing list)
On Tue, Nov 25, 2008 at 12:00 AM,  <jgheal@googlemail.com> wrote:
y
>
> # Any help greatly appreciated
>
>
http://en.wikipedia.org/wiki/Sorting_algorithm
Pick a simple on for starters; like Bubble Sort (though it is really a
stupid method ;) or Sorting by minimum search

HTH
Robert

--
Ne baisse jamais la tête, tu ne verrais plus les étoiles.

Robert Dober ;)
27e6171a66f1d99938f15d77f643e32f?d=identicon&s=25 unknown (Guest)
on 2008-11-25 15:25
(Received via mailing list)
On Nov 24, 11:14 pm, Robert Dober <robert.do...@gmail.com> wrote:
> HTH
> Robert
>
> --
> Ne baisse jamais la tête, tu ne verrais plus les étoiles.
>
> Robert Dober ;)

Thankyou for the responce.

What I'm worried about at the moment is the flow control? of my
program rather than the effiency. I'm using the built in
lexicographical ordering?? to compare strings i.e 'cat' < 'dog' .

Could you take a look at my program and give me a clue where I'm going
wrong?

Thanks again.
457cf540784a12ba2f30e06565a2c189?d=identicon&s=25 Hugh Sasse (Guest)
on 2008-11-25 15:42
(Received via mailing list)
On Tue, 25 Nov 2008, jgheal@googlemail.com wrote:

> I'm learning to progam and came accross Chris Pine's Ruby Tutorial.
>
> I've got to the Array and Iterators chapter ( http://pine.fm/LearnToProgram/?Chapter=07
> ).
>
> and 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? "

That's all fairly clear....
>
> ****** HOWEVER I'm not allowed to use the .sort method ********

That's also clear, you are writing a sort program to teach you about
programming, rather than to teach you to explore the library.
>
> The covered chapters (1 ~ 7) have not covered method creation,
> Classes, Blocks or Procs, so the challenge is to solve the assignment
> without using them ( which is dandy since I don't know what they are
> and I want to solve this assignment before I move forward to discover
> what they are).

OK
>
> This is what I've come up with so far, however when run.... It's not
> working - surprise surprise.
>
> Could someone initially give me an idea of what is going wrong rather
> than rectify my code.

This is rather difficult.  Why?

You have told us what the outcome of the program should be.
You have shown us a program that doesn't work.

There could be several things wrong, including the mental model you
have built.  It would be a big help to us in helping you if you told
us how you intended the program to work.  It may be that you have
misunderstood something, so expressed your idea poorly in code. Which
is OK of course, that's the point of learning.  It may be that the
algorithm you have chosen to implement doesn't work, so even if the
program implements it correctly, you won't get the answer you want..

So the next thing to learn about programming is that comments are to
express intention, to give people a bird's eye view of the code so they
can see what the programmer was trying to do, when that is not
immediately
obvious from the code, or when the code could be wrong, expressing
another
idea.

Add comments to this to explain your intentions about each major section
and then we can tell you if your code expresses that intention
>
>       rotateCounter = rotateCounter + 1
>   end
>   words_array.pop
>   rotateCounter = 0
>   wordCheck = words_array.last
> end
> puts sortedWords_array
>
> # Any help greatly appreciated
>

        Hugh
64aa4b69fdd7127e6f3ee16ae065a620?d=identicon&s=25 Giampiero Zanchi (giampiz)
on 2008-11-25 16:19
I am a beginner too;
I use to intermix my code with a lot of 'puts'; I think you could do it
as well;
your input part is ok; you can view it by means of

puts word_array.inspect

> words_array = []
>
> loop do
>    input = gets.downcase.chomp
>    break if input.empty?
>    words_array << input
> end

so, try insering some more puts in your script
I cannot understand the sort algorithm, so I cannot help, sorry
990bf71a4e84e1145a3131f35656dc18?d=identicon&s=25 List Rb (listx300108u79872)
on 2008-11-25 16:34
(Received via mailing list)
I'm ashamed to say I recently learned this, but thought is share just
in case you didn't know..

Instead of
puts something.inspect

You can use
p something

Quite a time saver
64aa4b69fdd7127e6f3ee16ae065a620?d=identicon&s=25 Giampiero Zanchi (giampiz)
on 2008-11-25 16:41
grazie (italian for thanks)

List Rb wrote:
> I'm ashamed to say I recently learned this, but thought is share just
> in case you didn't know..
>
> Instead of
> puts something.inspect
>
> You can use
> p something
>
> Quite a time saver

I have written a simple and rudimental script using min search sorting
words_array = []

loop do
   input = gets.downcase.chomp
   break if input.empty?
   words_array << input
end

puts words_array.inspect
sorted_array = []
until words_array.length == 0 do
  min = words_array.first
  min_index = 0
  words_array.each_index do |i|
    if words_array[i] < min then
      min_index = i
      min = words_array[i]
    end
  end
  sorted_array << min
  words_array.delete_at(min_index)
end
puts sorted_array.inspect
E088bb5c80fd3c4fd02c2020cdacbaf0?d=identicon&s=25 Jesús Gabriel y Galán (Guest)
on 2008-11-25 17:22
(Received via mailing list)
On Tue, Nov 25, 2008 at 4:15 PM, Giampiero Zanchi <cidza@tin.it> wrote:
> I am a beginner too;
> I use to intermix my code with a lot of 'puts'; I think you could do it
> as well;

Hi, I think it's better to use p instead of puts. p uses inspect on
the arguments, which is supposed to give you a better insight on what
is going on. Compare:

irb(main):001:0> a = %w{a b c d e}
=> ["a", "b", "c", "d", "e"]
irb(main):002:0> puts a
a
b
c
d
e
=> nil
irb(main):003:0> p a
["a", "b", "c", "d", "e"]

Jesus.
703fbc991fd63e0e1db54dca9ea31b53?d=identicon&s=25 Robert Dober (Guest)
on 2008-11-25 20:26
(Received via mailing list)
Try

p [:qua, some_obscure_variable]
p [:dove_vai?, even_more_obscure]
...
p [ :una_anitra, 42]

Well I guess you got the idea (and of course you know the -stupid?-
joke I am referring to ah yeah it cannot be translated BTW)

--
Ne baisse jamais la tête, tu ne verrais plus les étoiles.

Robert Dober ;)
27e6171a66f1d99938f15d77f643e32f?d=identicon&s=25 unknown (Guest)
on 2008-11-25 22:25
(Received via mailing list)
On Nov 25, 2:37 pm, Hugh Sasse <h...@dmu.ac.uk> wrote:
>
>
> > This is what I've come up with so far, however when run.... It's not
> There could be several things wrong, including the mental model you
> obvious from the code, or when the code could be wrong, expressing another
> > just \'enter\' a clear line.'
> > wordCheck = words_array.last
> >                    rotateCounter = 0
> >    wordCheck = words_array.last
> > end
> > puts sortedWords_array
>
> > # Any help greatly appreciated
>
>         Hugh

# basic mental model - store words in 1st array (words_array). Find
the 'smallest' word alphabetically by selecting the last word (call it
wordCheck) from words_array and compare wordCheck 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 words_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

# Hope the above is legible
457cf540784a12ba2f30e06565a2c189?d=identicon&s=25 Hugh Sasse (Guest)
on 2008-11-25 23:43
(Received via mailing list)
On Wed, 26 Nov 2008, jgheal@googlemail.com wrote:

> length of words_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.

I think this should work.  You will learn more efficient ways to do
this,
but this is a good start.  Knuth recommends thinking about how to solve
sorting problems yourself first, before consulting other algorithms.


>    break if input.empty?      # .. it 'input' , break from the loop if
> 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

>               end
>       words_array.pop                         # remove the last value contained within 
the 1st
>
So, what output do you get that is wrong?  This code works for me, for
the input "words"
a
b
a
c
a
b

        Hugh
27e6171a66f1d99938f15d77f643e32f?d=identicon&s=25 whisperjim (Guest)
on 2008-11-27 20:41
(Received via mailing list)
On 25 Nov, 21:20, jgh...@googlemail.com wrote:
> > > and the following assignment " Let's write a program which asks us to
>
>
> > us how you intended the program to work.  It may be that you have
>
> > >    break if input.empty?
>
> > >    until wordCheck = words_array.last
> >         Hugh
> wordCheck value from first unsorted array (words_array) and repeat
> 'enter' off the tail and lower the case and call ...
>
>                         rotateCounter = rotateCounter + 1 # add 1 to counter
>         until wordCheck = words_array.last      # rotate first array until a
> puts sortedWords_array  # print values within 2nd array, which should
> be in low to high alphabetical order
>
> # Hope the above is legible

On Wed, 26 Nov 2008, jgh...@googlemail.com wrote:
> On Nov 25, 2:37 pm, Hugh Sasse <h...@dmu.ac.uk> wrote:
> > [lots of stuff worth trimming]

> until words_array is empty.
I think this should work.  You will learn more efficient ways to do
this,
but this is a good start.  Knuth recommends thinking about how to
solve
sorting problems yourself first, before consulting other algorithms.

- Hide quoted text -
- Show quoted text -

> 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

> end
> puts sortedWords_array        # print values within 2nd array, which should
> be in low to high alphabetical order

> # Hope the above is legible

> So, what output do you get that is wrong?  This code works for me, for
> the input "words"
> a
> b
> a
> c
> a
> b

>        Hugh

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.

Thank you all for your time so far.
This topic is locked and can not be replied to.