Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Ruby solution (don't have enough rep to post to codegolf):

  def mad_addr(a,b)
    a == b && a == 2 ? (a.object_id + b.object_id)/a : a + b
  end
Explanation: If a and b are both equal to 2 we can sum the values of the object_id's (the object_id of 2 is 5), and then divide the sum by 2. [Edit to add] For all other numbers this should behave as expected.

I just learned the object_id of 2 is 5 while doing this exercise, and I would like to continue learning more about how Ruby works. So if you have feedback, criticisms, or other ideas regarding this solution please feel free to share :)

[edit: added missing `=`]



a == b && a = 2 ? (a.object_id + b.object_id)/a : a + b

It looks like you are missing an equals sign on a == 2.

I just learned the object_id of 2 is 5 while doing this exercise, and I would like to continue learning more about how Ruby works. So if you have feedback, criticisms, or other ideas regarding this solution please feel free to share :)

The object_id appears to be the tagged pointer that contains the value cast to an integer. Ruby stores all of its data types using a single underlying C data type (called VALUE in the Ruby source), using the bottom two bits to identify special values that aren't really pointers. This is why Fixnum can only hold 31 or 63 bits instead of 32 or 64 (including sign), for example:

    # Ruby irb on a 32-bit system
    > (1<<30 - 1).class
    => Fixnum
    > (1<<30).class
    => Bignum
See also:

https://en.wikipedia.org/wiki/Tagged_pointer


Thanks, nitrogen. Following your info led to a couple of other neat discoveries, and a bunch more useful material [1].

As a result here are some new ways I learned to get 5 from 2 + 2:

  require 'fiddle'
  a = 2
  b = 2
  Fiddle::Pointer.new(a.object_id << 1).to_value.ceil + b
  => 5
Note: This happens because calling `to_value` on the `Fiddle::Pointer` object returns a Float (2.0000000000000004) instead of Fixnum (which was a surprise to me).

And here's another using `Object#tap`:

  a = 2
  (a + a).tap{|x| a = x + 1}.send(:eval,'a')
  => 5
[1] These links were helpful for me. The last one is an MIT licensed book called, "Kestrels, Quirky Birds, and Hopeless Egocentricity."

http://stackoverflow.com/questions/1872110/is-ruby-pass-by-r...

http://patshaughnessy.net/2014/1/9/how-big-is-a-bignum

http://stackoverflow.com/questions/2818602/in-ruby-why-does-...

http://combinators.info/#kestrels

Edit: line formatting


If you want to dig even deeper into the way Ruby works, I recommend trying to write a C extension (or at least reading the documentation):

http://www.ruby-doc.org/docs/ruby-doc-bundle/ProgrammingRuby...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: