私はあなたのBIDMASを見て、BADMISを育てます


21

私はあなたのBIDMASを見て、BADMISを育てます

チャレンジ

"5 + 4 * 9/3-8"の間に演算子を含む一連の数値が与えられた場合、基本演算の順序のすべての順列[/、*、+、-]について、式のすべての可能な結果を​​返します。

ルール

  • 禁止されている標準的な抜け穴
  • I / O
    • 入力は中置演算で順序付けする必要がありますが、最も簡単です(文字列または配列)
    • 単項演算子をサポートする必要はありません(例:「-3 * 8 / +2」)
    • 暗黙的に型を解析する言語では、整数を浮動小数点数に置き換えることができます(例:45⟶45.0)
    • 出力は、式のすべての可能な結果であり、形式または順序は指定しないでください
  • 入力はすべて有効です(たとえば、「7/3 + *」を処理する必要はありません)。これは、ゼロで割る必要がないことも意味します。
  • 演算子はすべて左結合なので、「20/4/4」=「(20/4)/ 2」
  • これはCode Golfなので、バイト数が最も少なくなります

テストケース(説明付き)

  • 「2 + 3 * 4」= [14、20]
    • 2 +(3 * 4)⟶2 +(12)⟶14
    • (2 + 3)* 4⟶(5)* 4⟶20
  • 「18/3 * 2-1」= [11、2、6]
    • ((18/3)* 2)-1⟶((6)* 2)-1⟶(12)-1⟶11
    • (18/3)*(2-1)⟶(6)*(1)⟶6
    • (18 /(3 * 2))-1⟶(18 /(6))-1⟶(3)-1⟶2
    • 18 /(3 *(2-1))⟶18 /(3 *(1))⟶6
    • 18 /((3 * 2)-1)⟶18/5⟶3.6

テストケース(説明なし)

  • 「45/8 + 19/45 * 3」= [6.891666666666667、18.141666666666666、0.11111111111111113、0.01234567901234568、0.01234567901234568、5.765740740740741]
  • 「2 + 6 * 7 * 2 + 6/4」= [112 196 23 87.5]

2
ところで、素敵な最初の挑戦。
シャギー


推奨テストケース2 - 3 + 4=>[-5, 3]
ジョーキング

推奨されるテストケース:2*3-6+2-9/6*8+5/2-9、24の異なる結果が得られます。
アーナルド

回答:



3

C#(Visual C#Interactive Compiler)、285バイト

x=>{int c=0,j,t=1,i;for(;c++<25;t=c){var r="*+-/".ToList();for(i=j=1;j++<4;t=t/j+1)(r[j-1],r[t%j])=(r[t%j],r[j-1]);float k(float z,int p=4){char d;int l;float m;return i<x.Count&&(l=r.IndexOf(d=x[i][0]))<p?k((m=k(x[(i+=2)-1],l))*0+d<43?z*m:d<44?z+m:d<46?z-m:z/m,p):z;}Print(k(x[0]));}}

オンラインでお試しください!

x=>{                                          //Lambda taking in a List<dynamic>
  int c=0,j,t=1,i;                            //A bunch of delcarations jammed together to save bytes
  for(;c++<25;t=c){                           //Loop 24 times (amount of permutations a set of length 4 can have)
    var r="/+*-".ToList();                    //Initialize r as list of operators
    for(i=j=1;j++<4;t=t/j+1)                    //Create the Tth permutation, saving result in r, also reset i to 1
      (r[j-1],r[t%j])=(r[t%j],r[j-1]);
    float k(float z,int p=4) {                //Define local function 'k', with z as current value accumalated and p as current precedence
      char d;int l;float m;                   //Some helper variables
      return i<x.Count                        //If this is not the last number
        &&(l=r.IndexOf(d=x[i][0]))<p?         //  And the current operator's precedence is higher than the current precedence
      k(                                      //  Recursive call with the accumalative value as
        (m=k(x[(i+=2)-1],l))                  //    Another recursive call with the next number following the current operator as seed value,
                                              //    And the next operator's precedence as the precedence value, and store that in variable 'm'
        *0+d<43?z*m:d<44?z+m:d<46?z-m:z/m,    //    And doing the appropriate operation to m and current value ('z')
        p)                                    //  Passing in the current precedence
    :z;                                       //Else just return the current number
    }
    Print(k(x[0]));                           //Print the result of calling k with the first number as starting value
  }
}

指摘したように問題の根本的な部分ではないので、重複を省略する必要がないように修正しました。
フレディR

1
@Arnauld 4バイトのコストで修正されました。これは、順列アルゴリズムが少し間違っていたためです
Ignoranceの具体化

3

JavaScript(Node.js)、132バイト

a=>(w=[],F=(b,a)=>b?[...b].map(q=>F(b.replace(q,""),a.replace(eval(`/[\\d.-]+( \\${q} [\\d.-]+)+/g`),eval))):w.push(a))("+-*/",a)&&w

オンラインでお試しください!

これにより、出力を複製できます。

JavaScriptの(Node.jsの)165の 161 155 153 152 137バイト

a=>Object.keys((F=(b,a)=>b?[...b].map(q=>F(b.replace(q,""),a.replace(eval(`/[\\d.-]+( \\${q} [\\d.-]+)+/g`),eval))):F[a]=1)("+-*/",a)&&F)

オンラインでお試しください!

演算子と数字の間にスペースを含む文字列を受け取ります。

a=>                                             // Main function:
 Object.keys(                                   //  Return the keys of the -
  (
   F=(                                          //   Index container (helper function):
    b,                                          //    Operators
    a                                           //    The expression
   )=>
    b                                           //    If there are operators left:
    ?[...b].map(                                //     For each operator:
     q=>
      F(                                        //      Recur the helper function - 
       b.replace(q,""),                         //       With the operator deleted
       a.replace(                               //       And all -
        eval(`/[\\d.-]+( \\${q} [\\d.-]+)+/g`), //        Expressions using the operator
        eval                                    //        Replaced with the evaluated result
       )
      )
    )
    :F[a]=1                                     //     Otherwise - set the result flag.
  )(
   "+-*/",                                      //    Starting with the four operators
   a                                            //    And the expression
  )
  &&F
 )

@JoKing前に述べた修正を実装しました[3, -5]。今すぐ出力されるはずです。
朝琴しえる

2

Perl 6の92の90 88バイト

{map {[o](@_)($_)},<* / + ->>>.&{$^a;&{S:g{[\-?<[\d.]>+]+%"$a "}=$/.EVAL}}.permutations}

オンラインでお試しください!

演算子の後にスペースを含む文字列を取得し、一連の数値を返します。これは主n op nに、演算子のすべての順列のすべてのインスタンスを評価された結果で置き換えることで機能します。

説明:

{                                                                                   }  # Anonymous code block
                    <* / + ->>>.&{                                    } # Map the operators to:
                                  $^a;&{                             }  # Functions that:
                                        S:g{                }      # Substitute all matches of:
                                            \-?<[\d.]>+]+        # Numbers
                                                         %$a     # Joined by the operator
                                                              =$/.EVAL   # With the match EVAL'd
 map {           },                                                    .permutations   # Map each of the permutations of these operators
      [o](@_)        # Join the functions
             ($_)    # And apply it to the input

set重複を排除する条件が削除されたため、を削除できます。素敵なコード。
フレディR

2

Python 3、108バイト

f=lambda e,s={*"+-*/"}:[str(eval(p.join(g)))for p in s for g in zip(*map(f,e.split(p),[s-{p}]*len(e)))]or[e]

オンラインでお試しください!

この関数は、入力として単一の文字列を取り、可能な結果のリストを返します。

非ゴルフ

def get_all_eval_results(expr, operators={*"+-*/"}):
    results = []
    for operator in operators:
        remaining_operators = operators - {operator}

        # Split expression with the current operator and recursively evaluate each subexpression with remaining operators
        sub_expr_results = (get_all_eval_results(sub_expr, remaining_operators) for sub_expr in expr.split(operator))

        for result_group in zip(*sub_expr_results):   # Iterate over each group of subexpression evaluation outcomes
            expr_to_eval = operator.join(result_group)  # Join subexpression outcomes with current operator
            results.append(str(eval(expr_to_eval)))   # Evaluate and append outcome to result list of expr
    return results or [expr]  # If results is empty (no operators), return [expr]

オンラインでお試しください!


1

ゼリー、30バイト

œṡ⁹¹jṪḢƭ€jŒVɗßʋFL’$?
Ḋm2QŒ!烀

オンラインでお試しください!

リンクのペア。2つ目はメインリンクであり、引数として演算子として散在する浮動小数点数/整数のJellyリストを引数として取ります。これは、コマンドライン引数を指定した完全なプログラムとして実行された場合にJellyが入力を受け取る方法のフラットバージョンです。リンクの戻り値は、単一メンバーリストのリストのリストです。各リストは、式の可能な値です。

説明

ヘルパーリンク

浮動小数点数/整数のリストを、左引数として(文字として)演算子と、右引数として文字として演算子と交互に使用します。関連する演算子で区切られた数値を評価した後、左から右に入力リストを返します。

œṡ⁹                  | Split once by the right argument (the operator currently being processed)
                   ? | If:
                  $  | - Following as a monad
                L    |   - Length
                 ’   |   - Decremented by 1
              ʋ      | Then, following as a dyad:
   ¹                 | - Identity function (used because of Jelly’s ordering of dyadic links at the start of a dyadic chain)
    j       ɗ        | - Join with the following as a dyad, using the original left and right arguments for this chain:
     ṪḢƭ€            |   - Tail of first item (popping from list) and head from second item (again popping from list); extracts the numbers that were either side of the operator, while removing them from the split list
         j           |   - Joined with the operator
          ŒV         |   - Evaluate as Python (rather than V because of Jelly’s handling of decimals with a leading zero)
            ß        | - Recursive call to this helper link (in case there are further of the same operator)
               F     | Else: Flatten

メインリンク

浮動小数点数/整数のリストを演算子と交互に(文字として)取得します

Ḋ         | Remove first item (which will be a number)
 m2       | Every 2nd item, starting with the first (i.e. the operators)
   Q      | Uniquify
    Œ!    | Permutations
      烀 | For each permuted list of operators, reduce using the helper link and with the input list as the starting point

1

パイソン2182の 172バイト

import re
def f(s,P=set('+-/*')):
 S=[eval(s)]
 for p in P:
	t=s
	while p+' 'in t:t=re.sub(r'[-\d.]+ \%s [-\d.]+'%p,lambda m:`eval(m.group())`,t,1)
	S+=f(t,P-{p})
 return S

オンラインでお試しください!

「暗黙的に型を解析する言語では、整数をフロートに置き換えることができます」に従って、フロートとしてフォーマットされた整数で入力を受け取ります。


1

Julia 1.2、88(82)バイト

f(t)=get(t,(),[f.([t[1:i-1];t[i+1](t[i],t[i+2]);t[i+3:end]] for i=1:2:length(t)-2)...;])
julia> f([2, +, 3, *, 4])
2-element Array{Int64,1}:
 20
 14

julia> f([18, /, 3, *, 2, -, 1])
6-element Array{Float64,1}:
 11.0
  6.0
  2.0
  3.6
  6.0
  6.0

数値と挿入関数のベクトルの形式でテープを取り、各関数呼び出しを評価し、結果の各テープを単一の数値が残るまで再帰的に渡します。残念ながら、get(t, (), ...)Julia 1.0では正常に動作しないため、新しいバージョンが必要です。

ネストされた配列の束が出力として受け入れられる場合、6バイトを保存できます。

f(t)=get(t,(),f.([t[1:i-1];t[i+1](t[i],t[i+2]);t[i+3:end]] for i=1:2:length(t)-2))

出力:

julia> f([18, /, 3, *, 2, -, 1])
3-element Array{Array{Array{Float64,1},1},1}:
 [[11.0], [6.0]]
 [[2.0], [3.6]] 
 [[6.0], [6.0]] 

0

Perl 5(-alp)、89バイト

my$x;map{$x.=$`.(eval$&.$1).$2.$"while/\d+[-+*\/](?=(\d+)(.*))/g}@F;$_=$x;/[-+*\/]/&&redo

TIO

または一意の値、99バイト

my%H;map{$H{$`.(eval$&.$1).$2}++while/\d+[-+*\/](?=(\d+)(.*))/g}@F;$_=join$",keys%H;/[-+*\/]/&&redo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.