From: whisperjim Date: 2008-11-28T04:35:09+09:00 Subject: Re: Chris Pine tutorial assistance chapter 7 sort data without use of .sort method On 25 Nov, 21:20, jgh...@googlemail.com wrote: > On Nov 25, 2:37 pm, Hugh Sasse wrote: > > > > > On Tue, 25 Nov 2008, jgh...@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 > > > > 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 > > >         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 On Wed, 26 Nov 2008, jgh...@googlemail.com wrote: > On Nov 25, 2:37 pm, Hugh Sasse wrote: > > [lots of stuff worth trimming] > # 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. 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 > 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 > 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.