On 13 Jul 2008, at 16:35, James Gray wrote:
>
> Mine was similar to this:
>
>  def symbolify(n)
>    "??-??" + "--(?)-?()" * n
>  end

I came up with something along those lines.
The version that produces shorter output worked along these lines:

1. Express the number as a sum of powers of 63 (eg 250174 = 63^3 +  
2*63 +1)
2. Rewrite that polynomial to reduce the number of operations required  
(ie 3x^4+2x^2+x is written as x(x(3x^2+2)+1)
3. write that out. the exponents are dealt with by calling itself.  
Coefficients (which by definition are < 63) are dealt with by a  
function that deals with that.
Initially I just hardcoded numbers 1 to 5 (?( - ?) etc...) and dealt  
with others by dividing out by 5 and calling itself recursively. Later  
on I added special cases for most of the numbers to produce shorter  
output. Some other parts of the program can be simplified/eliminated  
as all they do is produce slightly more compact output. This forms the  
bulk of the program. Off the top of my head I'd assume that the  
approach taken results in O(ln n) complexity.

Fred

def strip_parens x
   x.gsub(/^\(/,'').gsub(/\)$/,'')
end

INVERTIBLE = [1,2,3,4,5,18,21,22,23,46,47,48,49,50]
def small_symbolify x
  case x
  when 0: return '(?*-?*)'
  when 1: return '(?)-?()'
  when -1: return '(?(-?))'
  when 2: return '(?*-?()'
  when -2: return '(?(-?*)'
  when 3: return '(?--?*)'
  when -3: return '(?*-?-)'
  when 4: return '(?--?))'
  when -4: return '(?)-?-)'
  when 5: return '(?--?()'
  when -5: return '(?(-?-)'
  when 6: return '('+small_symbolify(3)+'*'+small_symbolify(2)+')'
  when 8: return '('+small_symbolify(2)+'*'+small_symbolify(4)+')'
  when 9: return '('+small_symbolify(3)+'*'+small_symbolify(3)+')'
  when 10: return '(?--?(-(?(-?-))'
  when 12: return '('+small_symbolify(3)+'*'+small_symbolify(4)+')'
  when 13: return '(??-?--(?--?())'
  when 14: return '('+strip_parens(small_symbolify(18)) 
+'-'+small_symbolify(4)+')'
  when 16: return small_symbolify(2)+'**'+small_symbolify(4)
  when 17: return '('+strip_parens(small_symbolify(18)) 
+'-'+small_symbolify(1)+')'
  when 18: return '(??-?-)'
  when -18: return '(?--??)'
  when 19: return '('+strip_parens(small_symbolify(21)) 
+'-'+small_symbolify(2)+')'
  when 21: return '(??-?*)'
  when -21: return '(?*-??)'
  when 22: return '(??-?))'
  when -22: return '(?)-??)'
  when 23: return '(??-?()'
  when -23: return '(?(-??)'
  when 24: return '('+strip_parens(small_symbolify(23)) 
+'-'+small_symbolify(-1)+')'
  when 25: return small_symbolify(5)+'**'+small_symbolify(2)
  when 26: return '('+strip_parens(small_symbolify(23)) 
+'-'+small_symbolify(-3)+')'
  when 27: return small_symbolify(3)+'**'+small_symbolify(3)
  when 28: return '('+strip_parens(small_symbolify(23)) 
+'-'+small_symbolify(-5)+')'
  when 32: return small_symbolify(2)+'**'+small_symbolify(5)
  when 36: return '('+small_symbolify(18)+'*'+small_symbolify(2)+')'
  when 38: return '('+strip_parens(small_symbolify(40)) 
+'-'+small_symbolify(2)+')'
  when 39: return '('+small_symbolify(3)+'*'+small_symbolify(13)+')'
  when 40: return '?('
  when 41: return '?)'
  when 42: return '?*'
  when 45: return '?-'
  when 46: return '('+small_symbolify(45)+'-'+small_symbolify(-1)+')'
  when -46: return '('+strip_parens(small_symbolify(-1)) 
+'-'+small_symbolify(45)+')'
  when 47: return '('+small_symbolify(45)+'-'+small_symbolify(-2)+')'
  when -47: return '('+strip_parens(small_symbolify(-2)) 
+'-'+small_symbolify(45)+')'
  when 48: return '('+small_symbolify(45)+'-'+small_symbolify(-3)+')'
  when -48: return '('+strip_parens(small_symbolify(-3)) 
+'-'+small_symbolify(45)+')'
  when 49: return '('+small_symbolify(45)+'-'+small_symbolify(-4)+')'
  when -49: return '('+strip_parens(small_symbolify(-4)) 
+'-'+small_symbolify(45)+')'
  when 50: return '('+small_symbolify(45)+'-'+small_symbolify(-5)+')'
  when -50: return '('+strip_parens(small_symbolify(-5)) 
+'-'+small_symbolify(45)+')'
  when 52: return '('+small_symbolify(4)+'*'+small_symbolify(13)+')'
  when 54: return '('+small_symbolify(3)+'*'+small_symbolify(18)+')'
    end
  if x > 31
    return '(??-'+small_symbolify(63-x)+')'
  end
  quotient = x/5
  rem = x - quotient * 5
  if quotient==0
    small_symbolify rem
  else
    if quotient == 1
      quotient_string = ''
    else
      quotient_string = small_symbolify(quotient)+'*'
    end
    '('+quotient_string+small_symbolify(5)+(rem > 0 ? '-' +  
small_symbolify(-rem) : '') + ')'
  end
end


def log63(x)
   power=0
   value=1
   x=-x if x < 0
   while value <= x
     value*=63
     power+=1
   end
   power-1
end

def convert_to_base_63 x
   return [] if x == 0
   leading_term = log63(x).to_i
   if leading_term==0
     [[x,0]]
   else
     v = 63**leading_term

     quotient = x/v
     remainder = x - quotient*v
     [[quotient, leading_term]]+convert_to_base_63(remainder)
   end
end


def symbolify x
  return '(?*-?*)' if x == 0
  transform_polynomial(convert_to_base_63(x))
end

def transform_polynomial p
   return '' if p.empty?
   last = p.pop

   m_power_term = (['??']*last[1]).join('*')
   p_power_term = "??**#{symbolify last[1]}"

   power_term = m_power_term.length > p_power_term.length ?  
p_power_term : m_power_term
   if p.empty?
     if last[1]==0
       result = small_symbolify(last[0])
     elsif last[0] == 1
       result = power_term
     else
       result = small_symbolify(last[0]) + '*'+power_term
     end
   else
     remainder = transform_polynomial(p.collect {|t| [t[0], t[1] -  
last[1]]})
     if INVERTIBLE.include?(last[0])
       remainder += '-'
       remainder +=small_symbolify -last[0]
     else
       remainder += '--'
       remainder +=small_symbolify last[0]
     end
     if last[1]==0
       result = remainder
     else
       result = power_term + "*(#{remainder})"
     end
   end
   result
end