[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

How would you write it vs Smalltalk

SpringFlowers AutumnMoon

9/22/2007 5:37:00 PM

i found a description of Smalltalk in

http://www.engin.umd.umich.edu/CIS/course.des/cis400/smalltalk...

and then I tried it in Ruby:


h = Hash.new(0)

print "Enter line: "

gets.downcase.each_byte {|b| c = "%c" % b; h[c] += 1 if c =~ /[a-z]/}

p h.sort


C:\rails\depot>ruby count_alpha2.rb
Enter line: This is a test of the line count
[["a", 1], ["c", 1], ["e", 3], ["f", 1], ["h", 2], ["i", 3], ["l", 1],
["n", 2],
["o", 2], ["s", 3], ["t", 5], ["u", 1]]

I just wonder how would you write it? There is no each_char it seems,
unless with ActiveSupport.
--
Posted via http://www.ruby-....

7 Answers

gabriele renzi

9/22/2007 5:49:00 PM

0

On Sun, 23 Sep 2007 02:37:28 +0900, SpringFlowers AutumnMoon wrote:


> I just wonder how would you write it? There is no each_char it seems,
> unless with ActiveSupport.

running away but a quick idea: you could use Integer#chr to get a char
(well, a one-byte-string) from an integer.
And, since you're dwelling with bytes anyway, you could just do a test
like
if c =~ ?a..?z
(?a being the literal to get the integer value of a character)

So something like:
gets.downcase.each_byte {|b| h[c.chr] += 1 if c =~ ?a..?z}



--
goto 10: http://www...
blog it: http://riffraff.bl...
blog en: http://www.rif...

Rick DeNatale

9/22/2007 6:40:00 PM

0

On 9/22/07, gabriele renzi <rff_rffREMOVE@yahoo.it> wrote:
> On Sun, 23 Sep 2007 02:37:28 +0900, SpringFlowers AutumnMoon wrote:
>
>
> > I just wonder how would you write it? There is no each_char it seems,
> > unless with ActiveSupport.

>
> So something like:
> gets.downcase.each_byte {|b| h[c.chr] += 1 if c =~ ?a..?z}

Here's another way:

puts "Enter line:"
h = Hash.new(0)
gets.scan(/[a-zA-Z]/) {|ch| h[ch.downcase] += 1 }
p h.sort

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

Simon Kröger

9/23/2007 10:39:00 AM

0

Rick DeNatale schrieb:
> On 9/22/07, gabriele renzi <rff_rffREMOVE@yahoo.it> wrote:
>> On Sun, 23 Sep 2007 02:37:28 +0900, SpringFlowers AutumnMoon wrote:
>>
>>
>>> I just wonder how would you write it? There is no each_char it seems,
>>> unless with ActiveSupport.
>
>> So something like:
>> gets.downcase.each_byte {|b| h[c.chr] += 1 if c =~ ?a..?z}
>
> Here's another way:
>
> puts "Enter line:"
> h = Hash.new(0)
> gets.scan(/[a-zA-Z]/) {|ch| h[ch.downcase] += 1 }
> p h.sort

Well, we need an inject solution, right?

p gets.downcase.scan(/[a-z]/).inject({}){|h,c| h.merge({c,h[c].to_i+1})}.sort

cheers

Simon

7stud 7stud

9/23/2007 10:47:00 PM

0

Simon Kröger wrote:
> Rick DeNatale schrieb:
>> Here's another way:
>>
>> puts "Enter line:"
>> h = Hash.new(0)
>> gets.scan(/[a-zA-Z]/) {|ch| h[ch.downcase] += 1 }
>> p h.sort
>
> Well, we need an inject solution, right?
>
> p gets.downcase.scan(/[a-z]/).inject({}){|h,c|
> h.merge({c,h[c].to_i+1})}.sort
>

How about:

p gets.downcase.scan(/[a-z]/).inject(Hash.new(0)){|h, c| h[c]+= 1;
h}.sort
--
Posted via http://www.ruby-....

7stud 7stud

9/24/2007 1:01:00 AM

0

And this seems conceptually easier and it's slightly faster(if I
benchmarked it correctly):

input = gets
h = Hash.new(0)

input.scan(/[a-z]/){|char| h[char] += 1}
p h.sort


============

require "benchmark"

input = "123Hello+#"

h = Hash.new(0)
Benchmark.bm(20) do |br|
br.report("scan with block:") do
200_000.times do
input.downcase.scan(/[a-z]/){|char| h[char] += 1}
end
end
end

p h.sort
puts

h = Hash.new(0)
Benchmark.bm(20) do |br|
br.report("scan with inject:") do
200_000.times do
input.downcase.scan(/[a-z]/).inject(h) do |h, c|
h[c] += 1
h
end
end
end
end

p h.sort

--output:--

user system total real
scan with block: 2.690000 0.010000 2.700000 ( 2.714077)
[["e", 200000], ["h", 200000], ["l", 400000], ["o", 200000]]

user system total real
scan with inject: 2.830000 0.020000 2.850000 ( 2.856019)
[["e", 200000], ["h", 200000], ["l", 400000], ["o", 200000]]
--
Posted via http://www.ruby-....

7stud 7stud

9/24/2007 1:58:00 AM

0

7stud -- wrote:
> And this seems conceptually easier and it's slightly faster(if I
> benchmarked it correctly):
>
> input = gets
> h = Hash.new(0)
>
> input.scan(/[a-z]/){|char| h[char] += 1}
> p h.sort


Whoops. I didn't downcase the input in that example, but I did downcase
the input in the benchmark tests. In any case, apologies to Rick
Denatale who already posted that solution.
--
Posted via http://www.ruby-....

Brian Adkins

9/24/2007 4:08:00 AM

0

On Sep 22, 2:39 pm, "Rick DeNatale" <rick.denat...@gmail.com> wrote:
> On 9/22/07, gabriele renzi <rff_rffREM...@yahoo.it> wrote:
>
> > On Sun, 23 Sep 2007 02:37:28 +0900, SpringFlowers AutumnMoon wrote:
>
> > > I just wonder how would you write it? There is no each_char it seems,
> > > unless with ActiveSupport.
>
> > So something like:
> > gets.downcase.each_byte {|b| h[c.chr] += 1 if c =~ ?a..?z}
>
> Here's another way:
>
> puts "Enter line:"
> h = Hash.new(0)
> gets.scan(/[a-zA-Z]/) {|ch| h[ch.downcase] += 1 }
> p h.sort

More verbose but a teensy bit quicker by avoiding regex & downcase:

lambda do |str|
h = Hash.new(0)
str.each_byte do |b|
if (b > 96 && b < 123)
h[b.chr] += 1
elsif (b > 64 && b < 91)
h[(b+32).chr] += 1
end
end
h
end