14
\$\begingroup\$

Given a string, consisting of a prefix and then "illion", convert this number into standard form.

For example:

"million" -> 10^6
"trillion" -> 10^12
"quattuordecillion" -> 10^45

The program needs to be able to handle input going up to Centillion, which is 10^303. A list of names and their standard form values can be found here - note that this gives values for every 10^3 increment up to 10^63, but then gives them in 10^30 increments, however the pattern is fairly straightforward.

The program needs to handle all 100 cases (even the ones not explicitly given by the website provided) - here are some examples of this:

"sexvigintillion" -> 10^81
"unnonagintillion" -> 10^276
"octotrigintillion" -> 10^117

Input can be given via STDIN, function argument or hard-coded as a string.

This is code-golf, so shortest code wins!

\$\endgroup\$
7
  • \$\begingroup\$ What would 10^70 be? \$\endgroup\$
    – Scimonster
    Oct 28, 2014 at 18:56
  • 3
    \$\begingroup\$ 10^70 doesn't have a representation because 3 isn't a factor of 70 - but 10^69 would be sexvigintillion. 10^70 would be 10 sexvigintillion. \$\endgroup\$ Oct 28, 2014 at 19:02
  • \$\begingroup\$ Actually, doevigintillion = 10^69, and sexvigintillion = 10^81. \$\endgroup\$
    – Remy
    Oct 28, 2014 at 20:36
  • \$\begingroup\$ @Remy I would guess that you use the long scale (if that's right)? It sounds like this question uses the short scale. \$\endgroup\$
    – Cole Tobin
    Oct 29, 2014 at 2:59
  • \$\begingroup\$ @Cole Johnson: The question's provided list of names says vigintillion = 10^63, and shows that un- adds 3 to the power, doe- adds 6, sex- adds 18, etc. \$\endgroup\$
    – Remy
    Oct 29, 2014 at 3:15

5 Answers 5

11
\$\begingroup\$

Python 2 (384 368 365 348 347 bytes)

def c(s):
 s=s[:-6].replace('int','');k=0;d=dict(un=1,doe=2,tre=3,quattuor=4,quin=5,sex=6,septen=7,octo=8,novem=9,b=3,tr=4,quadr=5,qu=6,sext=7,sept=8,oct=9,non=10,dec=11,vig=21,trig=31,quadrag=41,quinquag=51,sexag=61,septuag=71,octog=81,nonag=91,cent=101)
 for p in(s!='m')*list(d)*2:
    if s.endswith(p):s=s[:-len(p)];k+=3*d[p]
 return 10**(k or 6)

(The if line is indented with a single tab, and the rest with single spaces.)

Here c('million') == 10**6 has to be a special case because 'novem' also ends in 'm'.

Examples:

c('million') == 10**6
c('trillion') == 10**12
c('quattuordecillion') == 10**45
c('novemnonagintillion') == 10**300
c('centillion') == 10**303

Thanks to Falko for obfuscating it down to 350 bytes.


For practice I tried rewriting this as a one-liner using lambdas. It's 404 398 390 384 380 379 bytes:

c=lambda s:(lambda t=[s[:-5].replace('gint',''),0],**d:([t.__setslice__(0,2,[t[0][:-len(p)],t[1]+3*d[p]])for p in 2*list(d)if t[0].endswith(p)],10**t[1])[1])(un=1,doe=2,tre=3,quattuor=4,quin=5,sex=6,septen=7,octo=8,novem=9,mi=2,bi=3,tri=4,quadri=5,qui=6,sexti=7,septi=8,octi=9,noni=10,deci=11,vii=21,trii=31,quadrai=41,quinquai=51,sexai=61,septuai=71,octoi=81,nonai=91,centi=101)
\$\endgroup\$
6
  • 2
    \$\begingroup\$ +1 for abusing OP's lack of specification of whether "10^x" should be printed or whether just returning the numerical value is sufficient. \$\endgroup\$
    – Ingo Bürk
    Oct 28, 2014 at 20:06
  • 1
    \$\begingroup\$ Thanks, although return'10^'+str(3*k) would only be 4 bytes more. \$\endgroup\$
    – Remy
    Oct 28, 2014 at 20:38
  • 1
    \$\begingroup\$ Since this is python 2, you could use a space indent for the first level, and tab for the second. You can also move both a and b into the function as keyword arguments. \$\endgroup\$ Oct 28, 2014 at 20:44
  • 2
    \$\begingroup\$ 1000**k is shorter than 10**(3*k). Incrementing k by 3*d[p] is also equally short. \$\endgroup\$
    – xnor
    Oct 28, 2014 at 21:31
  • 2
    \$\begingroup\$ You can save a few characters by avoiding the early exit using if'm'==s:k=6;d=[] instead of a second lengthy return statement. \$\endgroup\$
    – Falko
    Oct 28, 2014 at 22:22
9
\$\begingroup\$

JS (ES6), 292 270

Understands only the numbers written in the given list. The OP isn't clear about the others.

z=b=>{a="M0B0Tr0Quadr0Quint0Sext0Sept0Oct0Non0Dec0Undec0Doedec0Tredec0Quattuordec0Quindec0Sexdec0Septendec0Octodec0Novemdec0Vigint0Trigint0Quadragint0Quinquagint0Sexagint0Septuagint0Octogint0Nonagint0Cent".split(0);for(i in a)if(~b.indexOf(a[i]))return"10^"+(20>i?3*i+6:93+30*(i-20))}

Example:

z("Billion") // "10^9"
z("Centillion") // "10^303"
\$\endgroup\$
6
  • \$\begingroup\$ You can remove the zeroes in the string and replace split(0) with match(/[A-Z][a-z]*/g) to use regexes to match each string. \$\endgroup\$ Oct 28, 2014 at 20:57
  • \$\begingroup\$ This only handles the "un, doe, tre, etc" prefixes for decillion. It should also handle cases like unvigintillion = 10^66 and novemnonagintillion = 10^300 \$\endgroup\$
    – Remy
    Oct 28, 2014 at 21:08
  • \$\begingroup\$ You can shorten this by using ES6 functions =>. \$\endgroup\$
    – soktinpk
    Oct 28, 2014 at 23:13
  • \$\begingroup\$ thanks for the tips. @Remy are you sure? the OP doesn't seem to ask that \$\endgroup\$
    – xem
    Oct 29, 2014 at 6:20
  • \$\begingroup\$ Seems clear to me that all multiples of 3 are required: "... this gives values for every 10^3 increment up to 10^63, but then gives them in 10^30 increments, however the pattern is fairly straightforward" in the OP. Also OP gives an example of "sexvigintillion" in a comment. \$\endgroup\$
    – feersum
    Oct 29, 2014 at 8:13
9
\$\begingroup\$

C, 235

Handles all 100 cases. Program uses stdin and stdout.

Who needs regexes for camel-case splitting?

char*Z="UUUi+W<)E(<7-7-++*)('&%$,*$&%$",u[999]="\0MBRilDriPtiNiUnOeReTtUiXTeCtVeCiGRigRaUagInquiXaXsexPtuOgOoNaCeCeK1",s[99],*U=u+67;
main(n){
for(gets(s);*--U;)
*U<95?
*U|=32,
n+=!!strstr(s,U)*(*Z++-35),
*U=0:
3;puts(memset(u+68,48,3*n)-1);
}

Example

octoseptuagintillion
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
\$\endgroup\$
3
  • 1
    \$\begingroup\$ This thing doesn't even look like C anymore... I'm amazed. \$\endgroup\$
    – Quentin
    Oct 29, 2014 at 12:29
  • \$\begingroup\$ Why the space (*U<95 ?) and all the newlines? \$\endgroup\$
    – tomsmeding
    Oct 29, 2014 at 14:25
  • \$\begingroup\$ @tomsmeding The space was an oversight. The newlines make the code "readable" and are not included in the count. \$\endgroup\$
    – feersum
    Oct 29, 2014 at 19:25
2
\$\begingroup\$

Clojure, 381 377 bytes

(defn c[x](let[l{"M"6"B"9"Tr"12"Quadr"15"Quint"18"Sext"21"Sept"24"Oct"27"Non"30"Dec"33"Undec"36"Doedec"39"Tredec"42"Quattuordec"45"Quindec"48"Sexdec"51"Septendec"54"Octodec"57"Novemdec"60"Vigint"63"Trigint"93"Googol"100"Quadragint"123"Quinquagint"153"Sexagint"183"Septuagint"213"Octogint"243"Nonagint"273"Cent"303}v(l(clojure.string/replace x #"illion$" ""))](Math/pow 10 v)))

Example:

(c "Septuagintillion") ;; 1.0E213

\$\endgroup\$
2
\$\begingroup\$

Haskell, 204 bytes (+9 for formatted String)

import Data.List
x s=10^(f$[a|k<-tails s,i<-inits k,(b,a)<-zip["ce","ad","un","do","b","mi","vi","tr","at","ui","x","p","oc","no","ec","g"]$100:4:1:2:2:[1..],b==i])
f[]=3
f(x:11:r)=30*x+f r
f(x:r)=3*x+f r

In GHCi:

*Main> x "decillion"
1000000000000000000000000000000000

Replacing 10^( with "10^"++(show. adds another 9 bytes:

import Data.List
x s="10^"++(show.f$[a|k<-tails s,i<-inits k,(b,a)<-zip["ce","ad","un","do","b","mi","vi","tr","at","ui","x","p","oc","no","ec","g"]$100:4:1:2:2:[1..],b==i])
f[]=3
f(x:11:r)=30*x+f r
f(x:r)=3*x+f r

In GHCi:

*Main> x "decillion"
"10^33"

Edit: I had to correct for "quinquagintillion" which contains "qua".

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.