การประเมินการแสดงออกด้วยชวเลขที่เป็นตัวเลข


10

คุณทำงานให้กับ บริษัท ที่ต้องการที่จะทำให้เครื่องคิดเลขที่ใช้งานง่ายและทำให้คุณได้รับมอบหมายกับการเพิ่มความสามารถในการให้ผู้ใช้สามารถใช้ "shorthands ตัวเลข" ที่เป็นตัวอักษรที่แทนค่าตัวเลขเช่นสำหรับk 1000เนื่องจาก บริษัท ของคุณต้องการประหยัดเงินในการจัดเก็บในเครื่องคิดเลขดังกล่าวคุณต้องลดรหัสให้มากที่สุดเพื่อลดต้นทุนการจัดเก็บ


งานของคุณ

คุณต้องสร้างฟังก์ชั่นที่อ่านนิพจน์เป็นอินพุตจาก STDIN หรือใช้เป็นพารามิเตอร์และส่งคืนการประเมินหรือพิมพ์ไปที่ STDOUT

ชี้แจงบางอย่าง

ผมขอนิยามบางอย่าง ก่อนอื่นเรามีอินพุตซึ่งฉันเรียกว่านิพจน์ นี่อาจเป็นสิ่งต่อไปนี้:

x + y / z

ภายในการแสดงออกนี้เรามีสามตัวเลข: x, yและzแยกจากกันโดยผู้ประกอบการ ( +และ/) ตัวเลขเหล่านี้ไม่จำเป็นต้องเป็นจำนวนเต็มบวก (หรือจำนวนเต็มคู่) สิ่งที่ซับซ้อนคือเมื่อเราต้องประเมินชวเลขที่อยู่ในตัวเลข ตัวอย่างเช่นด้วย

2k15

สำหรับวัตถุประสงค์ของการประเมินผลเราแยกนี้ขึ้นเป็นสามหมายเลข: 2, 1000(ซึ่งเป็นk) 15และ จากนั้นตามกฎเรารวมเข้าด้วยกันเพื่อรับ

2*1000 + 15 = 2015

หวังว่านี่จะช่วยให้เข้าใจกฎต่อไปนี้ได้ง่ายขึ้น

กฎระเบียบ

หมายเหตุหากไม่ได้ระบุเป็นอย่างอื่นคุณสามารถแปลความหมายของคำว่า "ตัวเลข" หรือคำพ้องความหมายเพื่อรวมชวเลข

  1. ต่อไปนี้จะถือว่า shorthands k, m, b, t, and eตัวเลขการทำงานของคุณจะต้องสามารถที่จะดำเนินการ: k, m, b, and tสอดคล้องกับค่า1000, 1000000, 1000000000, and 1000000000000ตามลำดับ (หนึ่งพันหนึ่งล้านหนึ่งพันหนึ่งพันล้านล้าน) eชวเลขจะเสมอตามด้วยหมายเลขอื่นและแสดงให้เห็นถึงn 10^nคุณต้องอนุญาตให้มีการจดชวเลขตัวเลขในปัจจุบันnและก่อนหน้าeนี้ ยกตัวอย่างเช่นการประเมินkek1000*10^1000

  2. เพื่อความเรียบง่ายถ้าตัวเลขมีชวเลขeอยู่ในนั้นจะใช้เพียงครั้งเดียว

  3. จำนวนใด ๆ ( รวมชวเลข ) ก่อนที่จะมีการจดชวเลข เช่นจะได้รับการประเมินว่าเป็น120kk 120 * 1000 * 1000หากไม่มีตัวเลขอยู่ก่อนหน้าคุณต้องสมมติว่าตัวเลขนั้นเป็น 1 (เช่นเดียวกับที่คุณคิดว่าในทางคณิตศาสตร์ให้ถือว่าตัวแปรxเป็นนัย1x) เช่นe10ประเมิน10^10ว่า อีกตัวอย่าง: 2m2kประเมินเป็น2*1000000*2*1000(ไม่มีการเพิ่มอะไรลงไป)

  4. หมายเลขใด ๆ (การจดชวเลขไม่ได้นำไปใช้) หลังจากการจดชวเลขครั้งสุดท้ายในจำนวนที่มีการจดชวเลขจะถูกเพิ่มเข้าไป เช่นจะได้รับการประเมินว่าเป็น2k12 2*1000 + 12ข้อยกเว้นนี้คือถ้าใช้ชวเลขeซึ่งในกรณีนี้จำนวน ( รวมชวเลข ) ต่อไปนี้eจะได้รับการปฏิบัติnและประเมินเป็น10^n(ดูกฎแรก)

  5. ฟังก์ชั่นของคุณจะต้องสามารถประมวลผลตัวดำเนินการ+, -, *, and /ซึ่ง ได้แก่ การบวกการลบการคูณและการหารตามลำดับ มันอาจดำเนินการมากขึ้นถ้าคุณต้องการ

  6. การดำเนินงานจะได้รับการประเมินตามลำดับของการดำเนินการ

  7. ตัวเลขในชวเลขไม่ได้เป็นจำนวนเต็มเท่านั้น 3.5b1.2ถูกต้องและจะถูกประเมินเป็น3.5*1000000000 + 1.2 = 3500000001.2

  8. ไม่อนุญาตให้ใช้บิวด์อินหากมีอยู่สำหรับสิ่งนี้ ข้อยกเว้นที่ฉันจะเพิ่มก็คือหากภาษาของคุณแปลงตัวเลขขนาดใหญ่เป็นสัญกรณ์วิทยาศาสตร์โดยอัตโนมัติซึ่งในกรณีที่ยอมรับได้สำหรับผลลัพธ์ของคุณ

  9. รหัสที่สั้นที่สุดในการชนะไบต์ใช้ช่องโหว่มาตรฐาน

อินพุต

อินพุตจะเป็นนิพจน์โดยแต่ละหมายเลขและโอเปอเรเตอร์คั่นด้วยช่องว่าง ตัวเลขอาจมีหรือไม่มีชวเลข ตัวอย่างที่แสดงด้านล่าง:

10 + 1b - 2k

เอาท์พุต

ฟังก์ชั่นของคุณจะต้องส่งออกการประเมินผลของการแสดงออกเป็นจำนวน อนุญาตให้ใช้สัญกรณ์ทางวิทยาศาสตร์ได้หากเอาต์พุตมีขนาดใหญ่เกินกว่าจะแสดงได้ คุณต้องมีทศนิยมอย่างน้อยสามตำแหน่งหากตัวเลขไม่ใช่จำนวนเต็ม สามารถยอมรับได้หากคุณเก็บทศนิยมไว้หากตัวเลขเป็นจำนวนเต็ม

กรณีทดสอบ

อินพุต

t

เอาท์พุต

1000000000000

อินพุต

1 + 4b / 10k11

เอาท์พุต

399561.483

อินพุต

e2 + k2ke-1 - b12

เอาท์พุต

-999799912

หรือ

-999799912.000

อินพุต

142ek12

เอาท์พุต

142e1012

หรือ

142.000e1012

การป้อนข้อมูล:

1.2m5.25

เอาท์พุท:

1200005.25

หมายเหตุสุดท้าย

นี่เป็นความท้าทายครั้งแรกของฉันที่โพสต์ (ด้วยความช่วยเหลือจากผู้ใช้บน sandbox) หากมีสิ่งใดไม่ชัดเจนให้ฉันรู้จักและฉันจะพยายามอย่างดีที่สุดเพื่อชี้แจง


1
ความท้าทายแรกที่ดี
Digital Trauma

@ DigitalTrauma ขอบคุณมาก! ฉันหวังว่าจะเห็นคำตอบ
โคล

ฉันไม่เข้าใจตัวอย่างที่สอง ผมคิดว่าในระยะกลางถูกตีความว่าเป็นแต่ที่ให้คำตอบสุดท้ายของ1000 + 2000 * 10 ^ -1 -999998712(นอกจากนี้การตีความของฉันดูเหมือนจะไม่พูดกับ "บทสรุปสุดท้าย " ของกฎ 4 แต่ฉันไม่แน่ใจว่าจะเข้าใจลำดับk2kอื่นได้อย่างไร) คุณช่วยอธิบายขั้นตอนในการประเมินได้ไหม
DLosc

@ ตรีโกณมิติใช่มันควรจะเป็นตัวเลขเท่านั้น จับดี.
โคล

1
หลังจากดูความคิดเห็นในการโพสต์แซนด์บ็อกซ์ฉันคิดว่า2m2kควรเพิ่มตัวอย่างเช่นในการสนทนาของกฎ 3 นอกจากนี้ควรใช้คำอื่น - อาจจะเป็น "จำนวนเต็ม" - สำหรับตัวเลขตามตัวอักษรเช่น123นั้น มีไม่ shorthands คำว่า "หมายเลข" มีคำจำกัดความที่แตกต่างกันประมาณ 3 ข้อที่นี่เนื่องจากมันอยู่ในขณะนี้
DLosc

คำตอบ:


4

Python 2, 553 ไบต์

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

คำถามนี้ดูเล็กน้อยที่ไม่มีใครรักและดูสนุกดังนั้นฉันจึงให้มันยิง ฉันไม่เคยเล่นรหัสกอล์ฟมาก่อนดังนั้นอาจมีหลายสิ่งที่สามารถปรับปรุงได้ แต่ฉันให้ดีที่สุดโดยอิงจากความรู้ด้านภาษาของฉัน วิธีการแก้ปัญหาเทียบเท่าเป็นไปได้ในหลาม 3 ค่าใช้จ่ายของหนึ่งไบต์พิเศษ: ->print repr(z[0])print(repr(z[0]))

การใช้งานเป็นสิ่งที่สอดคล้องกับสายของ

python2 ShorthandMath.py <equation>

กล่าวคือ

python2 ShorthandMath.py e2 + k2ke-1 - b12

เอาท์พุท

-999799912.0

ป้อนข้อมูลสำหรับวิธีการปรับปรุงนี้จะได้รับการชื่นชมมาก หากมีความสนใจเพียงพอฉันสามารถถอดออกและแสดงความคิดเห็นโปรแกรม แต่ส่วนใหญ่มันชัดเจนชัดเจนแล้ว (ความจริงเกี่ยวกับรหัสกอล์ฟ)

ควรสังเกตว่าโปรแกรมหยุดทำงานพร้อมกับตัวอย่าง142ek12เนื่องจากค่านั้นมีขนาดใหญ่อย่างน่าหัวเราะและโปรแกรมโอเวอร์โฟลว์

เพื่อชดเชยสิ่งต่อไปนี้จะยาวขึ้นอีกเล็กน้อย แต่ในทางทฤษฎีสามารถจัดการสิ่งใดก็ได้ที่โยนทิ้งเนื่องจากการใช้ไลบรารีที่มีความแม่นยำในตัวเอง ไวยากรณ์เหมือนกัน

Python 2, 589 588 ไบต์ (ความแม่นยำโดยพลการ)

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.