Chris Pine tutorial assistance chapter 7 sort data without use of .sort method


#1

I’m learning to progam and came accross Chris P.'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


#2

On Tue, Nov 25, 2008 at 12:00 AM, removed_email_address@domain.invalid 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 :wink: or Sorting by minimum search

HTH
Robert


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

Robert D. :wink:


#3

On Nov 24, 11:14 pm, Robert D. removed_email_address@domain.invalid wrote:

HTH
Robert


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

Robert D. :wink:

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.


#4

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


#5

On Tue, 25 Nov 2008, removed_email_address@domain.invalid wrote:

I’m learning to progam and came accross Chris P.'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

#6

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


#7

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


#8

On Tue, Nov 25, 2008 at 4:15 PM, Giampiero Z. removed_email_address@domain.invalid 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.


#9

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 D. :wink:


#10

On Wed, 26 Nov 2008, removed_email_address@domain.invalid 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

#11

On Nov 25, 2:37 pm, Hugh S. removed_email_address@domain.invalid 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


#12

On 25 Nov, 21:20, removed_email_address@domain.invalid 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, removed_email_address@domain.invalid wrote:

On Nov 25, 2:37 pm, Hugh S. removed_email_address@domain.invalid 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.