Saya melihat BIDMAS Anda dan memberi Anda BADMIS

21

Saya melihat BIDMAS Anda dan memberi Anda BADMIS

Tantangan

Diberikan satu set angka dengan operator di antara mereka: "5 + 4 * 9/3 - 8", kembalikan semua hasil ekspresi yang mungkin untuk setiap permutasi dari urutan operasi dasar: [/, *, +, -].

Aturan

  • Celah standar dilarang
  • I / O
    • Input harus dipesan dengan operasi infiks, tetapi yang paling mudah (string atau array)
    • Anda tidak diharuskan mendukung operator unary (mis. "-3 * 8 / +2")
    • Integer dapat diganti dengan float untuk bahasa yang secara implisit menguraikan tipe (mis. 45 ⟶ 45.0)
    • Keluaran harus berupa semua hasil ekspresi yang mungkin, tanpa format atau urutan yang ditentukan
  • Semua input valid (mis. Tidak perlu berurusan dengan "7/3 + *"). Ini juga berarti bahwa Anda tidak perlu membagi dengan nol.
  • Semua operator asosiatif kiri sehingga "20/4/2" = "(20/4) / 2"
  • Ini adalah Code Golf sehingga jumlah byte yang paling sedikit menang

Test Cases (Dengan penjelasan)

  • "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

Test Cases (Tanpa penjelasan)

  • "45/8 + 19/45 * 3" = [6.891666666666667, 18.14166666666666666, 0,11111111111111113, 0,01234567901234568, 0,01234567901234568, 0,01234567901234568, 5.765740740740741]
  • "2 + 6 * 7 * 2 + 6/4" = [112 196 23 87.5]
Freddie R
sumber
2
Tapi tantangan pertama yang bagus.
Shaggy
Terkait erat
Arnauld
Kasing uji yang disarankan 2 - 3 + 4=>[-5, 3]
Jo King
Test case yang disarankan: 2*3-6+2-9/6*8+5/2-9 memberikan 24 hasil berbeda.
Arnauld

Jawaban:

3

C # (Visual C # Interactive Compiler) , 285 byte

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

Cobalah online!

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
  }
}
Perwujudan Ketidaktahuan
sumber
Saya telah memperbaikinya sehingga Anda tidak perlu menghilangkan duplikat karena itu bukan bagian mendasar dari masalah seperti yang ditunjukkan.
Freddie R
1
@Arnauld Diperbaiki dengan biaya 4 byte, itu karena algoritma permutasi saya agak salah
Perwujudan Ketidaktahuan
3

JavaScript (Node.js) , 132 byte

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

Cobalah online!

Ini memungkinkan duplikasi output.

JavaScript (Node.js) , 165 161 155 153 152 137 byte

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)

Cobalah online!

Mengambil string dengan spasi antara operator dan angka.

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
 )
Shieru Asakoto
sumber
@ JoKing Menerapkan perbaikan yang telah saya sebutkan sebelumnya, harus menampilkan [3, -5]sekarang.
Shieru Asakoto
2

Perl 6 , 92 90 88 byte

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

Cobalah online!

Mengambil string dengan spasi setelah operator apa pun dan mengembalikan serangkaian angka. Ini sebagian besar bekerja dengan mengganti semua instance darin op n dengan hasil yang dievaluasi untuk semua permutasi operator.

Penjelasan:

{                                                                                   }  # 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
Jo King
sumber
Anda dapat menghapus set, karena kondisi untuk menghilangkan duplikat telah dihapus. Kode yang bagus
Freddie R
2

Python 3 , 108 byte

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]

Cobalah online!

Fungsi mengambil string tunggal sebagai input dan mengembalikan daftar hasil yang mungkin.

Tidak disatukan

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]

Cobalah online!

Joel
sumber
1

Jelly , 30 byte

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

Cobalah online!

Sepasang tautan. Yang kedua adalah tautan utama, dan sebagai argumennya daftar Jelly float / integer diselingi dengan operator sebagai karakter. Ini adalah versi rata dari cara Jelly mengambil inputnya ketika dijalankan sebagai program lengkap dengan argumen baris perintah. Nilai balik tautan adalah daftar daftar daftar anggota tunggal, yang masing-masing merupakan nilai yang mungkin untuk ekspresi.

Penjelasan

Tautan pembantu

Membawa daftar float / integer bergantian dengan operator (sebagai karakter) sebagai argumen kiri dan operator sebagai karakter sebagai argumen kanannya; mengembalikan daftar input setelah mengevaluasi angka yang dipisahkan oleh operator terkait, bekerja dari kiri ke kanan.

œṡ⁹                  | 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

Tautan utama

Mengambil daftar float / integer bergantian dengan operator (sebagai karakter)

Ḋ         | 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
Nick Kennedy
sumber
1

Python 2 , 182 172 byte

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

Cobalah online!

Mengambil input dengan int yang diformat sebagai float, sesuai "Integer dapat diganti dengan float untuk bahasa yang secara implisit tipe parse".

Chas Brown
sumber
1

Julia 1.2 , 88 (82) byte

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

Membawa kaset dalam bentuk vektor angka dan fungsi infiks, mengevaluasi setiap panggilan fungsi tunggal dan secara rekursif melewati setiap kaset yang dihasilkan kembali ke dirinya sendiri sampai hanya satu nomor yang tersisa. Sayangnya,get(t, (), ...) tidak berfungsi dengan baik di Julia 1.0, sehingga diperlukan versi yang lebih baru.

Enam byte dapat disimpan, jika sekelompok array bersarang dapat diterima sebagai output:

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))

Keluaran:

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]] 
pengguna3263164
sumber
0

Perl 5 ( -alp), 89 byte

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

TIO

atau nilai unik, 99 byte

my%H;map{$H{$`.(eval$&.$1).$2}++while/\d+[-+*\/](?=(\d+)(.*))/g}@F;$_=join$",keys%H;/[-+*\/]/&&redo
Nahuel Fouilleul
sumber