Mengevaluasi ekspresi dengan singkatan numerik

10

Anda bekerja untuk perusahaan yang ingin membuat kalkulator yang ramah pengguna, dan dengan demikian Anda telah diberi tugas untuk menambahkan kemampuan bagi pengguna untuk menggunakan "steno angka," yaitu, huruf yang mewakili nilai numerik, seperti kuntuk 1000. Karena perusahaan Anda ingin menghemat uang pada penyimpanan dalam kalkulator tersebut, Anda harus meminimalkan kode Anda sebanyak mungkin untuk mengurangi biaya penyimpanan.


Tugas Anda

Anda harus membuat fungsi yang bisa membaca ekspresi sebagai input dari STDIN atau menjadikannya sebagai parameter dan mengembalikan evaluasinya atau mencetaknya ke STDOUT.

Beberapa Klarifikasi

Biarkan saya melakukan beberapa definisi. Pertama, kami memiliki input, yang saya sebut ungkapan. Ini bisa seperti berikut ini:

x + y / z

Dalam ungkapan ini kami memiliki tiga nomor: x, y, dan z, dipisahkan oleh operator ( +dan /). Angka-angka ini belum tentu bilangan bulat positif (atau bahkan bilangan bulat). Yang menyulitkan adalah ketika kita harus mengevaluasi steno yang terkandung dalam angka. Misalnya dengan

2k15

untuk tujuan evaluasi, kami membagi ini menjadi tiga nomor: 2, 1000(yang k), dan 15. Kemudian, sesuai aturan, kami menggabungkannya untuk mendapatkan

2*1000 + 15 = 2015

Semoga ini membuatnya sedikit lebih mudah untuk memahami aturan berikut ini.

Aturan

NB Kecuali ditentukan lain, Anda dapat mengartikan kata "angka" atau sinonimnya untuk memasukkan singkatan.

  1. Berikut ini merupakan shorthands numerik fungsi Anda harus mampu proses: k, m, b, t, and e. k, m, b, and tsesuai dengan nilai 1000, 1000000, 1000000000, and 1000000000000masing-masing (seribu, satu juta, satu miliar, dan satu triliun). The esingkat akan selalu diikuti dengan nomor lain, n, dan mewakili 10^n. Anda harus mengizinkan steno angka untuk hadir ndan hadir sebelumnya e. Misalnya, kekevaluasi ke 1000*10^1000.

  2. Demi kesederhanaan, jika angka memiliki steno edi dalamnya, itu hanya akan digunakan sekali.

  3. Angka apa pun ( termasuk steno ) sebelum steno dikalikan dengan steno. misalnya 120kkakan dievaluasi sebagai 120 * 1000 * 1000. Jika tidak ada angka sebelumnya, Anda harus mengasumsikan bahwa angka tersebut adalah 1 (seperti bagaimana Anda, dalam matematika, memperlakukan variabel xsecara implisit sebagai 1x). misalnya e10mengevaluasi 10^10. Contoh lain: 2m2kmengevaluasi ke 2*1000000*2*1000(tidak ada yang ditambahkan ke dalamnya).

  4. Nomor apa pun (singkatan tidak berlaku) mengikuti steno terakhir dalam nomor yang mengandung steno ditambahkan ke dalamnya. misalnya 2k12akan dievaluasi sebagai 2*1000 + 12. Pengecualian untuk hal ini adalah jika steno edigunakan, dalam hal ini nomor ( steno termasuk ) berikut eakan diperlakukan sebagai ndan dievaluasi sebagai 10^n(lihat aturan pertama).

  5. Fungsi Anda harus dapat memproses masing-masing operator +, -, *, and /yang penjumlahan, pengurangan, perkalian, dan pembagian. Ini dapat memproses lebih banyak, jika Anda inginkan.

  6. Operasi dievaluasi sesuai dengan urutan operasi.

  7. Angka dalam singkatan tidak hanya bilangan bulat. 3.5b1.2valid dan akan dievaluasi sebagai3.5*1000000000 + 1.2 = 3500000001.2

  8. Built-in tidak diperbolehkan, jika ada untuk hal semacam ini. Pengecualian yang akan saya tambahkan adalah jika bahasa Anda secara otomatis mengubah angka besar menjadi notasi ilmiah, dalam hal ini yang dapat diterima untuk hasil Anda.

  9. Kode terpendek dalam byte menang, penerapan celah standar.

Memasukkan

Input akan berupa ekspresi dengan setiap angka dan operator dipisahkan oleh spasi. Angka mungkin mengandung steno atau tidak. Contoh ditunjukkan di bawah ini:

10 + 1b - 2k

Keluaran

Fungsi Anda harus menampilkan evaluasi ekspresi sebagai angka. Diperbolehkan menggunakan notasi ilmiah jika hasilnya terlalu besar untuk ditampilkan. Anda harus memiliki setidaknya tiga tempat desimal jika angka tersebut bukan bilangan bulat. Ini diterima jika Anda mempertahankan tempat desimal ini jika angka adalah bilangan bulat.

Uji Kasus

Memasukkan

t

Keluaran

1000000000000

Memasukkan

1 + 4b / 10k11

Keluaran

399561.483

Memasukkan

e2 + k2ke-1 - b12

Keluaran

-999799912

atau

-999799912.000

Memasukkan

142ek12

Keluaran

142e1012

atau

142.000e1012

Memasukkan:

1.2m5.25

Keluaran:

1200005.25

Catatan Akhir

Ini adalah tantangan pertama saya yang diposting (dengan bantuan dari pengguna di kotak pasir). Jika ada yang tidak jelas, beri tahu saya dan saya akan melakukan yang terbaik untuk mengklarifikasi.

cole
sumber
1
Tantangan pertama yang bagus
Trauma Digital
@DigitalTrauma Terima kasih banyak! Saya berharap dapat melihat jawabannya.
cole
Saya tidak mengerti contoh kedua. Saya pikir istilah tengah ditafsirkan 1000 + 2000 * 10 ^ -1, tetapi itu memberikan jawaban akhir -999998712. (Juga, interpretasi saya sepertinya tidak cocok dengan " steno terakhir " aturan 4 , tetapi saya tidak yakin bagaimana lagi memahami urutannya k2k.) Bisakah Anda jelaskan langkah-langkah dalam mengevaluasinya?
DLosc
@trichoplax ya, itu hanya berupa angka; tangkapan yang bagus.
cole
1
Setelah melihat komentar di posting sandbox, saya pikir contoh seperti 2m2kharus ditambahkan ke diskusi aturan 3. Juga, mungkin lebih baik menggunakan istilah yang berbeda - mungkin "integer" - untuk angka literal seperti 123itu yang tidak shorthands. Kata "angka" memiliki sekitar 3 definisi berbeda di sini, seperti yang ada sekarang.
DLosc

Jawaban:

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

Pertanyaan ini tampak sedikit tidak dicintai dan terasa menyenangkan, jadi saya mencobanya. Saya belum pernah melakukan golf kode, jadi mungkin ada banyak yang bisa ditingkatkan, tapi saya memberikan yang terbaik berdasarkan pengetahuan saya tentang bahasa. Solusi yang setara dimungkinkan dalam Python 3 dengan biaya satu byte tambahan: print repr(z[0])-> print(repr(z[0])).

Penggunaan adalah sesuatu di sepanjang garis

python2 ShorthandMath.py <equation>

yaitu

python2 ShorthandMath.py e2 + k2ke-1 - b12

output

-999799912.0

Masukan untuk cara meningkatkan ini akan sangat dihargai. Jika ada minat yang cukup, saya bisa ungolf dan berkomentar program, tetapi sebagian besar sudah cukup terbaca (fakta tentang kode golf).

Perlu dicatat bahwa program rusak dengan contoh 142ek12karena nilai itu sangat besar dan program meluap.

Untuk mengkompensasi, berikut ini sedikit lebih lama, tetapi secara teoritis dapat menangani apa pun yang dilemparkan padanya karena penggunaan built in library presisi yang sewenang-wenang. Sintaksnya identik.

Python 2, 589 588 byte (presisi sewenang-wenang)

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]
BobChao87
sumber
Saya akan mengatakan versi pertama harus baik-baik saja dan saya akan menghubungi Anda jika mencoba ada yang salah (saya tidak bisa melihat / berpikir terlalu hati-hati sekarang).
cole
@Cole Luar Biasa, terima kasih. Saya mencobanya pada setiap contoh yang diberikan, dan setidaknya semua itu benar.
BobChao87