Programming Noob Chris Pine Tutorial sorting without use ofarray.sort method

W

whisperjim

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.
 
V

Vladimir Fekete

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.


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.
 
H

Hugh Sasse

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 ..

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
 
T

Todd Benson

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
 
L

List.rb

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

Nice
 
L

List.rb

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?
 
W

William James

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 > ary[i+1]
ary[i,2] = ary[i,2].reverse
swapped = true
end
}
end
p ary
 
T

Todd Benson

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
 
S

Sam Howes

whisperjim said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,040
Latest member
papereejit

Latest Threads

Top