William James <w_a_x_man@[EMAIL PROTECTED]
> writes Re: Euler problem #22
> On Apr 27, 3:51 pm, William James <w_a_x_...@[EMAIL PROTECTED]
> wrote:
>> On Apr 27, 7:29 am, m...@[EMAIL PROTECTED]
(Marcel Hendrix) wrote:
>> > The total of all the name scores in the file names.txt is
18,049,839,040
>> I arrive at a much smaller number.
> According to Project Euler, my result is correct.
Yes, your solution is correct. The names.txt file I was using had 4
linefeeds
in it. This was converted into negative (or unsigned exceptionally
"large") names.
Meanwhile I have gotten the right results too.
>> > 0.005 seconds elapsed. ok
> Since this problem takes so little time for the computer to solve,
> the amount of time needed to write the program is infinitely more
> im****tant. Making the program as fast as possible is simply a
> waste of human effort.
I see your point, but I was not trying to make it faster, just
deliberately
trying out a somewhat 'unconventional' approach.
> A shorter program:
> $names = IO.read("names.txt").scan(/[A-Z]+/).sort
> sum = 0
> $names.each_with_index do |name,i|
> sum += i.succ * name.split('').
> inject(0){|n,c| n + c[0] - ?A + 1}
> end
> p sum
I would be interested in a line-by-line comment. There's undoubted
large value here, and maybe it useful for other Eulers.
My guess is:
> $names = IO.read("names.txt").scan(/[A-Z]+/).sort
IO.read reads text files and returns them as some kind of object.
With the '.' methods of the file object can be triggered. (Apperently
the master object is an IO result and reading files is only one of its
methods).
The first method triggered is scan(/[A-Z]+/) . I guess the parameter
for the scan is a regular expression that describes a first name. Doing
it like this automatically throws away the quotes, comma's, linefeeds or
any other record or field delimiters. However, to fully understand how
this
operates I would need to understand on which representation of the file
scan() works. I guess simply a collection of raw characters. And what does
scan() return? I guess an array of strings. With that sort() probably
sorts
an array of strings in place, by default in lexicographic small-to-large
order.
In your previous program you did:
| $names = IO.read("names.txt").strip[1..-2].split( '","' ).sort
Here the split is probably breaking the file content with over ","
which would leave the first name with an unwanted quote, and the last
one can not be found properly because it doesn't end with "," but with
a single ". So I guess the strip[1..-2] removes the first byte and
adds two dummy characters at the end. Pretty specialized :-)
> sum = 0
> $names.each_with_index do |name,i|
Apparently the 'file object' is an array of strings, and it sup****ts
building an double index (one a string, the second a number) for it.
The two indexes are an uncommon construct for me.
How does each_with_index know what kind of indexes you mean? Or is it
always a string and a numeric one?
> sum += i.succ * name.split('').
An index (here i) is an object again that knows how to get its successor
(succ). The reason for name.split('') is unclear, but it could be
a trick to convert name into a number so that you get the right types
to multiply (or the right type for sum: probably an infinite precision
integer).
> inject(0){|n,c| n + c[0] - ?A + 1}
I have to pass this one.
Wait!
sum += i.succ * name.split('').inject(0){|n,c| n + c[0] - ?A + 1}
is probably how the language reads it. Apparently the split is a dummy
and the inject does the conversion from string to number. The syntax is
still not very obvious to me?
> end
> p sum
I would have expected sum.print
-marcel


|