计算小费


16

您和一个朋友走进酒吧。酒保对您很好,因此您决定给他小费。由于没有内置计算器,因此您拔出可信赖的袖珍计算机并编写一个快速程序即可为您计算小费。可是等等!您的操作员键已损坏!您的任务是为任何给定的输入量计算20%的小费。测试输入将采用xx.xx的形式,例如20.96。规则如下:

  • 在数学形式运算符中不使用以下内容:(+ - * / %感谢Wally West)
  • 不使用内置的百分比函数或API
  • 不能访问网络
  • 不使用eval或类似
  • 没有Windows计算器(是的,以前人们已经回答过)
  • 没有内置的提示功能(不是任何一种语言都可以)

输出应四舍五入到小数点后两位。

分数基于字节长度。

如果您的程序可以接受任何小费金额,则为-20%。金额输入将以xx的形式给出,例如35而不是0.35


5
@mniip:提示是您期望在不属于官方价格的餐厅支付的一笔额外费用。我不知道他们是否在俄罗斯这样做。
user2357112支持Monica 2014年

5
哦,那新一代的......我宁愿使用笔和纸,如果我不能用精神上5划分数
视觉

4
@VisioN注意:除以5等于除以10再乘以2,两者都是很容易的心理操作。
user12205 2014年

1
有人可以阐明规则吗:如果您不使用禁止运算符,是否可以使用这些禁止运算符?如果不使用,是否允许乘法*
Ypnypn 2014年

2
@TheDoctor真的是重复的吗?因为它没有添加。
米洛

Answers:


18

JavaScript 81

编辑:结果现在是一个真实的舍入,而不是被截断。

不要在这里使用任何数学运算,而只是使用字符串操作和按位运算符。
所有+char都是字符串连接,或字符串到浮点转换。
适用于(x)x.xx格式的任何xx.xx输入和输出

s='00'+(prompt().replace('.','')<<1);(+s.replace(/(.*)(...)/,'$1.$2')).toFixed(2)

特里克(Trick)解释:20%除以10再乘以2。

  • 通过点向左移动来除以10 (字符串操作)
  • 通过位向左移动,将每个部分乘以2 (按位运算)

当input 99.99为时19.998,它将返回,因此根据OP,它不会“舍入到小数点后两位”。
Geobits 2014年

2
嗯,这是一个很长的解决方案,但是它有12个投票。代码高尔夫的投票是怎么回事?
贾斯汀2014年

@Quincunx是的,你是对的,不是人气竞赛!
Mukul Kumar 2014年

由于它是一个代码高尔夫,所以我可能不会赢,但这并不意味着人们不喜欢我的解决方案...通常,代码高尔夫的赢家并不是投票最多的人。
Michael M.

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳,绝对!感谢您指出这一点。立即修复:)
Michael M.

6

J(9个字符)

J中的一个简短答案:

^.(^.2)^~ 32

1
...而且我不会讲J。它怎么说?
CousinCocaine 2014年

它说:计算32提高到幂log(2); 通常,指数在的右边,^但此处~表示顺序应颠倒;(^.2)是log(.2),^.最后执行的首字母是所有先前计算的对数:log(32 ^ log(.2))
Thomas Baruchel 2014年

4

纯bash,50个 43个字符

可以肯定,这将被击败,但这是一个开始:

a=$[10#${1/.}<<1]
echo ${a%???}.${a: -3:2}

根据评论:

  • /在这里不是除法运算符,它是模式替换参数扩展的一部分
  • % 在这里不是模运算符,它是参数扩展的一部分
  • - 在这里不是减法运算符,它是一个否定,根据评论允许

输出:

$ ./20pct.sh 0.96
.19
$ ./20pct.sh 20.96
4.19
$ ./20pct.sh 1020.96
204.19
$ 

我想我在那里看到了一个正斜线。
米洛(Milo)2014年

@Milo /bash参数扩展的一部分,而不是除法运算符。允许还是不允许?
Digital Trauma 2014年

1
我会允许的,在这种情况下它不是数学运算符...
WallyWest 2014年

1
-3表示取反,而不是减法... @Milo,您需要考虑取反以及这些运算符除了其数学等效项之外还可以使用的其他方式...例如+可以用作JavaScript中的连接器。 ..我可以提出建议吗?将“不使用以下运算符:+-* /%”更改为“不使用其数学形式的以下运算符:+-* /%”
WallyWest 2014年

2
@WallyWest要扮演魔鬼的拥护者,这里的取反仍然是数学运算符。也许“不使用其非一元数学形式的以下运算符:+-* /%” ;-)
Digital Trauma 2014年

4

的Python 98 * 0.8 = 78.4

d=`len('X'*int("{}{:>02}".format(*(raw_input()+".0").split('.')))*2)`;print'%s.%s'%(d[:-3],d[-3:])

Python 74(无奖金)

d=len('X'*int(raw_input().replace('.',''))*2);print'%s.%s'%(d[:-3],d[-3:])

注意

  • + 用于字符串连接
  • * 用于创建字符串的副本

不打高尔夫球

def tip():
    amount = raw_input()
    #Add an extra decimal point so that we can accept integer
    #amount
    amount += ".0"
    #Split the integer and decimal part
    whole, frac = amount.split('.')
    #Multiply amount by 100 :-)
    amount = "{}{:>02}".format(whole, frac)
    #Create amount copies of a character
    st = 'X'*amount
    #Double it
    st *= 2
    #Calculate the Length
    d = len(st)
    #Display the result as 3 decimal fraction
    print'%s.%s'%(d[:-3],d[-3:])

注意

本着问题的精神,我相信尽管遵循该问题的所有规则,以下解决方案也是一种滥用

Python 41

print __import__("operator")(input(),0.2)

最后

如果您坚持禁止使用数学符号,那么她是90个字符的解决方案

Python 90(不带任何数学符号)

print' '.join(str(int(raw_input().replace(".",""))<<1)).replace(' ','.',1).replace(' ','')

1
如前所述,*并且+是损坏的KEY(无论您将其用作什么)。
Thomas Baruchel 2014年

2
@ברוכאל: No use of the following in mathematical form operators: + - * / % (Thanks Wally West)。换句话说,这个问题需要改写。而且我还没有以数学形式使用过它们
阿比吉特(Abhijit)2014年

可以,但是在那种情况下,APL解决方案的低估是不公平的,因为没有其他解决方案因此被降低过。
Thomas Baruchel 2014年

您的答案将有少量的金钱问题,例如0.05
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ 2014年

您可以使用`input`(包括反引号)代替raw_input
nyuszika7h 2014年

4

APL(9个字符,新代码为7个字符,固定为13个字符)

计算给定金额的20%。

{⍟⍵*⍨*.2} 32

在APL中*是指数运算符。

在线尝试。

但是为什么要使用一个函数呢?看到这个新版本:

⍟(*.2)* 32

在线尝试。

请在下降投票之前,*不要将用作密钥,这并不意味着乘法。

好的,这是四舍五入到小数点后两位的版本(Dyalog APL):

⎕PP←2⋄⍟(*.2)* 32.01

2
求幂仍然是一种数学运算,并且*根据挑战规则,不允许以任何数学形式进行求幂。
Tony Ellis 2014年

Exponentiation is not fobidden here and other solutions actually use it, but you are right concerning the fact that * is forbidden as a key and not as its mathematical meaning.
Thomas Baruchel

@Tony H.,请删除您的否决票,因为显然其他解决方案中的所有注释似乎都最终接受了此类KEY,只要它们不被用于初始列表中禁止的数学运算即可。
Thomas Baruchel 2014年

1
我的理解是,禁止以任何与数学意义相关的方式使用星号,包括幂运算。到目前为止,所有其他使用指数的答案都使用^针对此类运算符使用插入符号()的语言,或者使用了函数调用。*仅当在乘法上下文中使用OP时,才禁止使用该规范。我怀疑,如果OP对此做出裁定,解决我们当中哪个人误解了挑战规则并消除混乱,那将是有帮助的。
Tony Ellis 2014年

1
也许×并且÷允许,但未列出。
marinus 2014年

4

电话30 27 36 34

更新为四舍五入到小数点后两位

使用Plannapus,节省了2个字符

创建一个从0到x的向量,并采用第二个元素。

a=function(x)round(seq(0,x,l=6)[2],2)

例:

> a(20.36)
[1] 4.07

进一步说明:

seq(0,x,len=6)

创建一个从0到输入值x的长度为6的向量,其值之间相等。

> seq(0,5,len=6)
[1] 0 1 2 3 4 5

然后,第一个值为0%,第二个为20%,第三个为40%,依此类推。


等等...什么?请给它的工作原理为那些(像我)谁不知道R.更多的细节
迈克尔M.

@Michael更新了我的答案以解释代码
Rift

您的解决方案不进行任何舍入。
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ 2014年

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳您是正确的(但是大多数解决方案都不能取整)。另外的9个字符将进行“正常”舍入。只有四舍五入会更加困难……
Rift

@Rift:我已经测试了几个答案(主要是Python,JS和Perl,因为它们很容易获得),并且大多数都进行了舍入。不过,我测试过的那些都没有。
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ 2014年

3

dc + sed +管道(44个字符)

我的第三个答案(一个APL,一个J,现在一个带有古老而古老的DC)。

dc -e 5o?p|sed -e 's/\(.\)$/.\1/'|dc -e 5i?p

它将要求输入INTEGER并以一种复杂的方式计算20%。输入被转换为基数5(使用许多其他工具都很容易,但是请稍候...);在sed的最后一位数字之前加上一个小数点(不幸的是,dc无法很好地处理字符串),然后,dc从浮点数的5底数转换回去(并非所有工具都可以这样做)。


1
“ INTEGER输入”不符合规范。我认为您可以通过更改sed表达式来解决此问题dc -e 5o?p|sed 's/\(.\)\./.\1/'|dc -e 5i?p。除去seds -e,得到的是42。但是结果仍然不符合规范(不是2个小数位)
Digital Trauma 2014年

@DigitalTrauma。你是对的。但是此解决方案实际上只是一种概念上的证明,我对dc(以及bc)中基数转换的异常特性更感兴趣。感谢您的评论和sed中的修复。
Thomas Baruchel 2014年

2

Python,88岁

这不是很短的时间,但这证明了应该如何将心理智商除以五。假设输入必须为xx.xx形式

import math
a,b=raw_input().split('.')
print'%.2f'%math.ldexp(float(a[0]+'.'+a[1]+b),1)

或者,对于任何长度的输入,需要添加3个字符。

import math
a,b=raw_input().split('.')
print'%.2f'%math.ldexp(float(a[:-1]+'.'+a[-1]+b),1)

说明:我们将输入作为字符串,然后将小数点向前移动一位(除以10)。然后,我们将其转换为浮点数,并使用ldexp函数将其乘以2。

请注意,在此答案中,+是字符串连接运算符,而%则用于格式化print

如果您坚持不使用任何这些字符,请使用以下159个字符的解决方案:

import math
a,b=raw_input().split('.')
l=[a[0]]
l.append('.')
l.append(a[1])
l.append(b)
c=str(math.ldexp(float(''.join(l)),1))
print ''.join([c[0:2],c[2:4]])

已经说了很多其他的答案,但我真的不认为+-被允许因为键被破坏(无论他们在你的代码的意思)。
Thomas Baruchel 2014年

@ברוכאל:请参阅我在回答中对您评论的回应
Abhijit

用你.split('.')的答案,切成一个字符
user80551

2

dc + sed-45 * 0.8 = 36

(灵感来自答案ברוכאל

  • 处理任何小费金额(整数或浮点)

运行示例(通过STDIN接受输入):

$ dc -e 5o?.0+p|sed 's/\(.\)\./.\1/'|dc -e 5i?p
42
8.400
$ dc -e 5o?.0+p|sed 's/\(.\)\./.\1/'|dc -e 5i?p
20.96
4.1920

这个.0+主意很棒;我投票赞成您的解决方案受到我的启发,但有些人可能会告诉您正在使用加法。也许一些解决方法?我试过了,dc -e 9k5o?v2^p但是多了2个字符。
Thomas Baruchel 2014年

@ברוכאל我没有意识到即使在这种情况下,+也可以算作加法。
devnull 2014年

@ברוכאל我将删除它。要求您修改自己的名称,以便它可以处理浮点数并符合资格-20%
devnull 2014年

2

Mathematica,19岁

Log[(E^.2)^Input[]]

没有用的数学运算符的+-*/,或者%。使用对数的属性来计算答案;当您简化表达式时,您会得到.2*Input[]

加上奖金(30 * 0.8 = 24):

Log[((E^.01)^Input[])^Input[]]

首先输入百分比,然后输入金额。

当您简化表达式时,您会得到 Input[]*Input[]*.01

感谢ברוכאל为缩短代码提供的帮助。


3
您确定要简化吗?对我Log[E^2]还是Log[E^Input[]]可以写得更短些。甚至10^-1可以编写.01(尽管我不使用Mathematica,但我可以肯定)。整个表达式(E^10^-1)^Log[E^2]似乎像E^.2,不是吗?
Thomas Baruchel 2014年

1

TI-89基础-39 * 0.8 = 31.2

Input y:Input x:Disp ln(((e^y)^.01)^x))

输入两个数字,然后使用对数属性进行计算 x * y / 100

如果我可以假设输入来自全局变量x和的放置y,那么它要短得多,得分为17 * 0.8 = 13.6

ln(((e^y)^.01)^x)

没有奖金(12):

ln((e^.2)^x)

但是,如果需要将其包装在一个函数中,则可以正常工作(38个字符,为30.4):

:f(x,y):Func:ln(((e^y)^.01)^x):EndFunc

请,请参阅我对您的其他解决方案的评论(在Mathematica中);这段代码确实可以简化很多。
Thomas Baruchel 2014年

Input x,y??? 适用于83/84。
Timtech

@Timtech不能在89中工作,但也许我可以做类似的事情Input{x,y}(83/84有ln吗?)
贾斯汀

@Quincunx是的,请参阅我的新答案。
Timtech

žr¹msmžr.n-将此代码无耻地移植到05AB1E中。
Magic Octopus Urn'Apr

1

PHP 107 * .8 = 85.6

不能真正在PHP的代码高尔夫上运行,但至少我可以对字符串进行操作。接受两个数字作为命令行参数。

<? @$r=strrev;unset($argv[0]);echo$r(substr_replace($r(str_replace('.','',array_product($argv)))),'.',2,0);

由于我不能使用-2 :(


1

Python,81 80 89个字符

a,b=map(str,raw_input().split('.'));c=str(int(a+b)<<1).zfill(4);print c[:-3]+'.'+c[-3:-1]

说明

x = raw_input()       # say 20.96
a , b = x.split('.')  # a = 20 , b = 96
c = a + b             # c = '2096'      # string concatenation , multiplying by 100
d = int(c)<<1         # multiply by 2 by bitshift left , c = 4096
e = str(d).zfill(4)   # zfill pads 0's making the string 
                      # atleast 4 chars which is required 
                      # for decimal notation next

#     divide by 1000 (4) + . (4.) + fraction rounded to 2 decimals (4.09)
print        e[:-3]      +   '.'  +              e[-3:-1]

从技术上讲,这是作弊,因为它被截断为两位小数而不是四舍五入,但是我可以说它四舍五入(对您来说更好,提示更少)。


我认为您可以[-3:]代替[-3:-1]
Justin

@Quincunx不能,-1将截断为两位小数。
user80551

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳是的,修复它。
user80551

1

JavaScript 251(强制限制:不能以任何方式使用+,-,* 、?或%)

虽然我知道这不会赢,但我想我会尝试通过采取非常严格的方法来获得布朗尼积分,甚至不考虑使用任何形状或形式的受限运算符...结果,我想出了这个美女...

A=(x,y)=>{for(;x;)b=x^y,x=(a=x&y)<<1,y=b;return y};D=(x,y,i=x,j=0)=>{for(;i>=y;)i=A(i,A(~y,1)),j=A(j,1);return j};alert(parseFloat((x="00".concat(String(D(prompt().replace(".",""),5)))).substr(0,A(x.length,y=A(~2,1))).concat(".").concat(x.substr(y))))

我使用按位运算来创建Add函数 A,然后从那里开始链接:

整数除法函数D使用了一系列的负加法(A(x,A(~y,1)以循环形式进行减法;剩下的是字符串操作和连接,以避免使用+串联运算符。

该数字必须以十进制形式提供,并带有两个小数位才能起作用。


嗯,现在就可以了。虽然如果我必须遵守新规则,那么我必须继续扩展……现在是251个字节……
WallyWest 2014年

1

Perl,50 60字节

$_=<>;s|\.||;$_<<=1;$_="00$_";m|\d{3}$|;printf'%.2f',"$`.$&"

预期在STDIN上输入。它必须包含带两位十进制数字的十进制分隔符。输出写入STDOUT。

更新:该步骤$_<<=1将删除前导零。因此m|\d{3}$|与小于1的钞票不匹配。因此,十个字节$_="00$添加了,Now甚至0.00可以正常工作。

例子:

  • 输入:20.96,输出:4.19
  • 输入:12.34,输出:2.47

非高尔夫版本:

$_=<>;
s|\.||; # multiply by 100
$_ <<= 1; # multiply by 2
$_="00$_";
m|\d{3}$|; # divide by 1000
printf '%.2f'," $`.$&"

首先从STDIN读取数字。然后删除小数点,该小数点乘以100。然后,通过移位运算符将小数点加倍。然后,重新插入小数点并打印结果并将其四舍五入为两位小数。

50字节(如果bill≥1:

如果x.xx大于或等于1.00,则可以删除10个字节:

$_=<>;s|\.||;$_<<=1;m|\d{3}$|;printf'%.2f',"$`.$&"

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳:谢谢,现在解决。
Heiko Oberdiek 2014年

1

JavaScript(ES6)(正则表达式)142

正则表达式很棒,它可以做很多事情。它甚至可以做数学!

a=('x'.repeat(prompt().replace('.', ''))+'xxxx').match(/^((x*)\2{99}(x{0,99}))\1{4}x{0,4}$/);c=a[3].length;alert(a[2].length+'.'+(c<10?'0'+c:c))

可读版本:

function tip(m) {
    var s = 'x'.repeat(m.replace('.', '')) + 'xxxx';
    var a = s.match(/^((x*)\2{99}(x{0,99}))\1{4}x{0,4}$/);
    var c = a[3].length;
    if (c < 10) c = '0' + c;
    return a[2].length + '.' + c;
}

tip()函数需要String参数,而不是Number参数。

的所有实例*/+不相关的数学运算。

  • + 在所有情况下都是字符串连接。
  • * 是RegExp语法的一部分
  • / 是RegExp文字的定界符

输入必须使用.作为小数点,并且存在必须是小数点后2位数字。

堆栈片段

<button onclick = "a=('x'.repeat(prompt().replace('.', ''))+'xxxx').match(/^((x*)\2{99}(x{0,99}))\1{4}x{0,4}$/);c=a[3].length;alert(a[2].length+'.'+(c<10?'0'+c:c))">Try it out</button>


0

Haskell 32个字符-20%= 25.6个字符

t y x=log $(^x)$(**0.01)$ exp y

滥用指数成为对数乘法的事实。

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.