减少数学陈述


18

挑战

您是名为Coyote Beta的出色服务的所有者,该服务神奇地回答了用户通过互联网发送给它的数学问题。

但事实证明,带宽很昂贵。您有两种选择,要么创建“ 土狼Beta Pro”,要么找到解决该问题的方法。就在最近,有人在询问(x + 2)。客户端无法发送x+2,用户将看不到差异吗?

任务

您的任务是“最小化”数学表达式。给定一个输入表达式,您必须除去空格和括号,直到它给出相同输入的最小表示。关联运算的括号不需要保留。

这里给出的唯一运营商+-*/,和^(幂),与标准的数学关联性和优先级。输入中给出的唯一空白将是实际的空格字符。

样本输入/输出

Input       | Output
------------|--------------
(2+x) + 3   | 2+x+3
((4+5))*x   | (4+5)*x
z^(x+42)    | z^(x+42)
x - ((y)+2) | x-(y+2)
(z - y) - x | z-y-x
x^(y^2)     | x^y^2
x^2 / z     | x^2/z
- (x + 5)+3 | -(x+5)+3

计分

输入/输出可以使用任何首选方法。以字节为单位的最小程序获胜。

确切的位

求幂是正确的关联,也遵循标准的数学优先级(最高)。有效数字文字为/[0-9]+/,有效变量文字为/[a-z]+/。即使变量的字符长度大于1,单个变量文字也代表一个值。

“不需要保留关联操作的括号”的意思是,输出应包含一个导致相同解析树的表达式,但可以重新安排关联操作。


这个想法是创建一个最小的等效语句,以产生相同的解析树。这样,当用户进行查询时,土狼Beta可以直观地显示它。
TND

如果有效变量为/[a-z]+/,则表示ab不允许通过并列相乘?
Joe Z.

1
您确实想2+(3+4)更改为2+3+4,对吗?这确实会更改分析树。
feersum

2
我对下列主张表示x^(y/2)=x^y/2质疑; 幂运算具有较高的优先级ergo x^y/2=(x^y)/2
Conor O'Brien 2015年

1
噢,我要用Prompt X:expr(X)TI-BASIC 提交,但您无法简化:(
DankMemes,2015年

Answers:


1

C#,523个 519 504字节

检查代码中的注释以查看其工作原理!


打高尔夫球

using System;using System.Collections.Generic;namespace n{class p{static void Main(string[]a){foreach(String s in a){String r=s.Replace(" ","");List<int>l=new List<int>();for(int i=0;i<r.Length;i++){if(r[i]=='('){l.Add(i);continue;}if(r[i]==')'){switch(r[Math.Max(l[l.Count-1]-1,0)]){case'+':case'(':switch(r[Math.Min(i+1,r.Length-1)]){case'+':case'-':case')':r=r.Remove(Math.Max(l[l.Count-1],0),1);r=r.Remove(Math.Min(i,r.Length)-1,1);i-=2;break;}break;}l.RemoveAt(l.Count-1);}}Console.WriteLine(r);}}}}

不打高尔夫球

using System;
using System.Collections.Generic;

namespace n {
    class p {
        static void Main( string[] a ) {
            // Loop every String given for the program
            foreach (String s in a) {
                // Get rid of the spaces
                String r = s.Replace( " ", "" );

                // A little helper that will have the indexes of the '('
                List<int> l = new List<int>();

                // Begin the optimizatio process
                for (int i = 0; i < r.Length; i++) {
                    // If char is an '(', add the index to the helper list and continue
                    if (r[ i ] == '(') {
                        l.Add( i );
                        continue;
                    }

                    // If the char is an ')', validate the group
                    if (r[ i ] == ')') {
                        // If the char before the last '(' is an '+' or '(' ...
                        switch (r[ Math.Max( l[ l.Count - 1 ] - 1, 0 ) ]) {
                            case '+':
                            case '(':
                                // ... and the char after the ')' we're checking now is an '+', '-' or ')' ...
                                switch (r[ Math.Min( i + 1, r.Length - 1 ) ]) {
                                    case '+':
                                    case '-':
                                    case ')':
                                        // Remove the '()' since they're most likely desnecessary.
                                        r = r.Remove( Math.Max( l[ l.Count - 1 ], 0 ), 1 );
                                        r = r.Remove( Math.Min( i, r.Length ) - 1, 1 );

                                        // Go two steps back in the loop since we removed 2 chars from the String,
                                        //   otherwise we would miss some invalid inputs
                                        i -= 2;
                                        break;
                                }

                                break;
                        }

                        // Remove the last inserted index of '(' from the list,
                        //   since we matched an ')' for it.
                        l.RemoveAt( l.Count - 1 );
                    }
                }

                // Print the result
                Console.WriteLine( r );
            }
        }
    }
}

旁注

  1. 修复了一些拼写错误,并重命名了一些变量。
  2. 嵌套开关以摆脱不必要的变量。此外,还修复了Anders Kaseorg报告的使某些解决方案无效的错误。

PS:如果您有提示或发现错误,请在评论中让我知道,我将尝试对其进行修复(然后,以您的姓名添加有关该错误修复的注释;))


好答案!:D实质性的答案,如果您包括一个解释,通常会更好地得到:P
cat

我可以用代码注释的形式吗?
auhmaan '16

当然,任何有效的方法c:

那我去做 我还将尝试在某处添加摘要。
auhmaan '16

顺便说一下,欢迎来到编程难题和Code Golf!(即使这不是您的第一个答案)
cat

0

C ++,284字节

打高尔夫球

#include<iostream>
#include<algorithm>
int main(){std::string e;std::getline(std::cin,e);e.erase(std::remove_if(e.begin(),e.end(),isspace),e.end());for(int x=0;x<e.length();x++){if(e[x]=='('&&e[x+1]=='('){e.erase(x,1);}if(e[x]==')'&&e[x+1]==')'){e.erase(x,1);}}std::cout<<e;return 0;}

不打高尔夫球

#include<iostream>
#include<algorithm>

int main()
{
    std::string e;
    std::getline(std::cin, e);
    e.erase(std::remove_if(e.begin(), e.end(), isspace), e.end());
    for(int x = 0; x < e.length(); x++) {
        if (e[x] == '(' && e[x+1] == '('){
            e.erase(x, 1);
        }
        if (e[x] == ')' && e[x+1] == ')'){
            e.erase(x, 1);
        }
    }
    std::cout<<e;
    return 0;
}

它没有任何优先逻辑,并且使许多给定的测试用例都失败了。
Anders Kaseorg '16
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.