수학 문장 축소


18

도전

귀하는 Coyote Beta 라는 놀라운 서비스의 소유자입니다.이 서비스 는 사용자가 인터넷을 통해 수학 질문에 마술로 대답합니다.

그러나 대역폭이 비싸다는 것이 밝혀졌습니다. " 코요테 베타 프로"를 만들거나이 문제를 해결할 방법을 찾는 두 가지 방법이 있습니다. 최근에 누군가가 질문했습니다 (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보다 길더라도 단일 값을 나타냅니다.

"연관 연산 주위의 괄호를 보존 할 필요는 없다"는 의미는 연산이 재 배열 될 수 있다는 점을 제외하고 출력이 동일한 구문 분석 트리를 생성하는 표현식으로 구성되어야한다는 것입니다.


아이디어는 동일한 구문 분석 트리를 생성하는 최소한의 동등한 명령문을 작성하는 것입니다. 이는 사용자가 쿼리 할 때 Coyote 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

1
Aww man, Prompt X:expr(X)TI-BASIC 에 제출하려고 했지만 단순화 할 수는 없습니다 :(
DankMemes

답변:


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에 의해 일부 솔루션이 유효하지 않은 버그가 수정 되었습니다 .

추신 : 팁이 있거나 버그를 발견 한 경우 의견에 알려주십시오. 그러면 문제를 해결할 것입니다 (귀하의 이름으로 버그 수정에 대한 메모를 추가합니다.))


좋은 대답입니다! : 설명을 포함하면 여기에 실질적인 답변이 더 많이 수신됩니다. : P
cat

코드 주석 형태로 할 수 있습니까?
auhmaan

물론, 어떤 것이 든 작동 c :
cat

그럼 내가 할게요! 또한 어딘가에 요약을 추가하려고합니다.
auhmaan

그건 그렇고 프로그래밍 퍼즐과 코드 골프에 오신 것을 환영합니다! (첫 번째 답변은 아니지만)
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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.