Espressione di valutazione con shorthands numerici


10

Lavori per un'azienda che desidera creare una calcolatrice intuitiva e quindi ti è stato assegnato il compito di aggiungere agli utenti la possibilità di utilizzare "scorciatoie numeriche", ovvero lettere che rappresentano valori numerici, come kper 1000. Poiché la tua azienda vuole risparmiare sull'archiviazione in detti calcolatori, devi ridurre il più possibile il codice per ridurre i costi di archiviazione.


Il tuo compito

Devi creare una funzione che legge un'espressione come input da STDIN o la prende come parametro e restituisce la sua valutazione o la stampa su STDOUT.

Alcuni chiarimenti

Vorrei fare alcune definizioni. Prima di tutto, abbiamo l'input, che chiamo espressione. Questo può essere simile al seguente:

x + y / z

Da questa espressione abbiamo tre numeri: x, ye z, separati da operatori ( +e /). Questi numeri non sono necessariamente numeri interi positivi (o addirittura numeri interi). Ciò che complica le cose è quando dobbiamo valutare le scorciatoie contenute nei numeri. Ad esempio, con

2k15

ai fini della valutazione, abbiamo diviso questo in tre numeri: 2, 1000(che è k), e 15. Quindi, secondo le regole, le combiniamo per ottenere

2*1000 + 15 = 2015

Speriamo che questo renda un po 'più facile capire le seguenti regole.

Regole

NB Se non diversamente specificato, è possibile interpretare la parola "numeri" o i suoi sinonimi per includere le scorciatoie.

  1. Quanto segue costituisce le abbreviazioni numeriche tua funzione deve essere in grado di processo: k, m, b, t, and e. k, m, b, and tcorrispondono 1000, 1000000, 1000000000, and 1000000000000rispettivamente ai valori (mille, un milione, un miliardo e un trilione). La estenografia sarà sempre seguita da un altro numero ne rappresenta 10^n. È necessario consentire la presenza e la presenza di shorthand numerici in nprecedenza e. Ad esempio, kekvaluta 1000*10^1000.

  2. Per semplicità, se un numero contiene la scorciatoia e, verrà utilizzato solo una volta.

  3. Qualsiasi numero ( comprese le abbreviazioni ) prima di una scorciatoia viene moltiplicato per esso. ad es. 120kkverrebbe valutato come 120 * 1000 * 1000. Se non c'è nessun numero prima di esso, devi supporre che il numero sia 1 (come in matematica potresti trattare ximplicitamente una variabile come 1x). ad esempio e10valuta 10^10. Un altro esempio: 2m2kvaluta 2*1000000*2*1000(non viene aggiunto nulla).

  4. Qualsiasi numero (le scorciatoie non si applicano) che segue l' ultima scorciatoia in un numero contenente una scorciatoia viene aggiunto ad esso. ad es. 2k12verrebbe valutato come 2*1000 + 12. L'eccezione a ciò è se eviene usata la scorciatoia , nel qual caso il numero ( shorthands incluso ) che segue everrà trattato come ne valutato come 10^n(vedi la prima regola).

  5. La tua funzione deve essere in grado di elaborare gli operatori +, -, *, and /che sono rispettivamente addizione, sottrazione, moltiplicazione e divisione. Potrebbe essere più elaborato, se lo desideri.

  6. Le operazioni vengono valutate in base all'ordine delle operazioni.

  7. I numeri in shorthands non sono solo numeri interi. 3.5b1.2è valido e deve essere valutato come3.5*1000000000 + 1.2 = 3500000001.2

  8. Gli incorporati non sono ammessi, se esistono per questo tipo di cose. L'eccezione che aggiungerei sarebbe se la tua lingua converte automaticamente grandi numeri in notazione scientifica, nel qual caso è ammissibile per il tuo output.

  9. Vince il codice più breve in byte, si applicano scappatoie standard.

Ingresso

L'input sarà un'espressione con ogni numero e operatore separati da spazi. I numeri possono contenere o meno una scorciatoia. Di seguito è mostrato un esempio:

10 + 1b - 2k

Produzione

La tua funzione deve generare la valutazione dell'espressione come un numero. È ammissibile utilizzare la notazione scientifica se l'output fosse troppo grande per essere visualizzato. È necessario disporre di almeno tre cifre decimali se il numero non è un numero intero. È ammissibile se si mantengono queste cifre decimali se il numero è un numero intero.

Casi test

Ingresso

t

Produzione

1000000000000

Ingresso

1 + 4b / 10k11

Produzione

399561.483

Ingresso

e2 + k2ke-1 - b12

Produzione

-999799912

o

-999799912.000

Ingresso

142ek12

Produzione

142e1012

o

142.000e1012

Ingresso:

1.2m5.25

Produzione:

1200005.25

Note finali

Questa è la mia prima sfida pubblicata (con l'aiuto degli utenti sulla sandbox). Se qualcosa non è chiaro, fammelo sapere e farò del mio meglio per chiarire.


1
Buona prima sfida
Digital Trauma,

@DigitalTrauma Grazie mille! Non vedo l'ora di vedere le risposte.
Cole

Non capisco il secondo esempio. Ho pensato che il termine medio fosse interpretato come 1000 + 2000 * 10 ^ -1, ma che ha dato una risposta finale di -999998712. (Inoltre, la mia interpretazione non sembra coincidere con l '" ultima scorciatoia " della regola 4 , ma non sono sicuro di come altrimenti comprendere la sequenza k2k.) Puoi spiegare i passaggi per valutarla?
DLosc,

@trichoplax sì, dovrebbe essere solo un numero; buona pesca.
Cole,

1
Dopo aver esaminato i commenti sul post sandbox, penso che un esempio come 2m2kdovrebbe essere aggiunto alla discussione della regola 3. Inoltre, potrebbe essere meglio utilizzare un diverso termine - forse "integer" - per i numeri letterali come 123quella non sono shorthands. La parola "numero" ha circa 3 diverse definizioni qui, così com'è ora.
DLosc,

Risposte:


4

Python 2, 553 byte

import sys
a=lambda i:lambda j:j*10**i
d={'k':a(3),'m':a(6),'b':a(9),'t':a(12)}
e='e'
o={'+':lambda i,j:i+j,'-':lambda i,j:i-j,'*':lambda i,j:i*j,'/':lambda i,j:i/j,e:lambda i,j:i*10**j}
r=[e,'*','/','+','-']
x=0
y=k=b=''
z=[]
q=lambda i,j:float(i or j)
for l in ''.join(sys.argv[1:]):
 if l in d:x,y=d[l](q(x,1)*q(y,1)),b
 elif l==e:z.extend([q(x+q(y,0),1),l]);x,y=0,b
 elif k==e:y+=l
 elif l in o:z.extend([x+q(y,0),l]);x,y=0,b
 else:y+=l
 k=l
z.append(x+q(y,0))
for m in r:
 while m in z:n=z.index(m);z[n-1:n+2]=[o[m](z[n-1],z[n+1])]
print repr(z[0])

Questa domanda sembrava un po 'non amata e sembrava divertente, quindi ho provato. Non ho mai giocato a code golf prima d'ora, quindi probabilmente c'è molto che può essere migliorato, ma ho dato il massimo in base alla mia conoscenza della lingua. Una soluzione equivalente è possibile in Python 3 al costo di un byte aggiuntivo: print repr(z[0])-> print(repr(z[0])).

L'uso è qualcosa sulla falsariga di

python2 ShorthandMath.py <equation>

vale a dire

python2 ShorthandMath.py e2 + k2ke-1 - b12

uscite

-999799912.0

Gli input per come migliorare questo sarebbero molto apprezzati. Se l'interesse è sufficiente, posso annullare il commento e commentare il programma, ma la maggior parte è già abbastanza leggibile (un fatto rilevante nel code golf).

Va notato che il programma si rompe con l'esempio 142ek12perché quel valore è ridicolmente grande e il programma trabocca.

Per compensare, quanto segue è leggermente più lungo, ma può teoricamente gestire qualsiasi cosa gli venga lanciata a causa dell'uso della libreria di precisione arbitraria integrata. La sintassi è identica.

Python 2, 589 588 byte (precisione arbitraria)

import sys
from decimal import*
a=lambda i:lambda j:j*10**i
d={'k':a(3),'m':a(6),'b':a(9),'t':a(12)}
e='e'
o={'+':lambda i,j:i+j,'-':lambda i,j:i-j,'*':lambda i,j:i*j,'/':lambda i,j:i/j,e:lambda i,j:i*10**j}
r=[e,'*','/','+','-']
x=c=Decimal(0)
y=k=b=''
z=[]
q=lambda i,j:Decimal(float(i or j))
for l in ''.join(sys.argv[1:]):
 if l in d:x,y=d[l](q(x,1)*q(y,1)),b
 elif l==e:z.extend([q(x+q(y,0),1),l]);x,y=c,b
 elif k==e:y+=l
 elif l in o:z.extend([x+q(y,0),l]);x,y=c,b
 else:y+=l
 k=l
z.append(x+q(y,0))
for m in r:
 while m in z:n=z.index(m);z[n-1:n+2]=[o[m](z[n-1],z[n+1])]
print z[0]

Sto per dire che la prima versione dovrebbe andare bene e ti ricontatterò se provo che c'è qualcosa di sbagliato (non posso guardare / pensare troppo attentamente in questo momento).
Cole

@Cole Fantastico, grazie. L'ho provato su tutti gli esempi forniti, e almeno ha funzionato tutti.
BobChao87,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.