[QUIZ] Symbolify (#169)

Discussion in 'Ruby' started by Matthew Moss, Jul 11, 2008.

  1. Matthew Moss

    Matthew Moss Guest

    -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

    The three rules of Ruby Quiz 2:

    1. Please do not post any solutions or spoiler discussion for this
    quiz until 48 hours have passed from the time on this message.

    2. Support Ruby Quiz 2 by submitting ideas as often as you can! (A
    permanent, new website is in the works for Ruby Quiz 2. Until then,
    please visit the temporary website at

    <http://splatbang.com/rubyquiz/>.

    3. Enjoy!
    Suggestion: A [QUIZ] in the subject of emails about the problem
    helps everyone on Ruby Talk follow the discussion. Please reply to
    the original quiz message, if you can.

    -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

    ## Symbolify (#169)

    Your task this week is to count. Yup, that's it.

    Oh, by the way... You may only use the characters `?`, `*`, `(`, `)` and `-`.

    Specifically, define a function `symbolify` that accepts an integer
    and returns a string composed of only the five characters shown above.
    The string, when evaluated, will equal the original number passed in.

    That is, the following test code should raise no exceptions:

    1000.times do |i|
    s = symbolify(i)
    raise "Not a string!" unless s.is_a? String
    raise "Invalid chars!" unless s.delete("?*()-").empty?

    x = eval(s)
    raise "Decode failed!" unless i == x
    end


    There are at least a few different approaches that come to mind, so
    don't expect everyone to have the same output. Well, not before the
    output is passed through `eval`, that is.

    I am not requiring that you produce the shortest string (though you
    are welcome to attempt such a thing). The only thing I _do_ ask is
    that you not produce megabytes of data to represent a simple integer.

    P.S. Cheating is encouraged (except that you may not write code
    outside of `symbolify`).



    --
    Matthew Moss <>
     
    Matthew Moss, Jul 11, 2008
    #1
    1. Advertising

  2. Matthew Moss

    ara.t.howard Guest

    On Jul 11, 2008, at 9:17 AM, Matthew Moss wrote:

    > That is, the following test code should raise no exceptions:
    >
    > 1000.times do |i|
    > s = symbolify(i)
    > raise "Not a string!" unless s.is_a? String
    > raise "Invalid chars!" unless s.delete("?*()-").empty?
    >
    > x = eval(s)
    > raise "Decode failed!" unless i == x
    > end


    i've got one line - tests pass.

    a @ http://codeforpeople.com/
    --
    we can deny everything, except that we have the possibility of being
    better. simply reflect on that.
    h.h. the 14th dalai lama
     
    ara.t.howard, Jul 11, 2008
    #2
    1. Advertising

  3. Matthew Moss

    Alex LeDonne Guest

    On Fri, Jul 11, 2008 at 12:12 PM, ara.t.howard <> wrote:
    >
    > On Jul 11, 2008, at 9:17 AM, Matthew Moss wrote:
    >
    >> That is, the following test code should raise no exceptions:
    >>
    >> 1000.times do |i|
    >> s = symbolify(i)
    >> raise "Not a string!" unless s.is_a? String
    >> raise "Invalid chars!" unless s.delete("?*()-").empty?
    >>
    >> x = eval(s)
    >> raise "Decode failed!" unless i == x
    >> end

    >
    > i've got one line - tests pass.
    >


    Me too. My method body is one line, 25 characters. Did you manage to
    stretch yours to 42? :)

    -A
     
    Alex LeDonne, Jul 11, 2008
    #3
  4. Matthew Moss

    ara.t.howard Guest

    On Jul 11, 2008, at 10:41 AM, Alex LeDonne wrote:

    > Me too. My method body is one line, 25 characters. Did you manage to
    > stretch yours to 42? :)




    haven't gone golfing yet - it's 74 now. you've guess my target
    accurately though ;-)


    a @ http://codeforpeople.com/
    --
    we can deny everything, except that we have the possibility of being
    better. simply reflect on that.
    h.h. the 14th dalai lama
     
    ara.t.howard, Jul 11, 2008
    #4
  5. Matthew Moss

    James Gray Guest

    On Jul 11, 2008, at 10:17 AM, Matthew Moss wrote:

    > ## Symbolify (#169)
    >
    > Your task this week is to count. Yup, that's it.
    >
    > Oh, by the way... You may only use the characters `?`, `*`, `(`, `)`
    > and `-`.


    Excellent quiz. Full marks Matthew. ;)

    James Edward Gray II
     
    James Gray, Jul 11, 2008
    #5
  6. Matthew Moss

    ara.t.howard Guest

    On Jul 11, 2008, at 11:07 AM, Dana Merrick wrote:

    > Haha, I just did it and my solution just happened to be 42 characters.



    damn - i've usurped!


    a @ http://codeforpeople.com/
    --
    we can deny everything, except that we have the possibility of being
    better. simply reflect on that.
    h.h. the 14th dalai lama
     
    ara.t.howard, Jul 11, 2008
    #6
  7. Matthew Moss

    James Gray Guest

    On Jul 11, 2008, at 12:16 PM, ara.t.howard wrote:

    >
    > On Jul 11, 2008, at 11:07 AM, Dana Merrick wrote:
    >
    >> Haha, I just did it and my solution just happened to be 42
    >> characters.

    >
    >
    > damn - i've usurped!


    Mine was 28 characters, with normal whitespace usage.

    James Edward Gray II
     
    James Gray, Jul 11, 2008
    #7
  8. Matthew Moss

    James Gray Guest

    On Jul 11, 2008, at 12:23 PM, James Gray wrote:

    > On Jul 11, 2008, at 12:16 PM, ara.t.howard wrote:
    >
    >>
    >> On Jul 11, 2008, at 11:07 AM, Dana Merrick wrote:
    >>
    >>> Haha, I just did it and my solution just happened to be 42
    >>> characters.

    >>
    >>
    >> damn - i've usurped!

    >
    > Mine was 28 characters, with normal whitespace usage.


    Of course, using my solution, the following code causes Ruby to
    Segfault:

    eval(symbolify(1200))

    James Edward Gray II
     
    James Gray, Jul 11, 2008
    #8
  9. Matthew Moss

    ara.t.howard Guest

    On Jul 11, 2008, at 11:22 AM, James Gray wrote:

    > Of course, using my solution, the following code causes Ruby to
    > Segfault:
    >
    > eval(symbolify(1200))


    a feature - no on needs numbers that big, 2 ** 10 should be enough for
    all computing

    a @ http://codeforpeople.com/
    --
    we can deny everything, except that we have the possibility of being
    better. simply reflect on that.
    h.h. the 14th dalai lama
     
    ara.t.howard, Jul 11, 2008
    #9
  10. Matthew Moss

    Chris Shea Guest

    Re: Symbolify (#169)

    On Jul 11, 10:41 am, Alex LeDonne <> wrote:
    > On Fri, Jul 11, 2008 at 12:12 PM, ara.t.howard <> wrote:
    >
    > > On Jul 11, 2008, at 9:17 AM, Matthew Moss wrote:

    >
    > >> That is, the following test code should raise no exceptions:

    >
    > >>   1000.times do |i|
    > >>     s = symbolify(i)
    > >>     raise "Not a string!"  unless s.is_a? String
    > >>     raise "Invalid chars!" unless s.delete("?*()-").empty?

    >
    > >>     x = eval(s)
    > >>     raise "Decode failed!" unless i == x
    > >>   end

    >
    > > i've got one line - tests pass.

    >
    > Me too. My method body is one line, 25 characters. Did you manage to
    > stretch yours to 42? :)
    >
    > -A


    And it works for negative integers too?

    Chris
     
    Chris Shea, Jul 11, 2008
    #10
  11. Matthew Moss

    Alex LeDonne Guest

    On Fri, Jul 11, 2008 at 1:19 PM, James Gray <> wrote:
    > On Jul 11, 2008, at 12:16 PM, ara.t.howard wrote:
    >
    >>
    >> On Jul 11, 2008, at 11:07 AM, Dana Merrick wrote:
    >>
    >>> Haha, I just did it and my solution just happened to be 42 characters.

    >>
    >>
    >> damn - i've usurped!

    >
    > Mine was 28 characters, with normal whitespace usage.
    >
    > James Edward Gray II
    >


    I managed to golf one char out of my first solution; it's 28 with
    "normal whitespace usage", 24 without. The output is ugly and long,
    though.


    I also have a longer solution that produces relatively compact
    representations relatively quickly such that

    symbolify(999).length == 145
    symbolify(9999).length == 145
    symbolify(999999).length == 389
    symbolify(12345678901234567890).length == 1290
    symbolify(("9"*2100).to_i).length == 402035

    -A
     
    Alex LeDonne, Jul 11, 2008
    #11
  12. Matthew Moss

    Matthew Moss Guest

    Re: Symbolify (#169)

    > > ## Symbolify (#169)
    >
    > > Your task this week is to count. Yup, that's it.

    >
    > > Oh, by the way... You may only use the characters `?`, `*`, `(`, `)` =

    =A0
    > > and `-`.

    >
    > Excellent quiz. =A0Full marks Matthew. =A0;)


    Somehow, with all the comparisons of how small solutions are, methinks
    there are other techniques that I hadn't considered. Mine own solution
    is short, but not *that* short.

    Though I haven't attempted to shrink it yet, so maybe I can make it
    smaller... Let's see...

    Okay, I can see how this can be seriously abused. But I guess I asked
    for it when I said "cheating encouraged!" No worries; it will be
    interesting to see how people do. I just wonder if anyone will write a
    solution that doesn't cheat. Or perhaps I'm still underestimating your
    solutions? Guess I'll see on Monday.
     
    Matthew Moss, Jul 11, 2008
    #12
  13. Matthew Moss

    Alex LeDonne Guest

    Re: Symbolify (#169)

    On Fri, Jul 11, 2008 at 1:57 PM, Chris Shea <> wrote:
    > On Jul 11, 10:41 am, Alex LeDonne <> wrote:
    >> On Fri, Jul 11, 2008 at 12:12 PM, ara.t.howard <> wrote:
    >>
    >> > On Jul 11, 2008, at 9:17 AM, Matthew Moss wrote:

    >>
    >> >> That is, the following test code should raise no exceptions:

    >>
    >> >> 1000.times do |i|
    >> >> s = symbolify(i)
    >> >> raise "Not a string!" unless s.is_a? String
    >> >> raise "Invalid chars!" unless s.delete("?*()-").empty?

    >>
    >> >> x = eval(s)
    >> >> raise "Decode failed!" unless i == x
    >> >> end

    >>
    >> > i've got one line - tests pass.

    >>
    >> Me too. My method body is one line, 25 characters. Did you manage to
    >> stretch yours to 42? :)
    >>
    >> -A

    >
    > And it works for negative integers too?
    >
    > Chris


    Hmm... that wasn't in the tests. That took 46 characters (so far) for
    my golfed solution.

    -A
     
    Alex LeDonne, Jul 11, 2008
    #13
  14. Matthew Moss

    ara.t.howard Guest

    Re: Symbolify (#169)

    On Jul 11, 2008, at 12:26 PM, Matthew Moss wrote:

    > I just wonder if anyone will write a
    > solution that doesn't cheat.


    no.

    a @ http://codeforpeople.com/
    --
    we can deny everything, except that we have the possibility of being
    better. simply reflect on that.
    h.h. the 14th dalai lama
     
    ara.t.howard, Jul 11, 2008
    #14
  15. Matthew Moss

    James Gray Guest

    Re: Symbolify (#169)

    On Jul 11, 2008, at 1:26 PM, Matthew Moss wrote:

    > Okay, I can see how this can be seriously abused. But I guess I asked
    > for it when I said "cheating encouraged!" No worries; it will be
    > interesting to see how people do. I just wonder if anyone will write a
    > solution that doesn't cheat. Or perhaps I'm still underestimating your
    > solutions? Guess I'll see on Monday.


    Mine builds strings using just the characters mentioned, so I doubt it
    would be classified as cheating.

    James Edward Gray II
     
    James Gray, Jul 11, 2008
    #15
  16. Matthew Moss

    Matthew Moss Guest

    Re: Symbolify (#169)

    This is not required extra work... just for a little more fun. I have
    some suspicions about some techniques, what I call "ugly" cheats (as
    opposed to the "pretty" cheats who ignored you in high school... umm,
    ignore that last part).

    Anyway, here's another test:

    nums = (0...1000).sort_by { rand }
    strs = nums.map { |n| symbolify(n) }

    strs.zip(nums).sort_by { rand }.each do |str, num|
    res = eval(str)
    raise "Not a string!" unless str.is_a? String
    raise "Invalid chars!" unless str.delete("?*()-").empty?
    raise "Decode failed!" unless res == num
    end

    puts "Passed!"


    This might affect some, maybe not others. I wrote two solutions, one
    classified as "pretty" while the other is "ugly" (i.e. fails this
    test). Again, you're not required to pass this... Looking at some ugly
    solutions will certainly be okay.

    Interestingly, my pretty solution confuses IRB. If I run on the
    command line:
    > ruby -r moss test.rb

    Passed!

    However, if I start up irb:
    > require 'moss'

    => true
    > symbolify(60)


    Then I get a nice stack crawl (not gonna show yet, spoiler) that ends
    in "Maybe IRB bug!!!". (I imagine you guys can guess what I'm
    doing...)
     
    Matthew Moss, Jul 11, 2008
    #16
  17. Matthew Moss

    Matthew Moss Guest

    Re: Symbolify (#169)

    Shortly after posting this, I realize that there could easily be ugly
    cheats that pass this test as well...

    You'd think I know Ruby a little better at this point in time... =)
     
    Matthew Moss, Jul 11, 2008
    #17
  18. Matthew Moss

    Alex LeDonne Guest

    On Fri, Jul 11, 2008 at 2:02 PM, Alex LeDonne
    <> wrote:
    > On Fri, Jul 11, 2008 at 1:19 PM, James Gray <> wrote:
    >> On Jul 11, 2008, at 12:16 PM, ara.t.howard wrote:
    >>
    >>>
    >>> On Jul 11, 2008, at 11:07 AM, Dana Merrick wrote:
    >>>
    >>>> Haha, I just did it and my solution just happened to be 42 characters.
    >>>
    >>>
    >>> damn - i've usurped!

    >>
    >> Mine was 28 characters, with normal whitespace usage.
    >>
    >> James Edward Gray II
    >>

    >
    > I managed to golf one char out of my first solution; it's 28 with
    > "normal whitespace usage", 24 without. The output is ugly and long,
    > though.
    >
    >
    > I also have a longer solution that produces relatively compact
    > representations relatively quickly such that
    >
    > symbolify(999).length == 145
    > symbolify(9999).length == 145
    > symbolify(999999).length == 389
    > symbolify(12345678901234567890).length == 1290
    > symbolify(("9"*2100).to_i).length == 402035
    >


    After clearing a "duh" moment, I've improved these encoded lengths...
    symbolify(999).length == 127
    symbolify(9999).length == 127
    symbolify(999999).length == 337
    symbolify(12345678901234567890).length == 1112
    symbolify(("9"*2100).to_i).length == 350265

    -A
     
    Alex LeDonne, Jul 11, 2008
    #18
  19. 2008/7/11 James Gray <>:
    > On Jul 11, 2008, at 12:16 PM, ara.t.howard wrote:
    >
    >>
    >> On Jul 11, 2008, at 11:07 AM, Dana Merrick wrote:
    >>
    >>> Haha, I just did it and my solution just happened to be 42 characters.

    >>
    >>
    >> damn - i've usurped!

    >
    > Mine was 28 characters, with normal whitespace usage.
    >
    > James Edward Gray II
    >
    >


    I managed to squeeze my solution in 19 characters and 23 with normal
    whitespace usage.

    Wouter Smeenk
     
    Wouter Smeenk, Jul 11, 2008
    #19
  20. Matthew Moss

    Chris Shea Guest

    Re: Symbolify (#169)

    On Jul 11, 12:57 pm, Matthew Moss <> wrote:
    > Anyway, here's another test:
    >
    >   nums = (0...1000).sort_by { rand }
    >   strs = nums.map { |n| symbolify(n) }
    >
    >   strs.zip(nums).sort_by { rand }.each do |str, num|
    >     res = eval(str)
    >     raise "Not a string!"  unless str.is_a? String
    >     raise "Invalid chars!" unless str.delete("?*()-").empty?
    >     raise "Decode failed!" unless res == num
    >   end
    >
    >   puts "Passed!"


    I've done some translating of these tests into test/unit (and some
    meta-programming to help me test multiple solutions easily. Here's
    what the end of my solution file looks like:

    ###
    require 'test/unit'

    class TestSymbolify < Test::Unit::TestCase
    @test_number = 1

    def self.solution_test(module_name, range, test=:delayed_eval_tests)
    class_eval <<-EOD
    def test_#{@test_number}_#{module_name.to_s.gsub('::','_')}
    Object.send:)include, #{module_name})
    #{test}(#{range})
    end
    EOD
    @test_number += 1
    end

    def symbolify_assertions_for(string, integer)
    assert_kind_of(String, string)
    assert_match(/\A[?*()-]*\Z/, string)
    assert_equal(integer, eval(string))
    end

    def cheat_friendly_tests(range)
    range.each do |i|
    s = symbolify(i)
    symbolify_assertions_for(s,i)
    end
    end

    def delayed_eval_tests(range)
    nums = range.sort_by { rand }
    strs = nums.map { |n| symbolify(n) }

    strs.zip(nums).sort_by { rand }.each do |s, i|
    symbolify_assertions_for(s,i)
    end
    end

    # The actual tests
    solution_test(Symbolify::Integers, -1000..1000)
    solution_test(Symbolify::NaturalNumbers, 0..1000)
    solution_test(Symbolify::Cheating,
    -1000..1000, :cheat_friendly_tests)
    end
    ###

    It might be a little much... but I *was* having fun.

    Chris
     
    Chris Shea, Jul 11, 2008
    #20
    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. BillLi
    Replies:
    0
    Views:
    171
    BillLi
    Jul 10, 2003
  2. Ruby Quiz

    [QUIZ] Animal Quiz (#15)

    Ruby Quiz, Jan 14, 2005, in forum: Ruby
    Replies:
    11
    Views:
    427
    James Edward Gray II
    Jan 18, 2005
  3. David Tran
    Replies:
    9
    Views:
    247
    David Tran
    Jan 21, 2005
  4. Ruby Quiz

    [QUIZ] 1-800-THE-QUIZ (#20)

    Ruby Quiz, Feb 18, 2005, in forum: Ruby
    Replies:
    15
    Views:
    353
    gabriele renzi
    Feb 24, 2005
  5. Matthew Moss

    [SUMMARY] Symbolify (#169)

    Matthew Moss, Jul 17, 2008, in forum: Ruby
    Replies:
    1
    Views:
    134
    Matthew Moss
    Jul 17, 2008
Loading...

Share This Page