# \[QUIZ\] Symbolify (#169)

**URL:** <https://rubytalk.org/t/quiz-symbolify-169/47650>\
**Category:** ruby-talk\
**Created:** [11 July 2008 15:17 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650 "2008-07-11T15:17:15Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Matthew\_D\_Moss1](https://avatars.discourse-cdn.com/v4/letter/m/91b2a8/32.png) [@Matthew\_D\_Moss1](https://rubytalk.org/u/Matthew_D_Moss1)\
**Post date:** [11 July 2008 15:17 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/1 "2008-07-11T15:17:15Z")

</div>



---

<div class="post-metadata">

**Author:** ![a11](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/a11/32/8169_2.png) [@a11](https://rubytalk.org/u/a11)\
**Post date:** [11 July 2008 16:12 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/2 "2008-07-11T16:12:32Z")

</div>

i've got one line - tests pass.

a @ [http://codeforpeople.com/](http://codeforpeople.com/)

> **···**
>
> On Jul 11, 2008, at 9:17 AM, Matthew Moss wrote:
> 
> > That is, the following test code should raise no exceptions:
> > 
> > &nbsp;&nbsp;&nbsp;1000.times do |i|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = symbolify(i)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Not a string!" unless s.is\_a? String  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Invalid chars!" unless s.delete("?\*()-").empty?
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x = eval(s)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Decode failed!" unless i == x  
> > &nbsp;&nbsp;&nbsp;end
> 
> --  
> we can deny everything, except that we have the possibility of being better. simply reflect on that.  
> h.h. the 14th dalai lama

---

<div class="post-metadata">

**Author:** ![James\_Edward\_Gray\_II](https://avatars.discourse-cdn.com/v4/letter/j/ea5d25/32.png) [@James\_Edward\_Gray\_II](https://rubytalk.org/u/James_Edward_Gray_II)\
**Post date:** [11 July 2008 17:14 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/3 "2008-07-11T17:14:54Z")

</div>

Excellent quiz. Full marks Matthew. 😉

James Edward Gray II

> **···**
>
> 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 `-`.

---

<div class="post-metadata">

**Author:** ![Matthew\_D\_Moss1](https://avatars.discourse-cdn.com/v4/letter/m/91b2a8/32.png) [@Matthew\_D\_Moss1](https://rubytalk.org/u/Matthew_D_Moss1)\
**Post date:** [11 July 2008 18:57 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/4 "2008-07-11T18:57:58Z")

</div>

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:

&nbsp;&nbsp;nums = (0...1000).sort\_by { rand }  
&nbsp;&nbsp;strs = nums.map { |n| symbolify(n) }

&nbsp;&nbsp;strs.zip(nums).sort\_by { rand }.each do |str, num|  
&nbsp;&nbsp;&nbsp;&nbsp;res = eval(str)  
&nbsp;&nbsp;&nbsp;&nbsp;raise "Not a string!" unless str.is\_a? String  
&nbsp;&nbsp;&nbsp;&nbsp;raise "Invalid chars!" unless str.delete("?\*()-").empty?  
&nbsp;&nbsp;&nbsp;&nbsp;raise "Decode failed!" unless res == num  
&nbsp;&nbsp;end

&nbsp;&nbsp;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:  
&nbsp;&nbsp;&nbsp;\> ruby -r moss test.rb  
&nbsp;&nbsp;&nbsp;Passed!

However, if I start up irb:  
&nbsp;&nbsp;&nbsp;\> require 'moss'  
&nbsp;&nbsp;&nbsp;=\> true  
&nbsp;&nbsp;&nbsp;\> 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...)

---

<div class="post-metadata">

**Author:** ![krusty.ar](https://avatars.discourse-cdn.com/v4/letter/k/f14d63/32.png) [@krusty.ar](https://rubytalk.org/u/krusty.ar)\
**Post date:** [12 July 2008 23:50 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/5 "2008-07-12T23:50:41Z")

</div>

eval(symbolify(1200))  
p symbolify(999).length  
p symbolify(9999).length  
p symbolify(999999).length  
p symbolify(12345678901234567890).length  
p symbolify(("9"\*2100).to\_i).length  
nums = (0...1000).sort\_by { rand }  
strs = nums.map { |n| symbolify(n) }  
strs.zip(nums).sort\_by { rand }.each do |str, num|  
&nbsp;&nbsp;res = eval(str)  
&nbsp;&nbsp;raise "Not a string!" unless str.is\_a? String  
&nbsp;&nbsp;raise "Invalid chars!" unless str.delete("?\*()-").empty?  
&nbsp;&nbsp;raise "Decode failed!" unless res == num  
end  
puts "Passed!"

outputs:  
3  
4  
6  
20  
2100  
Passed!

Now I'm going for the no cheating.

Lucas

> **···**
>
> On Jul 11, 12:17 pm, Matthew Moss \<matthew.m...@gmail.com\> wrote:
> 
> > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-  
> > ## Symbolify (#169)

---

<div class="post-metadata">

**Author:** ![Dvorkin\_Mike](https://avatars.discourse-cdn.com/v4/letter/d/9fc348/32.png) [@Dvorkin\_Mike](https://rubytalk.org/u/Dvorkin_Mike)\
**Post date:** [13 July 2008 07:44 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/6 "2008-07-13T07:44:39Z")

</div>

23 characters symbolify(i) body, no cheating.

> **···**
>
> On Jul 11, 2008, at 8:17 AM, Matthew Moss wrote:
> 
> > &nbsp;&nbsp;&nbsp;1000.times do |i|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = symbolify(i)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Not a string!" unless s.is\_a? String  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Invalid chars!" unless s.delete("?\*()-").empty?
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x = eval(s)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Decode failed!" unless i == x  
> > &nbsp;&nbsp;&nbsp;end

---

<div class="post-metadata">

**Author:** ![A\_LeDonne](https://avatars.discourse-cdn.com/v4/letter/a/6bbea6/32.png) [@A\_LeDonne](https://rubytalk.org/u/A_LeDonne)\
**Post date:** [13 July 2008 15:17 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/7 "2008-07-13T15:17:52Z")

</div>

My golfed solutions (with whitespace for readability):

def symbolify\_1(i)  
&nbsp;&nbsp;&nbsp;&nbsp;# natural numbers only  
&nbsp;&nbsp;&nbsp;&nbsp;"??-??" + "-?(--?)" \* i  
end

def symbolify\_2(i)  
&nbsp;&nbsp;&nbsp;&nbsp;# all integers  
&nbsp;&nbsp;&nbsp;&nbsp;"??-??" + (i\<0 ? "-?)--?(" : "-?(--?)") \* i.abs  
end

-A

> **···**
>
> On Fri, Jul 11, 2008 at 11:17 AM, Matthew Moss \<matthew.moss@gmail.com\> wrote:
> 
> > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> > 
> > 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
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;\<[http://splatbang.com/rubyquiz/&gt;\](http://splatbang.com/rubyquiz/&gt;%5C).
> > 
> > 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:
> > 
> > &nbsp;&nbsp;&nbsp;1000.times do |i|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = symbolify(i)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Not a string!" unless s.is\_a? String  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Invalid chars!" unless s.delete("?\*()-").empty?
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x = eval(s)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Decode failed!" unless i == x  
> > &nbsp;&nbsp;&nbsp;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@gmail.com\>

---

<div class="post-metadata">

**Author:** ![Matthew\_D\_Moss1](https://avatars.discourse-cdn.com/v4/letter/m/91b2a8/32.png) [@Matthew\_D\_Moss1](https://rubytalk.org/u/Matthew_D_Moss1)\
**Post date:** [13 July 2008 16:08 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/8 "2008-07-13T16:08:48Z")

</div>

My first version cheats a bit, but passes the tests. Converts the num  
to base-5 and back.

def symbolify(num)  
&nbsp;&nbsp;def eval(str)  
&nbsp;&nbsp;&nbsp;&nbsp;[str.tr](http://str.tr)('(?\*)-', '01234').to\_i(5)  
&nbsp;&nbsp;end  
&nbsp;&nbsp;num.to\_s(5).tr('01234', '(?\*)-')  
end

My second solution cheats badly, failing the delayed eval test. Still,  
it's a single line of length 42. 🙂

def symbolify(num)  
&nbsp;&nbsp;def eval(str) $num end; $num = num; "()"  
end

I need to finish my non-cheating version...

---

<div class="post-metadata">

**Author:** ![Jason\_Dew1](https://avatars.discourse-cdn.com/v4/letter/j/6f9a4e/32.png) [@Jason\_Dew1](https://rubytalk.org/u/Jason_Dew1)\
**Post date:** [13 July 2008 16:18 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/9 "2008-07-13T16:18:25Z")

</div>

Here's my long and expensive search:

module Symbolify

&nbsp;&nbsp;#allowed characters: ? \* ( ) -

&nbsp;&nbsp;PRIMITIVES = { 40 =\> "?(", 41 =\> "?)", 42 =\> "?\*", 45 =\> "?-", 63 =\>  
"??" }  
&nbsp;&nbsp;OPERATIONS = [:add, :subtract, :multiply, :exponentiate]

&nbsp;&nbsp;def symbolify target  
&nbsp;&nbsp;&nbsp;&nbsp;@cache ||= Hash.new

&nbsp;&nbsp;&nbsp;&nbsp;result = search PRIMITIVES, PRIMITIVES, target  
&nbsp;&nbsp;&nbsp;&nbsp;return result if result

&nbsp;&nbsp;&nbsp;&nbsp;result = search cache\_copy, PRIMITIVES, target  
&nbsp;&nbsp;&nbsp;&nbsp;return result if result

&nbsp;&nbsp;&nbsp;&nbsp;result = search PRIMITIVES, cache\_copy, target  
&nbsp;&nbsp;&nbsp;&nbsp;return result if result

&nbsp;&nbsp;&nbsp;&nbsp;result = search cache\_copy, cache\_copy, target  
&nbsp;&nbsp;&nbsp;&nbsp;return result if result

&nbsp;&nbsp;&nbsp;&nbsp;nil  
&nbsp;&nbsp;end

&nbsp;&nbsp;private

&nbsp;&nbsp;def cache\_copy  
&nbsp;&nbsp;&nbsp;&nbsp;@cache.dup  
&nbsp;&nbsp;end

&nbsp;&nbsp;def search alpha\_space, beta\_space, target  
&nbsp;&nbsp;&nbsp;&nbsp;alpha\_space.each do |(value\_of\_a, a)|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;beta\_space.each do |(value\_of\_b, b)|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expression = evaluate(a, b, target)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return expression if expression  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;nil  
&nbsp;&nbsp;end

&nbsp;&nbsp;def evaluate a, b, target  
&nbsp;&nbsp;&nbsp;&nbsp;OPERATIONS.each do |op|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expression = send(op, a, b)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next unless expression

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = eval(expression)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@cache[value] ||= expression if value \>= 0 and value \<= 1000

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return expression if value == target  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;nil  
&nbsp;&nbsp;end

&nbsp;&nbsp;def add a, b  
&nbsp;&nbsp;&nbsp;&nbsp;"(#{a}--#{b})"  
&nbsp;&nbsp;end

&nbsp;&nbsp;def subtract a, b  
&nbsp;&nbsp;&nbsp;&nbsp;return nil unless eval(a) \>= eval(b)  
&nbsp;&nbsp;&nbsp;&nbsp;"(#{a}-#{b})"  
&nbsp;&nbsp;end

&nbsp;&nbsp;def multiply a, b  
&nbsp;&nbsp;&nbsp;&nbsp;"(#{a}\*#{b})"  
&nbsp;&nbsp;end

&nbsp;&nbsp;def exponentiate a, n  
&nbsp;&nbsp;&nbsp;&nbsp;return nil unless eval(n) \<= 10  
&nbsp;&nbsp;&nbsp;&nbsp;"(#{a}\*\*#{n})"  
&nbsp;&nbsp;end

end

> **···**
>
> On Jul 11, 11:17 am, "Matthew Moss" \<matthew.m...@gmail.com\> wrote:
> 
> > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> > 
> > 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
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<[http://splatbang.com/rubyquiz/&gt;\](http://splatbang.com/rubyquiz/&gt;%5C).
> > 
> > 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:
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;1000.times do |i|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = symbolify(i)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Not a string!" unless s.is\_a? String  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Invalid chars!" unless s.delete("?\*()-").empty?
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x = eval(s)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Decode failed!" unless i == x  
> > &nbsp;&nbsp;&nbsp;&nbsp;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.m...@gmail.com\>

---

<div class="post-metadata">

**Author:** ![Dvorkin\_Mike](https://avatars.discourse-cdn.com/v4/letter/d/9fc348/32.png) [@Dvorkin\_Mike](https://rubytalk.org/u/Dvorkin_Mike)\
**Post date:** [13 July 2008 16:38 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/10 "2008-07-13T16:38:13Z")

</div>

After sleeping on it, I'm down to 19 chars, no cheating:

def symbolify(i)  
"?\*-?\*"+"-?)--?\*"\*i  
end

&nbsp;&nbsp;&nbsp;&nbsp;1000.times do |i|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = symbolify(i)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Not a string!" unless s.is\_a? String  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Invalid chars!" unless s.delete("?\*()-").empty?

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

&nbsp;&nbsp;&nbsp;&nbsp;puts "Passed!"

---

<div class="post-metadata">

**Author:** ![Martin\_Boese](https://avatars.discourse-cdn.com/v4/letter/m/35a633/32.png) [@Martin\_Boese](https://rubytalk.org/u/Martin_Boese)\
**Post date:** [13 July 2008 17:18 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/11 "2008-07-13T17:18:12Z")

</div>

My solution:

def symbolify(i)  
("?)-?(--"\*i)[0..-3]  
end

However, at about 3300 I get a SystemStackError and if I start at like 5000 I  
segfault the ruby interpreter (1.8.6) 😉

martin

> **···**
>
> On Friday 11 July 2008 16:17:15 Matthew Moss wrote:
> 
> > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> > 
> > 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
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<[http://splatbang.com/rubyquiz/&gt;\](http://splatbang.com/rubyquiz/&gt;%5C).
> > 
> > 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:
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;1000.times do |i|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = symbolify(i)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Not a string!" unless s.is\_a? String  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Invalid chars!" unless s.delete("?\*()-").empty?
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x = eval(s)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Decode failed!" unless i == x  
> > &nbsp;&nbsp;&nbsp;&nbsp;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`).

---

<div class="post-metadata">

**Author:** ![krusty.ar](https://avatars.discourse-cdn.com/v4/letter/k/f14d63/32.png) [@krusty.ar](https://rubytalk.org/u/krusty.ar)\
**Post date:** [13 July 2008 19:25 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/12 "2008-07-13T19:25:56Z")

</div>

I thought by cheating you meant duck typing, not rewriting eval:

def symbolify (n)  
&nbsp;&nbsp;s = "#{n}"  
&nbsp;&nbsp;def s.delete(\*args)  
&nbsp;&nbsp;&nbsp;&nbsp;""  
&nbsp;&nbsp;end  
&nbsp;&nbsp;s  
end

Lucas.

> **···**
>
> On Jul 11, 12:17 pm, Matthew Moss \<matthew.m...@gmail.com\> wrote:
> 
> > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-  
> > ## Symbolify (#169)

---

<div class="post-metadata">

**Author:** ![Bill\_Kelly](https://avatars.discourse-cdn.com/v4/letter/b/cc9497/32.png) [@Bill\_Kelly](https://rubytalk.org/u/Bill_Kelly)\
**Post date:** [13 July 2008 20:19 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/13 "2008-07-13T20:19:55Z")

</div>

Enjoyed the quiz - thanks! Here are my solutions...

# First, the CHEAT versions.

# The first is an 18-character Kobayashi Maru cheat,  
# i.e., following the teachings of Adm. James T Kirk,  
# "I reprogrammed the simulation... I don't like to lose."

def symbolify(i)  
&nbsp;&nbsp;def raise(a)end;""  
end

# Next, the 14-character uber-cheeze... (Yes, it # outputs the success indicator on stderr instead  
# of stdout, ... but who's going to notice? 🙂

def symbolify(i)  
&nbsp;&nbsp;abort"Passed!"  
end

# Finally, the NON-CHEAT versions.  
# Nothing special but here's what I came up with:

# Default version. Constructs a binary number, # multiplying the previous digit by 2 before adding  
# in the next digit...

def symbolify(i)  
&nbsp;&nbsp;x="(?(-?()";i.to\_s(2).each\_byte{|d|x="(#{x}\*(?\*-?()--(?#{(d-8).chr}-?())"};x  
end

# Sans-multiply solution. (Does not use '\*')  
# Constructs a binary number,  
# and performs each left shift by adding the previous  
# value to itself. Generates VERY large strings. Passes  
# the tests, but needs to be run with `ulimit -s unlimited`  
# 🙂  
def symbolify(i)  
&nbsp;&nbsp;x="(?(-?()";i.to\_s(2).each\_byte{|d|x+="--#{x}--(?#{(d-8).chr}-?()"};x  
end

Regards,

Bill

---

<div class="post-metadata">

**Author:** ![Dana\_Merrick1](https://avatars.discourse-cdn.com/v4/letter/d/e9a140/32.png) [@Dana\_Merrick1](https://rubytalk.org/u/Dana_Merrick1)\
**Post date:** [13 July 2008 23:08 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/14 "2008-07-13T23:08:48Z")

</div>

Here is my solution. It's not really outstanding on any front, but it works and it's my first Ruby Quiz submission.

def symbolify(i)  
&nbsp;&nbsp;&nbsp;i.zero?? "??-??":"-"+("(?(-?))-"\*i).chop  
end

Also, I added this part for fun:

require 'mathn'  
def symbolify\_short(i)  
&nbsp;&nbsp;&nbsp;return "??-??" if i.zero?  
&nbsp;&nbsp;&nbsp;factors = i.prime\_division  
&nbsp;&nbsp;&nbsp;factors.inject("") do |string,pair|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string \<\< "(" \<\< symbolify(pair.first) \<\< ")\*\*(" \<\< symbolify(pair.last) \<\< ")\*"  
&nbsp;&nbsp;&nbsp;end.chop  
end

-Dana

> **···**
>
> --  
> Dana Merrick - System Administrator  
> Integrated Computer Solutions, Inc.  
> 54B Middlesex Tpke, Bedford, MA 01730  
> 617.621.0060 x112 - [http://www.ics.com](http://www.ics.com)

---

<div class="post-metadata">

**Author:** ![a11](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/a11/32/8169_2.png) [@a11](https://rubytalk.org/u/a11)\
**Post date:** [14 July 2008 03:28 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/15 "2008-07-14T03:28:06Z")

</div>

a full-on cheat:

cfp:~/src/ruby \> cat a.rb  
# impl

> **···**
>
> On Jul 11, 2008, at 9:17 AM, Matthew Moss wrote:
> 
> > ## Symbolify (#169)
> 
> #  
> &nbsp;&nbsp;&nbsp;def symbolify i;def (s=i.to\_s).delete \_;'';end;s;end
> 
> # test  
> #  
> &nbsp;&nbsp;&nbsp;nums = (0...1000).sort\_by { rand }  
> &nbsp;&nbsp;&nbsp;strs = nums.map { |n| symbolify(n) }
> 
> &nbsp;&nbsp;&nbsp;strs.zip(nums).sort\_by { rand }.each do |str, num|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;res = eval(str)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Not a string!" unless str.is\_a? String  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Invalid chars!" unless str.delete("?\*()-").empty?  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Decode failed!" unless res == num  
> &nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;puts "Passed!"
> 
> cfp:~/src/ruby \> time ruby a.rb  
> Passed!
> 
> real 0m0.026s  
> user 0m0.021s  
> sys 0m0.005s
> 
> a @ [http://codeforpeople.com/](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

---

<div class="post-metadata">

**Author:** ![j\_B](https://avatars.discourse-cdn.com/v4/letter/j/d07c76/32.png) [@j\_B](https://rubytalk.org/u/j_B)\
**Post date:** [14 July 2008 12:49 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/16 "2008-07-14T12:49:02Z")

</div>

> ## Symbolify (#169)

Fairly straightforward; handles negative and positive. I tried for the  
shortest resulting encoding but fell a little short compared to some of  
the other results . Thats likely due to my use of addition instead of  
multiplication.

def symbolify(j)  
&nbsp;&nbsp;&nbsp;&nbsp;i = j.abs  
&nbsp;&nbsp;&nbsp;&nbsp;add = "--"  
&nbsp;&nbsp;&nbsp;&nbsp;unless $nums  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;code = {?? =\> "??", ?- =\> "?-", ?) =\> "?)", ?( =\> "?(", ?\* =\>  
"?\*"}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$nums = {}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;code.keys.each do |x|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;code.keys.each do |y|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$nums[x-y] = "%s-%s" % [code, code[y]]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$nums[x\*y] = "%s\*%s" % [code, code[y]]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$nums[x\*\*y] = "%s\*\*%s" % [code, code[y]]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;if $nums[i]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eq = "%s%s%s" % [j \< 0 ? "-(" : "", $nums[i], j \< 0 ? ")" : ""]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return eq  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;values = {}  
&nbsp;&nbsp;&nbsp;&nbsp;remove = 0  
&nbsp;&nbsp;&nbsp;&nbsp;$nums.keys.sort.reverse.each do |num|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next unless num \> 1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if num \< i and i % num == 0  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return "%s(%s)\*(%s)" % [j\<0 ? "-" :  
"",$nums[num],symbolify(i/num)]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pow = 0  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pow += 1 while num\*\*pow \<= i  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;values[num\*\*(pow-1)] = [num,pow-1]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;remove = num\*\*(pow-1) if remove \< num\*\*(pow-1)  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;base,pow = values[remove]  
&nbsp;&nbsp;&nbsp;&nbsp;equation = "(%s)\*\*(%s)" % [$nums[base], symbolify(pow)]  
&nbsp;&nbsp;&nbsp;&nbsp;equation \<\< add + symbolify(i-remove) if i - remove \> 0  
&nbsp;&nbsp;&nbsp;&nbsp;j \< 0 ? "-(" + equation + ")" : equation

end

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![A\_LeDonne](https://avatars.discourse-cdn.com/v4/letter/a/6bbea6/32.png) [@A\_LeDonne](https://rubytalk.org/u/A_LeDonne)\
**Post date:** [11 July 2008 16:41 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/17 "2008-07-11T16:41:59Z")

</div>

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

-A

> **···**
>
> On Fri, Jul 11, 2008 at 12:12 PM, ara.t.howard \<ara.t.howard@gmail.com\> wrote:
> 
> > On Jul 11, 2008, at 9:17 AM, Matthew Moss wrote:
> > 
> > > That is, the following test code should raise no exceptions:
> > > 
> > > &nbsp;&nbsp;1000.times do |i|  
> > > &nbsp;&nbsp;&nbsp;&nbsp;s = symbolify(i)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;raise "Not a string!" unless s.is\_a? String  
> > > &nbsp;&nbsp;&nbsp;&nbsp;raise "Invalid chars!" unless s.delete("?\*()-").empty?
> > > 
> > > &nbsp;&nbsp;&nbsp;&nbsp;x = eval(s)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;raise "Decode failed!" unless i == x  
> > > &nbsp;&nbsp;end
> > 
> > i've got one line - tests pass.

---

<div class="post-metadata">

**Author:** ![Matthew\_D\_Moss1](https://avatars.discourse-cdn.com/v4/letter/m/91b2a8/32.png) [@Matthew\_D\_Moss1](https://rubytalk.org/u/Matthew_D_Moss1)\
**Post date:** [11 July 2008 18:26 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/18 "2008-07-11T18:26:52Z")

</div>

> \> ## 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. 😉

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.

---

<div class="post-metadata">

**Author:** ![Matthew\_D\_Moss1](https://avatars.discourse-cdn.com/v4/letter/m/91b2a8/32.png) [@Matthew\_D\_Moss1](https://rubytalk.org/u/Matthew_D_Moss1)\
**Post date:** [11 July 2008 19:02 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/19 "2008-07-11T19:02:59Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Chris\_Shea1](https://avatars.discourse-cdn.com/v4/letter/c/b487fb/32.png) [@Chris\_Shea1](https://rubytalk.org/u/Chris_Shea1)\
**Post date:** [11 July 2008 20:10 UTC](https://rubytalk.org/t/quiz-symbolify-169/47650/20 "2008-07-11T20:10:55Z")

</div>

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:

> **···**
>
> On Jul 11, 12:57 pm, Matthew Moss \<matthew.m...@gmail.com\> 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!"
> 
> ###  
> require 'test/unit'
> 
> class TestSymbolify \< Test::Unit::TestCase  
> &nbsp;&nbsp;@test\_number = 1
> 
> &nbsp;&nbsp;def self.solution\_test(module\_name, range, test=:delayed\_eval\_tests)  
> &nbsp;&nbsp;&nbsp;&nbsp;class\_eval \<\<-EOD  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def test\_#{@test\_number}\_#{module\_name.to\_s.gsub('::','\_')}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object.send(:include, #{module\_name})  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#{test}(#{range})  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;EOD  
> &nbsp;&nbsp;&nbsp;&nbsp;@test\_number += 1  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;def symbolify\_assertions\_for(string, integer)  
> &nbsp;&nbsp;&nbsp;&nbsp;assert\_kind\_of(String, string)  
> &nbsp;&nbsp;&nbsp;&nbsp;assert\_match(/\A[?\*()-]\*\Z/, string)  
> &nbsp;&nbsp;&nbsp;&nbsp;assert\_equal(integer, eval(string))  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;def cheat\_friendly\_tests(range)  
> &nbsp;&nbsp;&nbsp;&nbsp;range.each do |i|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = symbolify(i)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;symbolify\_assertions\_for(s,i)  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;def delayed\_eval\_tests(range)  
> &nbsp;&nbsp;&nbsp;&nbsp;nums = range.sort\_by { rand }  
> &nbsp;&nbsp;&nbsp;&nbsp;strs = nums.map { |n| symbolify(n) }
> 
> &nbsp;&nbsp;&nbsp;&nbsp;strs.zip(nums).sort\_by { rand }.each do |s, i|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;symbolify\_assertions\_for(s,i)  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;# The actual tests  
> &nbsp;&nbsp;solution\_test(Symbolify::Integers, -1000..1000)  
> &nbsp;&nbsp;solution\_test(Symbolify::NaturalNumbers, 0..1000)  
> &nbsp;&nbsp;solution\_test(Symbolify::Cheating,  
> -1000..1000, :cheat\_friendly\_tests)  
> end  
> ###
> 
> It might be a little much... but I \*was\* having fun.
> 
> Chris

[Next page](https://rubytalk.org/t/quiz-symbolify-169/47650.md?page=2)
