Here's my solution (130.50):

#!perl -lp071
s/te|lv/ q/g;s%(.*?)$&\w*%+($+)*1E0$/
%gi,--$/while
b__m__THoHuyzOnwThFofSisEiiqv=~/[(-^]*./g;$_-=eval;s/.(?=(...)+$)/$&,/g
__END__

  This is what it does:

Transform the input into a perl expression that evaluates to the
correct number, evaluate it, and commafy the result.

  And this is how it does it:
  
# Set $/ to "9", for later use. Won't have any effect on the input,
# since "9" never appears there.
#!perl -lp071

# Munge input. Makes numbers 10 and 12-19 more uniform.
s/te|lv/ q/g;

# Loop through the data string, setting $& to consecutive tokens in
# the data string. A token is /[A-Z]*./, slightly obfuscated for the
# tiebreaker.
while ("b__m__THoHuyzOnwThFofSisEiiqv"=~/[(-^]*./g) {
   # Substitute all instances of the token in the input. 
   # Basically this accomplishes three different tasks:
   #  foo (billion|million|thousand|hundred) bar ->
   #      +(foo)*1E9 (or 1E6, 1E3, 1E2) bar
   #  barty foo ->
   #      +(bar)*1E1 foo   (for 20,30,40,etc)
   #  one|two|three|..|eleven
   #      +()*1E0-[value of the token]
   # Note the newline at the end. It's needed to get the precedence 
   # of the multiplications right.
   s%(.*?)$&\w*%+($+)*1E0$/
%gi,
   # And finally decrement $/ on each iteration
   --$/
}
# Now we have an expression in $_. For example, "one hundred twelve" 
# would produce something like this:
#  +(+()*1E0-1)*1E02+()*1E0-3+()*1E0-10

# Negate the eval, since the literals in the expression are negative.
$_-=eval;

# And finally, a suboptimal commafy
s/.(?=(...)+$)/$&,/g

# -pl takes care of the rest
__END__

All in all, the code is just too cute for it's own good, and I'm 
sort of suprised that it got me a fourth place. Brute force, man, 
brute force.

-- 
Juho Snellman

Reply via email to