Converta x-illion em forma padrão

14

Dada uma string, consistindo de um prefixo e, em seguida, "illion", converta esse número no formato padrão.

Por exemplo:

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

O programa precisa ser capaz de lidar com entradas que vão até Centillion, que é 10 ^ 303. Uma lista de nomes e seus valores de forma padrão pode ser encontrada aqui - observe que isso fornece valores para cada incremento de 10 ^ 3 até 10 ^ 63, mas depois os fornece em incrementos de 10 ^ 30, no entanto, o padrão é bastante direto.

O programa precisa lidar com todos os 100 casos (mesmo os que não são explicitamente fornecidos pelo site fornecido) - eis alguns exemplos disso:

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

A entrada pode ser fornecida via STDIN, argumento de função ou codificado como uma string.

Isso é código-golfe, então o código mais curto vence!

James Williams
fonte
O que 10 ^ 70 seria?
Scimonster
3
10 ^ 70 não tem uma representação porque 3 não é um fator de 70 - mas 10 ^ 69 seria um milhão de sexos. 10 ^ 70 seria 10 sexvigintilhões.
James Williams
Na verdade, doevigintillion = 10 ^ 69 e sexvigintillion = 10 ^ 81.
Remy
@Emy Eu acho que você usa a longa escala (se isso é certo)? Parece que esta pergunta usa a escala curta.
Cole Johnson
@Cole Johnson: lista fornecida da questão dos nomes diz vigintillion = 10 ^ 63, e mostra que un adiciona 3 ao poder, doe- acrescenta 6, sexo- adiciona 18, etc.
Remy

Respostas:

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)

(A iflinha é recuada com uma única guia e o restante com espaços únicos.)

Aqui c('million') == 10**6tem que haver um caso especial, porque 'novem'também termina 'm'.

Exemplos:

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

Agradecemos a Falko por ofuscá-lo até 350 bytes.


Para a prática, tentei reescrever isso como uma linha usando lambdas. São 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
fonte
2
+1 por abusar da falta de especificação do OP sobre se "10 ^ x" deve ser impresso ou se apenas retornar o valor numérico é suficiente.
Ingo Bürk
1
Obrigado, embora tenha return'10^'+str(3*k)apenas 4 bytes a mais.
Remy
1
Como esse é o python 2, você pode usar um recuo de espaço para o primeiro nível e uma guia para o segundo. Você também pode mover ambos ae bpara a função como argumentos de palavra-chave.
FryAmTheEggman 28/10
2
1000**ké mais curto que 10**(3*k). Incrementar kpor 3*d[p]também é igualmente curto.
Xnor
2
Você pode salvar alguns caracteres, evitando a saída antecipada usando em if'm'==s:k=6;d=[]vez de uma segunda returndeclaração longa .
Falko
9

JS (ES6), 292 270

Compreende apenas os números escritos na lista fornecida. O OP não é claro sobre os outros.

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))}

Exemplo:

z("Billion") // "10^9"
z("Centillion") // "10^303"
xem
fonte
Você pode remover os zeros na sequência e substituir split(0)por match(/[A-Z][a-z]*/g)para usar expressões regulares para corresponder a cada sequência.
NinjaBearMonkey
Isso lida apenas com os prefixos "un, doe, tre, etc" por decilhão. Ele também deve lidar com casos como unvigintillion = 10 ^ 66 e novemnonagintillion = 10 ^ 300
Remy
Você pode encurtar isso usando as funções do ES6 =>.
soktinpk
Obrigado pelas dicas. @Remy, você tem certeza? o OP parece não perguntar isso
xem 29/10
Parece-me claro que todos os múltiplos de 3 são necessários: "... isso fornece valores para cada incremento de 10 ^ 3 até 10 ^ 63, mas depois os fornece em incrementos de 10 ^ 30, no entanto, o padrão é bastante direto" no OP. O OP também fornece um exemplo de "sexvigintilhão" em um comentário.
feersum
9

C, 235

Lida com todos os 100 casos. O programa usa stdin e stdout.

Quem precisa de regexes para separar camelos?

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);
}

Exemplo

octoseptuagintillion
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
feersum
fonte
1
Essa coisa nem se parece mais com C ... Estou impressionado.
Quentin
Por que o espaço ( *U<95 ?) e todas as novas linhas?
tomsmeding
@tomsmeding O espaço foi um descuido. As novas linhas tornam o código "legível" e não são incluídas na contagem.
feersum
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)))

Exemplo:

(c "Septuagintillion") ;; 1.0E213

Headmastersquall
fonte
2

Haskell, 204 bytes (+9 para String formatada)

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

No GHCi:

*Main> x "decillion"
1000000000000000000000000000000000

Substituir 10^(por "10^"++(show.adiciona outros 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

No GHCi:

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

Edit: Eu tive que corrigir para "quinquagintillion"que contém "qua".

AplusKminus
fonte