Symbolify (#169)

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

The three rules of Ruby Q. 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 Q. 2 by submitting ideas as often as you can! (A
    permanent, new website is in the works for Ruby Q. 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 T. 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).

On Jul 11, 2008, at 9:17 AM, Matthew M. 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/

On Fri, Jul 11, 2008 at 12:12 PM, ara.t.howard [email protected]
wrote:

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? :slight_smile:

-A

ara.t.howard wrote:

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? :slight_smile:

haven’t gone golfing yet - it’s 74 now. you’ve guess my target
accurately though :wink:

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

First quiz, too.

-Dana

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? :slight_smile:

haven’t gone golfing yet - it’s 74 now. you’ve guess my target
accurately though :wink:

a @ http://codeforpeople.com/

On Jul 11, 2008, at 11:07 AM, Dana M. wrote:

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

damn - i’ve usurped!

a @ http://codeforpeople.com/

On Jul 11, 2008, at 10:17 AM, Matthew M. 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. :wink:

James Edward G. II

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

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 G. II

On Jul 11, 2008, at 11:22 AM, James G. 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/

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

On Jul 11, 2008, at 11:07 AM, Dana M. 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 G. II

On Jul 11, 10:41 am, Alex LeDonne [email protected] wrote:

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? :slight_smile:

-A

And it works for negative integers too?

Chris

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. :wink:

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.

On Fri, Jul 11, 2008 at 1:19 PM, James G. [email protected]
wrote:

Mine was 28 characters, with normal whitespace usage.

James Edward G. 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

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

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

no.

a @ http://codeforpeople.com/

On Jul 11, 2008, at 1:26 PM, Matthew M. 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 G. II

On Fri, Jul 11, 2008 at 1:57 PM, Chris S. [email protected] wrote:

raise "Invalid chars!" unless s.delete("?*()-").empty?

-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

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… =)

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…)

On Fri, Jul 11, 2008 at 2:02 PM, Alex LeDonne
[email protected] wrote:

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

2008/7/11 James G. [email protected]:

Mine was 28 characters, with normal whitespace usage.

James Edward G. II

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

Wouter S.