[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Re: [SOLUTION][QUIZ] Panagrams (#86

Daniel Martin

7/10/2006 2:18:00 AM

Simon Kröger <SimonKroeger@gmx.de> writes:

> (this is my second version, the other one is longer and uses a slightly
> other algorithm (and is sometimes even faster) but i like this one)

Huh. I must say that when I saw your program, it wasn't at all what I
expected - namely, you are changing all 26 letters at once, and then
recalculating. I had assumed you were doing one letter at a time,
which I found to be much, much faster than doing all 26 at once.

I'm going to have to look into NArray, clearly. In fact, I think I'll
try converting my solution to use NArray.

4 Answers

Kroeger, Simon (ext)

7/10/2006 8:56:00 AM

0



> From: Daniel Martin [mailto:martin@snowplow.org]
> Sent: Monday, July 10, 2006 4:18 AM
>
> Simon Kröger <SimonKroeger@gmx.de> writes:
>
> > (this is my second version, the other one is longer and
> uses a slightly
> > other algorithm (and is sometimes even faster) but i like this one)
>
> Huh. I must say that when I saw your program, it wasn't at all what I
> expected - namely, you are changing all 26 letters at once, and then
> recalculating. I had assumed you were doing one letter at a time,
> which I found to be much, much faster than doing all 26 at once.

Ok, I will post my other version as soon as I'm home again.
Btw: nice idea to use Bignums :)

> I'm going to have to look into NArray, clearly. In fact, I think I'll
> try converting my solution to use NArray.

yes, some of the stuff is a little bit mind bending (using 'true' or
'false' for slicing dimensions for example) but you get true C speed
while implementing in ruby - that's fun.

cheers

Simon

Simon Kröger

7/10/2006 6:37:00 PM

0


>> Huh. I must say that when I saw your program, it wasn't at all what I
>> expected - namely, you are changing all 26 letters at once, and then
>> recalculating. I had assumed you were doing one letter at a time,
>> which I found to be much, much faster than doing all 26 at once.
>
> Ok, I will post my other version as soon as I'm home again.

Here is the second version (which was my first version):
--------------------------------------------------------------------
require 'narray'
class NArray; include Enumerable; end
srand(1)

NUMS = %w(no one two three four five six seven eight nine ten eleven) +
%w(twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen)
TENS = [nil] + %w(teen twenty thirty forty fifty sixty seventy eighty ninety)

class Fixnum
def to_english
return NUMS[self] if self < 20
return TENS[self / 10] if (self % 10).zero?
TENS[self / 10] + '-' + NUMS[self % 10]
end
end

class String
def to_na
count = NArray.byte(26)
each_byte do |b|
count[b - ?a] += 1 if b >= ?a and b <= ?z
count[b - ?A] += 1 if b >= ?A and b <= ?Z
end
count
end
end

text = "This is a pangram from simon, it contains "
number = (0..99).map{|i| i.to_english.to_na + (i > 1 ? 's' : '').to_na}
guess = NArray.byte(26).fill!(1)
real = guess + text.to_na + 'and'.to_na + (number[1] * 26)

i, r, g, changed = nil, nil, nil, true
while changed do
changed = false
26.times do |i|
g = guess[i]
r = real[i]
if g != r
real.sbt! number[g]
guess[i] = g = (g < r ? g : r) + rand((g - r).abs + 1)
real.add! number[g]
changed = true
end
end
end

s = guess.zip([*(' a'..' z')]).map{|g, l| g.to_english + l + (g>1 ? "'s":"")}
result = text + s[0..-2].join(', ') + ' and ' + s.last + '.'

puts result
puts(result.to_na == guess)
--------------------------------------------------------------------

It's quite similar except the loop.

cheers

Simon

Daniel Martin

7/11/2006 9:05:00 PM

0

Simon Kröger <SimonKroeger@gmx.de> writes:

> Here is the second version (which was my first version):
> --------------------------------------------------------------------
> --------------------------------------------------------------------
>
> It's quite similar except the loop.

Indeed, this is more what I expected - and this is a distinctly
different algorithm than the first solution you posted. In fact, your
main loop is pretty much identical to mine, except that you were using
NArray whereas I was using a bignum to hold the frequency. This meant
that it was much more cumbersome for me to extract each component and
update than it was for you.

I think that this algorithm itself is significantly faster than the
update-all-26-at-once version, and the only reason you see an
advantage to the update-all-26-at-once approach is because you can do
almost all of it by calling NArray vector operations.

Daniel Martin

7/13/2006 8:44:00 AM

0

"Nasir Khan" <rubylearner@gmail.com> writes:

> You may notice that I have tried both changing current value one at a time
> and also accumulating changes in @nchar_cnt_arr and changing in one go. The
> convergence has been elusive in either case.
> One way for me is to start looking at other solutions (which I will
> certainly do), but it would be a great help if someone points me towards a
> flaw in this.

I'll look more at your code later, but have you tried different
initial sentence parts? Specifically, have your tried the initial
bits that others were posting over the weekend?

I found that my code was unable to converge (after four hours) if I began with:

The program from martin@snowplow.org produced a sentence with

But when I switched to:

Daniel Martin's sallowsgram program produced a sentence with

I then got convergence in less than ten seconds. Some initial
sequences are just impossible to complete.