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