Help w/ Codegolf Total Triangles- reading input

Discussion in 'Ruby' started by Drew Olson, Sep 24, 2006.

  1. Drew Olson

    Drew Olson Guest

    Hello all -

    I'm getting quite frustrated with a very "easy" part of this
    problem...reading the input! Basically, the input is given as so:

    1
    1 2
    1 3 2
    1 4 2 1

    What I intend to do is read the input line by line, split the lines by
    spaces and store each substring as the associated integer. Essentially I
    want to end up with a two dimensional array holding the integers shown
    above. I'm using the following line of code:

    a = readlines.each{|i|i.split(" ").each{|j|j=j.to_i}}

    However, when I do a puts I see the following:

    puts a[1][1] => 32

    GAH! Why is it printing the ascii character value? Do I have a logic
    flaw in the way I'm reading the input? Is there a better way to read the
    input? Should I just tear my hair out?

    Thanks,
    Drew

    --
    Posted via http://www.ruby-forum.com/.
     
    Drew Olson, Sep 24, 2006
    #1
    1. Advertising

  2. On Sep 23, 2006, at 10:44pm, Drew Olson wrote:

    > a = readlines.each{|i|i.split(" ").each{|j|j=j.to_i}}


    You don't want #each, but rather #map or #collect:

    a = readlines.map { |i| i.split(" ").map { |j| j.to_i } }

    And just as a point of style, some whitespace in there would read a
    whole lot better.

    --John
     
    John Labovitz, Sep 24, 2006
    #2
    1. Advertising

  3. Drew Olson

    Drew Olson Guest

    John -

    Thanks for the help...and with respect to white space, I apologize, I
    was in the codegolf mindset and trying to conserve bytes.
    http://www.codegolf.com

    Also, can you explain to me the difference between map and each?


    --
    Posted via http://www.ruby-forum.com/.
     
    Drew Olson, Sep 24, 2006
    #3
  4. On Sep 23, 2006, at 11:12pm, Drew Olson wrote:

    > Thanks for the help...and with respect to white space, I apologize, I
    > was in the codegolf mindset and trying to conserve bytes.
    > http://www.codegolf.com


    Ah, then the compression is forgiven. ;)

    > Also, can you explain to me the difference between map and each?


    #each just evaluates the block for each element of the list (or
    whatever you're iterating over). You don't usually use the return
    value of #each.

    #map (aka #collect) also evaluates the block for each element, but
    returns a new list containing the return value of each evaluation.
    It's good for translating one set of values to another, like you were
    doing in your code.

    --John
     
    John Labovitz, Sep 24, 2006
    #4
  5. John Labovitz <> wrote:

    Additional note: it's probably better to use #scan instead of split because
    then you can make sure to only get the numbers:

    a = readlines.map {|line| line.scan(/\d+/).map! {|s| s.to_i}}

    Kind regards

    robert
     
    Robert Klemme, Sep 24, 2006
    #5
  6. Drew Olson

    MonkeeSage Guest

    Drew Olson wrote:
    > GAH! Why is it printing the ascii character value? Do I have a logic
    > flaw in the way I'm reading the input? Is there a better way to read the
    > input? Should I just tear my hair out?


    Well firstly, because as others have mentioned, you were using #each,
    so you were getting an array populated with strings:

    ["1", "1 2", "1 3 2", "1 4 2 1"]
    ^
    ....and the 1-index of the 1-item of the array is a space (" ") -- ascii
    ordinal 32.

    But why doesn't ruby give you the space -- why the ordinal? Because in
    1.8, indexing a string by a single integer gives you the ascii ordinal
    for that character of the string (this changed in 1.9, now it gives you
    the character and you have to explicitly use #ord to get the ordinal).
    So, 'a'[0] => 97. If you ever need to get around that, just make the
    indexer into a range: 'a'[0,1] => a, 'a'[0..0] => a.

    Regards,
    Jordan
     
    MonkeeSage, Sep 24, 2006
    #6
  7. Drew Olson wrote:
    > Essentially I
    > want to end up with a two dimensional array holding the integers shown
    > above.

    Figure out your algorithm first.
     
    Devin Mullins, Sep 24, 2006
    #7
  8. Drew Olson

    Drew Olson Guest

    Devin Mullins wrote:
    > Drew Olson wrote:
    >> Essentially I
    >> want to end up with a two dimensional array holding the integers shown
    >> above.

    > Figure out your algorithm first.


    Devin -

    My first attempt at an algorithm was this:

    Work backwards row by row. In each row, compare the current element with
    the next, and whichever ever is larger, add this number to the element
    in the same index in the next highest row. Eventually, the value in
    a[0][0] will be the largest path...does this makes sense? Is it an
    effective strategy?

    --
    Posted via http://www.ruby-forum.com/.
     
    Drew Olson, Sep 24, 2006
    #8
  9. Drew Olson wrote:
    > Work backwards row by row. In each row, compare the current element with
    > the next, and whichever ever is larger, add this number to the element
    > in the same index in the next highest row. Eventually, the value in
    > a[0][0] will be the largest path...does this makes sense? Is it an
    > effective strategy?

    Yeah, that does seem like it'll work. I never thought of it that way.

    Think of the forwards algorithm, too. Then determine if the code you
    write with the backwards is 8 bytes shorter (to make up for reverse_each
    vs each). (I'll have to look at it, myself. :p)

    One more hint: You probably don't need to waste your time with map.
    Consider:
    a=readlines.each{|i|i.split(" ").each{|j|j=j.to_i}}
    a.reverse_each{|r|p r[0]}
    vs:
    readlines.reverse_each{|l|l.split(" ")[0].to_i}
    Again, try it both ways and see. (Keeping in mind that if the difference
    is small, then the winner's not certain -- the little optimizations
    could tip it either way.)

    I could suggest more things, but I don't wanna lose my spot. It's the
    one challenge at which I was actually successful. :)

    Devin
    Wow... acting as if I'm an expert after a few little internet
    challenges... Well, grain of salt and all that.
     
    Devin Mullins, Sep 24, 2006
    #9
  10. Drew Olson

    Guest

    Hi --

    On Mon, 25 Sep 2006, Devin Mullins wrote:

    > Drew Olson wrote:
    >> Work backwards row by row. In each row, compare the current element with
    >> the next, and whichever ever is larger, add this number to the element in
    >> the same index in the next highest row. Eventually, the value in a[0][0]
    >> will be the largest path...does this makes sense? Is it an effective
    >> strategy?

    > Yeah, that does seem like it'll work. I never thought of it that way.
    >
    > Think of the forwards algorithm, too. Then determine if the code you write
    > with the backwards is 8 bytes shorter (to make up for reverse_each vs each).
    > (I'll have to look at it, myself. :p)
    >
    > One more hint: You probably don't need to waste your time with map. Consider:
    > a=readlines.each{|i|i.split(" ").each{|j|j=j.to_i}}


    That just assigns the lines you've read in, unchanged, to a. In the
    outer each, you split lines and send the results, before you discard
    them, to the inner each -- where you reuse the identifier j, and then
    throw its new value away. Meanwhile, all a cares about is the return
    value of readlines.each, which is its receiver.

    I think maybe map is indeed called for :)


    David

    --
    David A. Black |
    Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
    DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
    [1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
    [2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
     
    , Sep 24, 2006
    #10
  11. wrote:
    >> a=readlines.each{|i|i.split(" ").each{|j|j=j.to_i}}

    > That just assigns the lines you've read in, unchanged, to a.

    That was a paste-o on my part. My point was that the functional means of
    doing things don't tend to golf well. Compare:
    a.map{|b|b.to_i}.each{|c|}
    a.each{|b|c=b.to_i}

    Devin
     
    Devin Mullins, Sep 24, 2006
    #11
  12. Drew Olson

    Guest

    Hi --

    On Mon, 25 Sep 2006, Devin Mullins wrote:

    > wrote:
    >>> a=readlines.each{|i|i.split(" ").each{|j|j=j.to_i}}

    >> That just assigns the lines you've read in, unchanged, to a.

    > That was a paste-o on my part. My point was that the functional means of
    > doing things don't tend to golf well. Compare:
    > a.map{|b|b.to_i}.each{|c|}
    > a.each{|b|c=b.to_i}


    Doesn't it depend what you need, though? Also, you can always do the
    each-like side-effect stuff with map, but not the map-like stuff with
    each.


    David

    --
    David A. Black |
    Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
    DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
    [1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
    [2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
     
    , Sep 24, 2006
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    4
    Views:
    335
  2. Frank Spychalski

    Codegolf - Writing a Brainf*ck interpreter

    Frank Spychalski, Aug 7, 2006, in forum: Ruby
    Replies:
    13
    Views:
    216
    Ben Bleything
    Aug 10, 2006
  3. Michael Ulm

    Codegolf - Pascals Triangle

    Michael Ulm, Aug 11, 2006, in forum: Ruby
    Replies:
    12
    Views:
    185
    Carlos
    Aug 11, 2006
  4. Drew Olson

    Compact if statement for Codegolf

    Drew Olson, Oct 11, 2006, in forum: Ruby
    Replies:
    10
    Views:
    222
    Rajat Garg
    Nov 23, 2007
  5. Drew Olson

    Codegolf: Pascal's Triangle

    Drew Olson, Jan 25, 2007, in forum: Ruby
    Replies:
    1
    Views:
    93
    Erik Veenstra
    Jan 25, 2007
Loading...

Share This Page