数学ステートメントの縮小


18

チャレンジ

あなたはCoyote Betaと呼ばれる素晴らしいサービスの所有者です。これは、ユーザーがインターネット経由で送信する数学の質問に魔法のように答えます。

しかし、結局のところ、帯域幅は高価です。「コヨーテベータプロ」を作成するか、これを解決する方法を見つけるかの2つの選択肢があります。つい最近、誰かが質問した(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は許可されませんか?
ジョーZ.

1
2+(3+4)に変更したい2+3+4ですか?これにより、解析ツリーが変更されます。
feersum

2
私はその主張に問題があるx^(y/2)=x^y/2; べき乗の優先順位は、エルゴなどx^y/2=(x^y)/2です。
コナーオブライエン

1
ああ、私は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によって報告された一部のソリューションを無効にするバグを修正しました

PS:ヒントがある場合やバグが見つかった場合は、コメントでお知らせください。修正を試みます(バグ修正に関するメモをあなたの名前で追加します;))


いい答え!:Dここでの実質的な答えは、説明を含めると一般的に良くなります。:P
cat

コードコメントの形でそれを行うことはできますか?
-auhmaan

確かに、何でも動作しますc:
cat

それから私はそれをします!また、どこかに要約を追加しようとします。
-auhmaan

プログラミングパズルとコードゴルフへようこそ。(それはあなたの最初の答えではないにもかかわらず)

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;
}

これには優先順位ロジックがなく、指定されたテストケースの多くが失敗します。
アンデルスカセオルグ16
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.