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\$
  • \$\begingroup\$ What would 10^70 be? \$\endgroup\$ – Scimonster Oct 28 '14 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\$ – James Williams Oct 28 '14 at 19:02
  • \$\begingroup\$ Actually, doevigintillion = 10^69, and sexvigintillion = 10^81. \$\endgroup\$ – Remy Oct 28 '14 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 Johnson Oct 29 '14 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 '14 at 3:15
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\$
  • 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 '14 at 20:06
  • 1
    \$\begingroup\$ Thanks, although return'10^'+str(3*k) would only be 4 bytes more. \$\endgroup\$ – Remy Oct 28 '14 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\$ – FryAmTheEggman Oct 28 '14 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 '14 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 '14 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\$
  • \$\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\$ – NinjaBearMonkey Oct 28 '14 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 '14 at 21:08
  • \$\begingroup\$ You can shorten this by using ES6 functions =>. \$\endgroup\$ – soktinpk Oct 28 '14 at 23:13
  • \$\begingroup\$ thanks for the tips. @Remy are you sure? the OP doesn't seem to ask that \$\endgroup\$ – xem Oct 29 '14 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 '14 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\$
  • 1
    \$\begingroup\$ This thing doesn't even look like C anymore... I'm amazed. \$\endgroup\$ – Quentin Oct 29 '14 at 12:29
  • \$\begingroup\$ Why the space (*U<95 ?) and all the newlines? \$\endgroup\$ – tomsmeding Oct 29 '14 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 '14 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, privacy policy and cookie policy

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