用数字速记计算表达式


10

您在一家想要制作用户友好型计算器的公司工作,因此,您要承担增加用户使用“数字速记”(即表示数字的字母,例如kfor)功能的任务1000。因为您的公司希望在上述计算器中节省存储空间,所以您必须尽可能减少代码,以降低存储成本。


你的任务

您将创建一个函数,该函数要么从STDIN读取表达式作为输入,要么将其用作参数并返回其求值或将其打印到STDOUT。

一些澄清

让我做一些定义。首先,我们有输入,我称之为表达式。可能类似于以下内容:

x + y / z

在此表达我们有三个数字:xy,和z,由运营商(分离+/)。这些数字不一定是正整数(甚至整数)。使事情变得复杂的是,当我们必须评估数字中包含的速记时。例如,

2k15

为了进行评估,我们将其分为三个数字:21000(即k)和15。然后,根据规则,我们将它们组合以获得

2*1000 + 15 = 2015

希望这会使理解以下规则更加容易。

规则

注意:除非另有说明,否则您可以解释单词“数字”或其同义词以包括速记。

  1. 以下是您的函数必须能够处理的数字速记形式:k, m, b, t, and e。分别k, m, b, and t对应值1000, 1000000, 1000000000, and 1000000000000(一千,一百万,十亿和一万亿)。该e速记将永远跟着另一个号码,n和代表10^n。您必须允许数字速记出现在n之前和之前e。例如,kek计算为1000*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

最后说明

这是我发布的第一个挑战(在沙盒中得到了用户的一些帮助)。如果有任何不清楚的地方,请告知我,我将尽力澄清。


1
很好的第一个挑战
Digital Trauma 2015年

@DigitalTrauma非常感谢!我期待看到答案。
2015年

我不明白第二个例子。我以为中间术语被解释为1000 + 2000 * 10 ^ -1,但给出了最终答案-999998712。(此外,我的解释似乎并不符合规则4的“ 最后简写 ”,但我不确定其他如何理解序列k2k。)您能否解释一下评估它的步骤?
DLosc

@trichoplax是的,只能是一个数字;接得好。
2015年

1
在查看了沙盒帖子中的评论之后,我认为2m2k应该在规则3的讨论中添加一个类似的示例。此外,对于像123这样的文字数字,最好使用另一个术语(可能是“整数”)是不是速记。到目前为止,“数字”一词在这里有大约3个不同的定义。
DLosc 2015年

Answers:


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

这个问题看起来有点不受欢迎,而且看起来很有趣,所以我试了一下。我以前从未做过代码高尔夫,所以可能有很多可以改进的地方,但是我根据对语言的了解尽力而为。在Python 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]

我要说的是第一个版本应该没问题,如果尝试有什么问题,我会尽快回复您(我现在不能仔细看/想)。
2015年

@科尔真棒,谢谢。我在给出的每个示例中都进行了尝试,并且至少使所有这些正确。
BobChao87
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.