交替求解数学表达式


9

创建一个程序,使用表达式交替两边的元素来求解数学表达式。这样做的方法是,先阅读第一个字符,然后阅读最后一个,然后阅读第二个字符,再阅读第二个字符,再读另一个字符,而不是从左到右阅读。这将为您提供一个新的表达式,您必须对其进行计算和输出。

a*b/c+d-e
135798642  <-- Order you read the expression in
ae*-bd/+c  <-- Order of operation. 

例:

1*3/2+4-5
15*-34/+2 = -255

如果表达式不起作用,则1必须将其插入必要的位置以使其起作用。

一些示例可能会更好地说明它:

Input: 1+1+1+1+1
Result: 23     // Because 1+1+1+1+1 -> 11++11++1 -> 23

Input: 1+2-3+12-5
Result: -19    // Because 1+2-3+12-5 -> 15+-22-13+ -> 15+-22-13+1 -> -19
               //                                 |
               //                                 Not valid expression

Input: 2*2*2*2*2
Result: 968    // Because 2*2*2*2*2 -> 22**22**2 -> 22*1*22*1*2 -> 968
               //                        ||  ||
               //                        Not valid, 1 must be inserted

Input: 17/2
Output: 127    // Because 17/2 = 127/ -> 127/1 -> 127

必须支持的运算符为+ - * /。不会有括号。使用正常的数学规则和“语法”,因此例如**并不意味着求幂。a++++1等价于a+1(即MATLAB风格,而不是C ++)。

如有疑问,一些有效的操作是:

-a
+a
a++b
a+-b
a*-b
a*+b
a*++b
a/b
a/-b
a/+b
-a/--b

虽然以下所有无效。显示了它们应替换为:

a+      | a+1
a-      | a-1
a++++   | a++++1   (This is equivalent to a+1)
a*+++   | a*+++1   (This is equivalent to a*1)
a**b    | a*1*b
a*/b    | a*1/b
a/*b    | a/1*b
a*      | a*1
*a      | 1*a
***a    | 1*1*1*a

规则:

  • 该代码可以是函数或完整程序
  • 输入可以是STDIN或函数参数
  • 输入的内容必须是有效的数学表达式,且不带引号''""
  • 输出应为新表达式的答案,以整数,十进制或简化的分数表示。
  • 小数点后必须至少支持三位数字。所以1/3 = 0.333,不是0.330.333333333被接受。
  • ans = ... 被接受。
  • 开头和结尾的换行符和空格均被接受。
  • 输入只会是整数
  • 零除可能导致错误,NaN,Inf等。不接受输出数字。

与往常一样,以字节为单位的最短代码获胜。从挑战发布之日起的一周内将选出一名优胜者。如果发布的答案比当前的领导者短,则仍然可以获胜。


输入字符串上是否有最大长度或运算符/整数输入的数量?另外,我是否必须支持数学运算,直到结束2^64,它是否会出错或自动换行?

“输出应该是答案[ ... ] 简化分数 ...”,因此,0/0如果表达式等于整数除法或取零模,我可以返回吗?

2
如果答案为零,x/0则为有效输出。只要它没有输出错误的答案就可以。错误和“非数字”在定义上是正确的,并且无穷大是“足够正确”,
Stewie Griffin 2015年

可以确定-可以使用eval对吗?
orlp 2015年

是的,评估是可以的。
Stewie Griffin 2015年

Answers:


3

Perl,108 100字节

$_="";while(@F){$_.=shift@F;$_.=pop@F}s@(\*|/)\1+@\1@g;s@^[*/]@1$&@;s@\D$@$&1@;s@\D@$&@g;$_=eval

该代码为96字节,再加上4作为命令行参数-pF//,其中

  • -p插入while (<>) { .. } continue { print }
  • -F//分割输入并将其放入@F

请注意,输入中不应包含尾随换行符,因此请使用 /bin/echo -n 'formula' | perl ...

少打高尔夫球:

$_='';              # reset $_
while(@F) {         # reorder input
   $_.=shift @F;    # take first element off of @_
   $_.=pop @F       # idem for last; if @F is empty, undef is appended
}

s@(\*|/)\1+@\1@g;   # replace 2 or more '*' or '/' with just one: *1 and /1 = nop
s@^[*/]@1$&@;       # if expression starts with * or / prepend a 1
s@\D$@$&1@;         # if expression doesn't end with a number, append 1
s@\D@$& @g;         # eval doesn't like '++1': add spaces after operators
$_ = eval           # set $_ to 3v1l, so the `-p` will print the new value

测试中

将以上内容放入名为的文件中114.pl,并将以下测试脚本放入其旁边的文件中:

%test = (
    '1+1+1+1+1' =>   23,
    '1*3/2+4-5' => -255,
    '1+2-3+12-5'=>  -19,
    '2*2*2*2*2' =>  968,
    '17/2'      =>  127,
    '--/-1-2-'  =>   -2,
    '**2*'      =>    2,
    '++1++'     =>    1,
    '/2/'       =>  0.5,
    '10/'       =>   '',
);

printf "%-20s -> %5s: %5s\n", $_, $test{$_}, `/bin/echo -n '$_' | perl -pF// 114.pl`
for keys %test;

运行它输出:

++1++                ->     1:     1
**2*                 ->     2:     2
17/2                 ->   127:   127
10/                  ->      :
1+1+1+1+1            ->    23:    23
1*3/2+4-5            ->  -255:  -255
2*2*2*2*2            ->   968:   968
1+2-3+12-5           ->   -19:   -19
--/-1-2-             ->    -2:    -2
/2/                  ->   0.5:   0.5

请注意,这1/0会导致被零除的错误:evaloutputs undef,由空字符串表示。


还有一些测试用例!我将使用它们
edc65

3

的JavaScript ES6,105 106

编辑已保存的1字节thx @Kenney

t=>eval("for(t=[...t],p=o='';c=t.reverse().pop();p=c)o+=p<'0'?(c=='/'|c<'+'||' ')+c:c;eval(p<'0'?o+1:o)")

// Less golfed
t=>{
  for(t = [...t], p = o = '';
      c = t.reverse().pop();
      p = c)
    o += p<'0' 
     ? (c=='/' | c=='*' || ' ')+c  // '1' or ' '
     : c;
  return eval(p<'0' ? o+1 : o)
}

测试片段

f=t=>eval("for(t=[...t],p=o='';c=t.reverse().pop();p=c)o+=p<'0'?(c=='/'|c<'+'||' ')+c:c;eval(p<'0'?o+1:o)")

console.log=x=>O.innerHTML+=x+'\n'

function test() { console.log(I.value + ' -> '+f(I.value)) }

;['1+1+1+1+1', '1*3/2+4-5', '1+2-3+12-5', '2*2*2*2*2',
  '17/2', '--/-1-2-', '**2*', '++1++', '/2/', '10/' ]
.forEach(t=>console.log(t+' -> '+f(t)))
Your test <input id=I><button onclick="test()">-></button>
<pre id=O></pre>


为您节省了一个字节:p < '0' ? ( c=='/' | c<'+' || ' ' )+c : c ;
肯尼2015年
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.