数学問題表記法を解く


14

それぞれに整数が与えられた宿題の問題が無限にあると想像してください(!)。

数学問題表記法は、問題指定子を使用して問題のサブセットを記述するための表記法です。

MPN式は、次のもので構成されます。

  • 単一の値。これは、番号を含むセットを表します99 -> {99}
  • シンプルな範囲。これは、範囲の最初から最後までのすべての数値を含むセットを表します10~13 -> {10, 11, 12, 13}。左側または右側が欠落している場合、それぞれ-InfinityまたはInfinityと見なされます~10 -> {x|x ≤ 10}~ -> ℤ
  • 「スキップ」と別のMPN式が続くMPN式。これは、2つのセットの差を表します10~20 skip 12~14 -> {10, 11, 15, 16, 17, 18, 19, 20}
  • コンマで区切られた2つのMPN式。これは、2つのセットの和集合を表します1,8~9,15~17 -> {1,8,9,15,16,17}

「スキップ」演算子はコンマ演算子よりも厳密にバインドするため、16,110~112 skip 16 -> {16,110,111,112}16はset {110,111,112}に含まれないため、16を除外することは問題になりません。

曖昧さをなくすために括弧で式を置くこともできます: 1~9 skip (2~8 skip (3~7 skip (4~6 skip 5))) -> {1,3,5,7,9}

これは文法です:

<expr>  ::= "(" <expr> ")"
         || <number>
         || [<number>] "~" [<number>]
         || <expr> "skip" <expr>
         || <expr> "," <expr>

あなたの仕事は、2つの入力を受け取るプログラムを作成することです。

  • MPN式

そして、その問題がMPN式で記述されたセットにあるかどうかに応じて、真偽値または偽値を出力します。

仕様書

  • 最初の入力が整形式のMPN式であると想定できます(つまり、上記の文法と一致する)
  • MPN式の数値は常に整数です。負またはゼロにすることができますが、小数部分はありません。
  • これはであるため、最短の有効な送信(バイト単位で測定)が優先されます。
  • 必要に応じて~,に異なる文字を使用できます。

テストケース

10~20             14 -> True
10~20             20 -> True
10~20 skip 14~18  17 -> False
~ skip 6          8  -> True
16,17 skip 16     16 -> True
(16,17) skip 16   16 -> False
~10,5~            8  -> True
~10,5~            4  -> True
6 skip 6,~        6  -> True

他の文字を使用して演算子を表すことは可能ですか?。たとえば、〜の代わりに#を使用する
-rahnema1

1
@ rahnema1 ~および,に対して、ただしに対してではありませんskip
エソランジングフルーツ

3
4が〜10,5〜であるのはなぜですか?これは、
-∞から10、5

@ ev3commander編集。私はいつもテストケースを台無しにします。私はそれらを追加しなかった場合、私の課題が明確になり賭け:P
Esolangingフルーツ

1
@ Challenger5テストケース6 skip 6,~を追加しましたが、正しく解釈できた思います。他の2つの答えはこれまでのところ満足していません(これもまた、私が正しく解釈していると仮定して)。誤解した場合は修正して明確にしてください。しかし、私の理解から、それは何にも一致するはずです(すべてに一致するセットと何も一致しないセットの和集合です)。これらは、以前に話していた種類のケースであり、ソリューションをテストするときに大いに役立つと思います。
-briantist

回答:


3

PowerShell189195バイト

param($m,$q)('$m',"'(\d*)~(\d*)','($q-ge(`$1)-and$q-le(`$2))'","'\(\)',$q","'((?<=,|skip )\d+|\d+(?=,| skip))','($q-eq`$1)'","'skip','-and!'"-join'-replace'|iex|% Sp* ','|%{"($_)"})-join'-or'|iex

説明

配列の生成や値のテストには無限大がこれを受け入れがたくすることを私は早い段階で認識しました。

私は範囲を調べましたが、.Netでは必要な範囲がありません(範囲の長さは符号付き(32ビット)整数に制限されているので、範囲を符号付き32ビットintに制限しても問題ありませんでした、すべての範囲を処理できなかったでしょう。

したがって、開始と終了の観点からこれについて考え始め、最終的に一連のブールテストを実行し、一連の正規表現置換を作成して、MPNをPowerShellが理解できるブール式に変換しました。

基本的に、これをいくつかのルールに分解しました。

  • 範囲は、どちらの側でも式にすることができないため、最初に操作する方が簡単でしたが、すぐに実装するのは苦労でした。前提は2~8、と言っているようなn >=2 && n <=8ものですが、端の1つが欠落している場合は&&、欠落している側を省略します。両方が欠落している場合、元々それを単にに置き換えるつもり$trueでした。私がやったことは、実際に行方不明の側をテストすることではありませんでしたが、各番号をでラップすることを確認しました()
  • 次に、空の括弧()を入力値に置き換える直接置換を実行します。したがって、~8入力値がのようなMPNの場合55、最初の置換が生成され(55-ge()-and55-le(8))、次に2番目の置換が行われて(55-ge55-and55-le(8))、本質的に範囲のその部分が無効になります。
  • 次に、MPNの個々の番号を処理する必要がありましたが、前から挿入した番号を混乱させないように注意する必要がありました。それは本当にカンマ,区切りのリストの数字でありskip、aの前後の個々の数字なので、残念ながら長い見回しを使用しました。
  • skipは基本的には同じな-and -notので、skiptoをそのまま置き換えます-and!(の!省略形として使用-not)。
  • 次のトリッキーなことは、残りのコンマの優先順位が低いことです。私はもともとそれらを置き換えました-orが、その後の式を考慮しなかったため、の16,17 skip 16ようなコードを生成していました($n-eq16)-or($n-eq17) -and! ($n-eq16)。括弧が必要でしたが、それはまっすぐに置き換えると実行不可能に思えました。コンマ以外のすべてのものが置き換えられ、優先順位が最も低いため、生成された文字列全体を残りのコンマで分割し、各要素を括弧で囲み、で再結合しました-or

最終的に、生成されたコードはInvoke-Expressioniex)にパイプされて実行されるだけで、ブール値の結果が得られます結果の代わりに生成されたコードを見ることができます)。

これには時間がかかりすぎて、さらに数バイトを圧縮する余地があると確信していますが、もう見ることはできません:-p


2

Perl、99 130バイト

sub f{($_,$n)=@_;s/(-?\d+)?~(-?\d+)?|(-?\d+)/!(defined$3?$n!=$3:length$1&&$1>$n||length$2&&$n>$2)+0/ge;s/skip/&&!/g;s/,/||/g;eval}

Ideoneでお試しください。

ゴルフをしていない:

sub f {
    my ($e, $n) = @_;

    $e =~ s/(-?\d+)?~(-?\d+)?|(-?\d+)/ (defined($3) ? $n == $3 : (!length($1) || $n >= $1) && (!length($2) || $n <= $2)) + 0 /ge;
    $e =~ s/skip/ && ! /g;
    $e =~ s/,/ || /g;

    return eval($e);
}

1
入力-2で〜-2が失敗します。挿入するときも-?3つのすべての\ D *の前に
はKjetil S.

@KjetilS。負の数とゼロの修正。
デニスイバエフ

素敵なコード(本格的な文法がしばしば必要ではないの解析、正規表現は簡単です)
はKjetil S.

1

JavaScript(ES6)、221 292 287 309 274 277 278バイト

(Oxxのおかげで5バイト)

(j,v,m=1/0,Z=/(skip)([^,]+)/g)=>eval(j[M='replace'](/(-?\d*)~(-?\d*)/g,(e,a,b)=>(a[M]('-','#')||-m)+'<='+(T=v[M]('-','#'))+'&&'+T+'<='+(b[M]('-','#')||m))[M](Z,i=o=>o.match(Z)?i(o[M](Z,'&&!($2)')):o)[M](/,/g,'||')[M](/(^|[^=&#\d])(\d+)([^<\d]|$)/g,'$1$2=='+v+'$3')[M](/#/g,'-'))

ワオ。これはすべてのエッジケースのため簡単ではありませんでしたが、私はそれをしたと思います。私は願っています使用される正規表現を破ることができ、特別な例はありません。できればいつでもこれをゴルフします。

テストスニペット

D=(j,v,m=1/0,Z=/(skip)([^,]+)/g)=>eval(j[M='replace'](/(-?\d*)~(-?\d*)/g,(e,a,b)=>(a[M]('-','#')||-m)+'<='+(T=v[M]('-','#'))+'&&'+T+'<='+(b[M]('-','#')||m))[M](Z,i=o=>o.match(Z)?i(o[M](Z,'&&!($2)')):o)[M](/,/g,'||')[M](/(^|[^=&#\d])(\d+)([^<\d]|$)/g,'$1$2=='+v+'$3')[M](/#/g,'-'))
MPN Expression:<input type="text" value="1~9 skip (2~8 skip (3~7 skip (4~6 skip 5)))" id="MPN"></input>
<br>
Integer:<input type="number" id="INT" value=6></input>
<input type="button" value="Submit" onclick="T=r=>document.getElementById(r).value;console.log(D(T('MPN'),T('INT')))"></input>


@AriaAxこれで動作するはずです。
R. Kap

R.Kap @あなたは使用することができます 1/0のためにInfinity
Okx

@ R.Kap私はあるべきだと思う66 skip 6,~で値を試しましたがtrue、それは戻りますfalse
-briantist

@briantist実際、括弧で囲まれていない限り、それに続くすべて(この場合)に適用されるように返されるべきだと思います。そのため、整数入力ではなくを返す必要があると考えています。falseskip6,~true(6 skip 6),~6 skip 6,~6
R. Kap

@briantistつまり、set とsetの違いを表すため、何にも6 skip 6,~一致しないはずです。{6}{6,-Infinity...Infinity}
R. Kap

0

ローダ + bc、183バイト

f x{{["x=",x,"\n"];replace" ","",",","||","skip\\(","&&!","skip([0-9~]+)","&&!($1)","(?<!~|\\d)(\\d+)(?!~|\\d)","x==$1","(\\d*)~(\\d*)","x>=($1)&&x<=($2)","\\(\\)",x;["\n"]}|exec"bc"}

これは、PowerShellの回答に似ています(または、PowerShellが理解できないと思います)。次のように、入力ストリームで引数として数値を、値としてコードを受け取りますmain { push("1~9") | f(5) }

少なくとも、すべてのテストケースを解決できると思います。以下のスクリプトを使用して、これを確認できます。

main {
    readLines("/tmp/tests.txt") | split(sep=";") | for code, num, ans do
        push(code, " -> ")
        print(code) | replace" ","",",","||","skip\\(","&&!","skip([0-9~]+)","&&!($1)","(?<!~|\\d)(\\d+)(?!~|\\d)","x==$1","(\\d*)~(\\d*)","x>=($1)&&x<=($2)","\\(\\)",num
        a := push(code) | f(num) | head()
        result := push("OK") if [ (a = "0" and ans = "False") or (a = "1" and ans = "True") ] else push("FAIL")
        print code, " ; ", num, " -> ", a, " ", ans, " (", result, ")\n"
    done
}

そしてテスト:

10~20;14;True
10~20;20;True
10~20 skip 14~18;17;False
~ skip 6;8;True
16,17 skip 16;16;True
(16,17) skip 16;16;False
~10,5~;8;True
~10,5~;4;True
6 skip 6,~;6;True
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.