Đánh giá biểu thức với các tốc ký số


10

Bạn làm việc cho một công ty mà muốn làm cho một máy tính người dùng thân thiện, và do đó bạn đã được giao nhiệm vụ thêm khả năng cho người dùng để sử dụng "shorthands số," có nghĩa là, chữ cái đại diện cho các giá trị số, chẳng hạn như kcho 1000. Vì công ty của bạn muốn tiết kiệm tiền cho việc lưu trữ trong các máy tính đã nói, bạn phải giảm thiểu mã của mình càng nhiều càng tốt để giảm chi phí lưu trữ.


Nhiệm vụ của bạn

Bạn phải tạo một hàm đọc một biểu thức làm đầu vào từ STDIN hoặc lấy nó làm tham số và trả về đánh giá của nó hoặc in nó thành STDOUT.

Một số làm rõ

Hãy để tôi làm một số định nghĩa. Trước hết, chúng ta có đầu vào, mà tôi gọi là một biểu thức. Đây có thể là một cái gì đó như sau:

x + y / z

Trong biểu thức này chúng tôi có ba con số: x, y, và z, ngăn cách bởi các nhà khai thác ( +/). Những số này không nhất thiết là số nguyên dương (hoặc thậm chí là số nguyên). Điều làm phức tạp mọi thứ là khi chúng ta phải đánh giá các tốc ký có trong các con số. Ví dụ với

2k15

cho mục đích đánh giá, chúng tôi chia số này thành ba số : 2, 1000(đó là k) và 15. Sau đó, theo các quy tắc, chúng tôi kết hợp chúng để có được

2*1000 + 15 = 2015

Hy vọng rằng điều này làm cho nó dễ dàng hơn một chút để hiểu các quy tắc sau đây.

Quy tắc

NB Trừ khi có quy định khác, bạn có thể diễn giải từ "số" hoặc từ đồng nghĩa của nó để bao gồm các tốc ký.

  1. Sau đây cấu thành các tốc ký số, chức năng của bạn phải có khả năng xử lý : k, m, b, t, and e. k, m, b, and ttương ứng với các giá trị 1000, 1000000, 1000000000, and 1000000000000tương ứng (một nghìn, một triệu, một tỷ và một nghìn tỷ). Tốc eký sẽ luôn được theo sau bởi một số khác n, và đại diện 10^n. Bạn phải cho phép các tốc ký số có mặt trong nvà hiện tại trước đó e. Ví dụ, kekđánh giá để 1000*10^1000.

  2. Để đơn giản, nếu một số có tốc ký etrong đó, nó sẽ chỉ được sử dụng một lần.

  3. Bất kỳ số nào ( bao gồm các tốc ký ) trước một tốc ký được nhân với nó. ví dụ 120kksẽ được đánh giá là 120 * 1000 * 1000. Nếu không có số nào trước nó, bạn phải giả sử rằng số đó là 1 (giống như cách bạn có thể, trong toán học, coi một biến xngầm là 1x). ví dụ: e10đánh giá 10^10. Một ví dụ khác: 2m2kđánh giá 2*1000000*2*1000(không có gì được thêm vào nó).

  4. Bất kỳ số nào (tốc ký không áp dụng) theo cách viết tắt cuối cùng trong một số có chứa một tốc ký được thêm vào nó. ví dụ 2k12sẽ được đánh giá là 2*1000 + 12. Ngoại lệ cho điều này là nếu tốc ký eđược sử dụng, trong trường hợp đó, số ( bao gồm các tốc ký ) sau đây esẽ được coi là nvà được đánh giá là 10^n(xem quy tắc đầu tiên).

  5. Hàm của bạn phải có khả năng xử lý các toán tử lần lượt +, -, *, and /là cộng, trừ, nhân và chia. Nó có thể xử lý nhiều hơn, nếu bạn mong muốn.

  6. Hoạt động được đánh giá theo thứ tự của hoạt động.

  7. Các số trong tốc ký không chỉ là số nguyên. 3.5b1.2là hợp lệ và được đánh giá là3.5*1000000000 + 1.2 = 3500000001.2

  8. Tích hợp không được phép, nếu chúng tồn tại cho loại điều này. Ngoại lệ mà tôi sẽ thêm là nếu ngôn ngữ của bạn tự động chuyển đổi số lượng lớn thành ký hiệu khoa học, trong trường hợp đó là chấp nhận được cho đầu ra của bạn.

  9. Mã ngắn nhất trong byte thắng, áp dụng sơ hở tiêu chuẩn.

Đầu vào

Đầu vào sẽ là một biểu thức với mỗi số và toán tử được phân tách bằng dấu cách. Các số có thể có hoặc không chứa một tốc ký. Một mẫu được hiển thị dưới đây:

10 + 1b - 2k

Đầu ra

Hàm của bạn phải xuất đánh giá biểu thức dưới dạng số. Có thể sử dụng ký hiệu khoa học nếu đầu ra quá lớn để hiển thị. Bạn phải có ít nhất ba chữ số thập phân nếu số đó không phải là số nguyên. Nó được chấp nhận nếu bạn giữ lại các vị trí thập phân này nếu số đó là một số nguyên.

Các trường hợp thử nghiệm

Đầu vào

t

Đầu ra

1000000000000

Đầu vào

1 + 4b / 10k11

Đầu ra

399561.483

Đầu vào

e2 + k2ke-1 - b12

Đầu ra

-999799912

hoặc là

-999799912.000

Đầu vào

142ek12

Đầu ra

142e1012

hoặc là

142.000e1012

Đầu vào:

1.2m5.25

Đầu ra:

1200005.25

Ghi chú cuối cùng

Đây là thử thách đầu tiên của tôi được đăng (với một số trợ giúp từ người dùng trên hộp cát). Nếu bất cứ điều gì không rõ ràng, làm cho nó được biết đến với tôi và tôi sẽ làm hết sức mình để làm rõ.


1
Thử thách đầu tiên tốt
Chấn thương kỹ thuật số

@DigitalTrauma Cảm ơn rất nhiều! Tôi mong muốn được nhìn thấy câu trả lời.
cole

Tôi không hiểu ví dụ thứ hai. Tôi nghĩ rằng thuật ngữ giữa được hiểu là 1000 + 2000 * 10 ^ -1, nhưng điều đó đã đưa ra câu trả lời cuối cùng -999998712. (Ngoài ra, cách giải thích của tôi dường như không có ý nghĩa với "tốc ký cuối cùng " của quy tắc 4 , nhưng tôi không chắc làm thế nào khác để hiểu trình tự k2k.) Bạn có thể giải thích các bước trong việc đánh giá nó không?
DLosc

@trichoplax vâng, chỉ nên là một con số; nắm bắt tốt.
cole

1
Sau khi xem xét các ý kiến về bài sandbox, tôi nghĩ rằng một ví dụ như 2m2knên được thêm vào các cuộc thảo luận về quy tắc 3. Ngoài ra, nó có thể là tốt nhất để sử dụng một thuật ngữ khác nhau - có thể "số nguyên" - cho những con số đen như 123rằng không phải là tốc ký. Từ "số" có khoảng 3 định nghĩa khác nhau ở đây, vì nó hiện nay.
DLosc

Câu trả lời:


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

Câu hỏi này có vẻ hơi không được yêu thích và có vẻ vui, vì vậy tôi đã cho nó một shot. Tôi chưa bao giờ chơi golf mã, vì vậy có lẽ có rất nhiều thứ có thể được cải thiện, nhưng tôi đã cố gắng hết sức dựa trên kiến ​​thức về ngôn ngữ của mình. Một giải pháp tương đương có thể có trong Python 3 với chi phí thêm một byte: print repr(z[0])-> print(repr(z[0])).

Cách sử dụng là một cái gì đó dọc theo dòng

python2 ShorthandMath.py <equation>

I E

python2 ShorthandMath.py e2 + k2ke-1 - b12

đầu ra

-999799912.0

Đầu vào cho cách cải thiện điều này sẽ được nhiều đánh giá cao. Nếu có đủ sự quan tâm, tôi có thể ungolf và nhận xét chương trình, nhưng hầu hết đều khá dễ đọc (một thực tế liên quan đến môn đánh gôn).

Cần lưu ý rằng chương trình phá vỡ với ví dụ 142ek12vì giá trị đó lớn một cách lố bịch và chương trình tràn ra.

Để bù lại, phần sau dài hơn một chút, nhưng về mặt lý thuyết có thể xử lý bất cứ thứ gì ném vào nó do sử dụng thư viện chính xác được xây dựng tùy ý. Cú pháp giống hệt nhau.

Python 2, 589 588 byte (độ chính xác tùy ý)

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]

Tôi sẽ nói phiên bản đầu tiên sẽ ổn và tôi sẽ liên lạc lại với bạn nếu thử bất cứ điều gì sai (tôi không thể nhìn / suy nghĩ quá cẩn thận ngay bây giờ).
cole

@Cole Tuyệt vời, cảm ơn. Tôi đã thử nó trên mọi ví dụ được đưa ra, và ít nhất nó cũng có được tất cả những điều đó.
BobChao87
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.