创建一个多功能计算器


16

灵感。 逆。

评估给定的omnifix表达式。

Omnifix就像普通的数学中缀表示法一样,只是参数周围带有每个符号的其他副本。外部符号代替括号,因此不需要其他括号。

您必须-0-n-在您的语言的合理范围内支持加,减,乘,除和正实数(可以写负数)。

加号和减号必须为+-,但是您可以将*×用作时间和/÷除法。根据要求也可以使用其他合理的符号。

核仁巧克力饼指出了解释和其他功能(例如其他操作,负数,字符串等),即使您的答案没有这些功能,也可以随时演示如何实现。

请提供链接以测试您的解决方案。

例子

为了清楚起见,以下说明使用高减号(¯)表示负数。您可以使用任何合理的格式返回负数。

-5-2-3

+2+×3×2×+8 (+2+×3×2×++2+6+8

-14--3-1--12 (-4--3-1---14-2-12

+2.1+×3.5×2.2×+9.8 (+2.1+×3.5×2.2×++2.1+7.7+9.8

×3×÷-0-6-÷2÷×-9 (×3×÷-0-6-÷2÷××3×÷¯6÷2÷××3ׯ3ׯ9

÷4÷-3-÷1÷2÷-÷1.6 (÷4÷-3-÷1÷2÷-÷÷4÷-3-0.5-÷÷4÷2.5÷1.6


1
The explanations below use high minus (`¯`) to indicate negative numbers.您绝对喜欢APL。
大公埃里克(Erik the Outgolfer)'17年

@EriktheOutgolfer您有更好的建议吗?此外,TI-BASIC的负值较高。
亚当

实际上不是,因为-s可以与-s 混淆,而¯s不能与-s 混淆。
大公埃里克(Erik the Outgolfer)'17年

ah,我刚注意到实数要求。对于我的290字节整数算术Retina解决方案而言,如此之多……
Neil

@Neil为什么不将其发布为答案?
阿达姆(Adám)'17

Answers:


4

C#(.NET Core)198197188字节

float O(string s){try{return float.Parse(s);}catch{var f=s[0];int i=s.IndexOf(f,1);float a=O(s.Substring(1,i-1)),b=O(s.Substring(i+1,s.Length-i-2));return f<43?a*b:f<44?a+b:f<46?a-b:a/b;}}

在线尝试!

用途*/

递归函数。它首先尝试将输入字符串解析为float。如果失败,它将调用自身递归地传递第一个和第二个操作数作为参数,然后对结果执行选定的操作。

  • 多亏了Xcoder先生,节省了1个字节!
  • 感谢TheLethalCoder,节省了9个字节!

IndefOf(f, 1)可以是IndexOf(f,1)
Xcoder先生,2017年

1
使用floats代替,使用char代码,当您拥有它们时,可以在><几个地方将它们缩短。
TheLethalCoder

您可以将字节更改i+1,s.Length-i-2++i,s.Length+~i
凯文·克鲁伊森

4

Python 3中,159个 158 152 144 136 135 132字节

def t(i,a=1):
 while'-'<l[i]!='/':i+=1;a=0
 if a:l[i]='(';i=t(t(i+1));l[i-1]=')'
 return-~i
*l,=input()
t(0)
print(eval(''.join(l)))

在线尝试!

不允许使用负数(-0-5-当然可以),并且需要python运算符。


您可以添加TIO链接吗?
亚当

1
while~-(l[i]in'+-*/'):i+=1;a=1*l,=input()152个字节
Felipe Nardi Batista

1
与所有测试用例:链接
Felipe Nardi Batista


1
if a:l[i]='(';i=t(t(i+1));l[i-1]=')'return-~i135个字节:P
Felipe Nardi Batista

3

视网膜290个 287 286字节

\d+
¦$&$*
¯¦
¯
{`\+([¯¦]1*)\+([¯¦]1*)\+
-$1-¯$2-
-(¯|¦)(1*)-([¯¦]+1*\2)-
-¯$3-¯$1$2-
(×|÷)¯(1*\1)([¯¦]1*\1)
$1¦$2¯$3
צ×[¯¦]1*×|¯¯¦?
¦
¯¦|¦¯
¯
+`-((¯|¦)1*)(1*)-\2\3-
$1
-([¯¦]1*)-[¯¦](1*)-
$1$2
צ1(1*)×([¯¦]1*)×
+צ$1×$2×+$2+
}`÷¦(?=1*÷(¯|¦)(1+)÷)(\2)*1*÷\1\2÷
$1$#3$*
((¯)|¦)(1*)
$2$.3

在线尝试!注意:仅支持整数运算,因此已删除了一些测试用例。接受并使用¯前缀返回负数。编辑:由于@Cowsquack,节省了3 4个字节。说明:

\d+
¦$&$*

我需要某种方式来处理零,因此我将其¦用作正数前缀。然后将数字转换为一元。

¯¦
¯

但是负数只需要一个¯前缀。

{`\+([¯¦]1*)\+([¯¦]1*)\+
-$1-¯$2-

引用+s很难看,所以我将加法转换成减法。

-(¯|¦)(1*)-([¯¦]+1*\2)-
-¯$3-¯$1$2-

如果减法的LHS的绝对值小于RHS,则将它们切换到相反的方向并取反。

(×|÷)¯(1*\1)([¯¦]1*\1)
$1¦$2¯$3

同样,如果乘法或除法的LHS为负,则求反。

צ×[¯¦]1*×|¯¯¦?
¦

同样,如果乘法的LHS为零,则结果为零。另外,两个缺点也加分。

¯¦|¦¯
¯

但是减号和加号(或反之亦然)就是减号。

+`-((¯|¦)1*)(1*)-\2\3-
$1

减去两个相同符号的数字。重复执行此操作,直到没有剩余的减法为止。

-([¯¦]1*)-[¯¦](1*)-
$1$2

如果仍然存在减法,则符号必须不同,因此请将数字加在一起。(但只能执行一次,因为这可能会再次减去两个相同符号的数字。)

צ1(1*)×([¯¦]1*)×
+צ$1×$2×+$2+

通过重复加法执行乘法。

}`÷¦(?=1*÷(¯|¦)(1+)÷)(\2)*1*÷\1\2÷
$1$#3$*

执行整数除法。上述步骤之一将简化表达式,因此请循环返回,直到没有剩余操作为止。

((¯)|¦)(1*)
$2$.3

转换回十进制。


哇,那是史诗般的。PPCG上最大的视网膜帖子?但是,通常QuadR和Retina解决方案彼此非常相似。我可以激发灵感吗?
2015年

在这条线上+`-(([¯¦])1*)(1*)-\2\3-[¯¦]可以成为¯|¦
Kritixi Lithos

@Cowsquack实际上发生了三次,谢谢!
尼尔

您错过了一个([×÷]);)
Kritixi Lithos

1
@Cowsquack您最好不要再找到一个,否则我将不得不
Neil

2

PHP116个 114 109字节

-5感谢Martin Ender

for($s=$argv[$o=1];$o!=$s;)$s=preg_replace('#([*+/-])(([\d.]+|(?R))\1(?3))\1#','($2)',$o=$s);eval("echo$s;");

用途*乘法和/除法。尽管我没有做出任何具体尝试,但负数碰巧仍然起作用。

在线尝试!

脱胎换骨和解释

for($s=$argv[$o=1];   # Initialize with $s = input and $o = 1;
    $o!=$s;)          # While $o != $s
    # Set $o to $s and set $s to be $s after this regex replacement:
    $s=preg_replace('#([*+/-])(([\d.]+|(?R))\1(?3))\1#','($2)',$o=$s);
    # i.e., continue to do this replacement until the result is the same on two consecutive
    # steps (no replacement was made)
# Once $o == $s (i.e. no more replacement can be made), eval the result and print
eval("echo$s;"); 

我还将解释正则表达式,因为它有点神奇:

([*+/-])(([\d.]+|(?R))\1(?3))\1


([*+/-])

首先,我们要匹配四个运算符中的任何一个: *+/-

([\d.]+|(?R))

然后,我们需要匹配一个数字[\d.]+或另一个有效的omnifix表达式(?R)

\1

然后,我们匹配开始时相同的运算符。

(?3)

然后,我们做与第3组相同的事情:匹配一个数字或一个omnifix表达式。

\1

最后,再次匹配初始运算符。

与此匹配的内容都将替换为($2)。这部分内容包含在周围的运算符中,并将其放在方括号内,因此看起来像普通的中缀表示法。


2

QuadR33 32 27字节

-1感谢Cows Quack。-5感谢外长艾里克(Erik the Outgolfer)

((.)[\d¯\.]+){2}\2
⍎¯11↓⍵M

与参数/标志

在线尝试!

这等效于40字节的Dyalog APL解决方案:

'((.)[\d¯\.]+){2}\2'R{⍕⍎1↓¯1↓⍵.Match}⍣≡

在线尝试!

说明

(带括号的文本是指Dyalog APL而不是QuadR)

(... ){2}\2 以下模式的两倍,并且整个匹配太两次:
  (.) 任何字符
  [... ]+ 接着是一个或多个以下的字符集的:
   \dd igits,
   ¯ 高负(负号)
   \. 期间

⎕R 被ř eplaced与:)

{} 以下匿名函数应用于名称空间⍵的结果:)

⍵M (⍵.Match)的文本中号 ATCH
¯1↓ 下降的最后一个字符(符号+ - ×÷
1↓ 下降的第一个字符(符号)
 执行作为APL代码
 ( 字符串化)

 (⍣≡)重复更换,直到不再发生更改为止


我认为您可以
放手

@Cowsquack您对QuadR的看法是正确的。⎕R无法对数字数据进行运算。谢谢。
阿达姆(Adám)'17


1

Haskell,132个字符

(134个字节,因为×÷采取两个字节在UTF-8)

f y|(n@(_:_),r)<-span(`elem`['.'..'9'])y=(read n,r)
f(c:d)|(l,_:s)<-f d,(m,_:r)<-f s=(o[c]l m,r)
o"+"=(+)
o"-"=(-)
o"×"=(*)
o"÷"=(/)

在线尝试!

f尽可能多地解析输入,并产生结果以及剩余的字符串(在测试用例中为空)。如果这不符合规则,则使用

Haskell,139个字符

...
g=fst.f

0

Perl,64 53字节

包含+1-p

perl -pe 's%([*-/])(([\d.]+|(?0))\1(?3))\1%($2)%&&redo;$_=eval' <<< "/4/-3-/1/2/-/"

偶然也实现,(丢弃第一个参数),有时也实现(将参数.附加在一起)。.尽管它在解析级别和评估级别都会干扰小数点,但它并不是很可靠


0

Java 8、205200字节

float O(String s){try{return new Float(s);}catch(Exception e){int f=s.charAt(0),i=s.indexOf(f,1);float a=O(s.substring(1,i)),b=O(s.substring(i+1,s.length()-1));return f<43?a*b:f<44?a+b:f<46?a-b:a/b;}}

@Charlie的C#答案的端口。
-5个字节,感谢@ceilingcat

在线尝试。

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.