Convert x-illion into standard form

14

1

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!

James Williams

Posted 2014-10-28T18:32:05.063

Reputation: 1 735

Besides, in the long scale, one vigintillion would be 10^120. – SuperJedi224 – 2015-05-27T17:38:11.343

What would 10^70 be? – Scimonster – 2014-10-28T18:56:27.713

310^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. – James Williams – 2014-10-28T19:02:39.077

Actually, doevigintillion = 10^69, and sexvigintillion = 10^81. – Remy – 2014-10-28T20:36:53.447

@Remy I would guess that you use the long scale (if that's right)? It sounds like this question uses the short scale. – Cole Johnson – 2014-10-29T02:59:26.487

@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. – Remy – 2014-10-29T03:15:27.973

@Remy You are absolutely right, apologies. – James Williams – 2014-10-29T11:40:53.003

Answers

11

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)

Remy

Posted 2014-10-28T18:32:05.063

Reputation: 183

2+1 for abusing OP's lack of specification of whether "10^x" should be printed or whether just returning the numerical value is sufficient. – Ingo Bürk – 2014-10-28T20:06:12.910

1Thanks, although return'10^'+str(3*k) would only be 4 bytes more. – Remy – 2014-10-28T20:38:10.650

1Since 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. – FryAmTheEggman – 2014-10-28T20:44:00.297

21000**k is shorter than 10**(3*k). Incrementing k by 3*d[p] is also equally short. – xnor – 2014-10-28T21:31:51.180

2You can save a few characters by avoiding the early exit using if'm'==s:k=6;d=[] instead of a second lengthy return statement. – Falko – 2014-10-28T22:22:34.343

1Two more bytes: if(s!='m')*s.endswith(p) and return 10**[k,6][k<1] saves you the other if statement. That's it for tonight. :) – Falko – 2014-10-28T22:43:15.903

9

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"

xem

Posted 2014-10-28T18:32:05.063

Reputation: 5 523

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. – NinjaBearMonkey – 2014-10-28T20:57:18.723

This only handles the "un, doe, tre, etc" prefixes for decillion. It should also handle cases like unvigintillion = 10^66 and novemnonagintillion = 10^300 – Remy – 2014-10-28T21:08:22.883

You can shorten this by using ES6 functions =>. – soktinpk – 2014-10-28T23:13:55.780

thanks for the tips. @Remy are you sure? the OP doesn't seem to ask that – xem – 2014-10-29T06:20:23.607

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. – feersum – 2014-10-29T08:13:59.463

I thought I had made it pretty clear in my question description - see the "note" part after I give the link - however I will clarify. – James Williams – 2014-10-29T11:39:00.767

9

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

feersum

Posted 2014-10-28T18:32:05.063

Reputation: 29 566

1This thing doesn't even look like C anymore... I'm amazed. – Quentin – 2014-10-29T12:29:01.287

Why the space (*U<95 ?) and all the newlines? – tomsmeding – 2014-10-29T14:25:07.250

@tomsmeding The space was an oversight. The newlines make the code "readable" and are not included in the count. – feersum – 2014-10-29T19:25:43.813

2

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

Headmastersquall

Posted 2014-10-28T18:32:05.063

Reputation: 41

2

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".

AplusKminus

Posted 2014-10-28T18:32:05.063

Reputation: 171