BIDMAS'ınızı görüyorum ve sizi bir BADMİS yükseltiyorum


21

BIDMAS'ınızı görüyorum ve sizi bir BADMİS yükseltiyorum

Meydan okuma

Aralarında operatörleri olan bir sayı kümesi göz önüne alındığında: "5 + 4 * 9/3 - 8", temel işlemlerin sırasındaki her permütasyon için ifadenin olası tüm sonuçlarını döndürür: [/, *, +, -].

kurallar

  • Standart boşluklar yasaktır
  • I / O
    • Giriş, infix işlemleriyle birlikte sipariş edilmelidir, ancak bu en kolay olanıdır (string veya array)
    • Tekli operatörleri desteklemeniz gerekmez (örn. "-3 * 8 / +2")
    • Tamsayılar, dolaylı olarak ayrıştırma yapan diller için float'lar ile değiştirilebilir (ör. 45) 45.0)
    • Çıktı, ifadenin olası sonuçlarının tümü olmalı, belirtilen biçim veya düzen olmamalıdır
  • Tüm girdiler geçerlidir (örneğin "7/3 + *" ile uğraşmanıza gerek yoktur). Bu aynı zamanda asla sıfıra bölmek zorunda kalmayacağınız anlamına gelir.
  • Operatörlerin tümü sola dayalıdır, yani "20/4/2" = "(20/4) / 2"
  • Bu Code Golf yani en az bayt sayısı kazanıyor

Test Kılıfları (Açıklamalı)

  • "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) 5 (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 Durumları (açıklama olmadan)

  • "45/8 + 19/45 * 3" = [6.891666666666667, 18.141666666666666, 0.1111111111111111113, 0.01234567901234568, 0.01234567901234568, 5.765740740740741]
  • "2 + 6 * 7 * 2 + 6/4" = [112 196 23 87,5]

2
Güzel ilk meydan okuma olsa da, bu arada.
Shaggy,


Önerilen test durumu 2 - 3 + 4=>[-5, 3]
Jo King

Önerilen test durumu: 2*3-6+2-9/6*8+5/2-924 farklı sonuç verir.
Arnauld

Yanıtlar:



3

C # (Visual C # Etkileşimli Derleyici) , 285 bayt

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

Çevrimiçi deneyin!

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

Bunu düzelttim, böylece belirtildiği gibi sorunun temel bir parçası olmadığı için kopyaları atlamanıza gerek yok.
Freddie R

1
@Arnauld 4 bayt pahasına giderildi, çünkü permütasyon algoritmam biraz yanlıştı
Ignorance'ın uygulaması

3

JavaScript (Node.js) , 132 bayt

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

Çevrimiçi deneyin!

Bu, çoğaltılmış çıktılara izin verir.

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

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)

Çevrimiçi deneyin!

İşleçler ve sayılar arasında boşluk bulunan bir dize alır.

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 Daha önce belirttiğim düzeltmeyi uyguladı, [3, -5]şimdi çıkmalı .
Shieru Asakoto

2

Perl 6 , 92 90 88 bayt

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

Çevrimiçi deneyin!

Herhangi bir operatörden sonra boşluğu olan bir dize alır ve bir sayı kümesi döndürür. Bu çoğunlukla n op n, operatörlerin tüm izinleri için değerlendirilen sonucun tüm örneklerini değiştirerek çalışır .

Açıklama:

{                                                                                   }  # 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

setYinelenenleri kaldırma koşulu kaldırıldığı için , kaldırabilirsiniz . Güzel kod.
Freddie R

2

Python 3 , 108 bayt

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]

Çevrimiçi deneyin!

İşlev giriş olarak tek bir dize alır ve olası sonuçların bir listesini döndürür.

Ungolfed

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]

Çevrimiçi deneyin!


1

Jöle , 30 bayt

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

Çevrimiçi deneyin!

Bir çift bağlantı. İkincisi ana bağlantıdır ve argümanı olarak, işleçlerle karakter olarak serpiştirilmiş yüzerlerin / tam sayıların bir Jelly listesidir. Bu, Jelly'in girişini komut satırı argümanlarına sahip tam bir program olarak çalıştırıldığında girdi aldığı düzleştirilmiş bir versiyonudur. Bağlantının dönüş değeri, her biri ifade için olası bir değer olan tek üye listelerinin bir listesidir.

açıklama

Yardımcı bağlantı

Operatörlerle (karakter olarak) sol argümanı olarak değişen bir değişken / tam sayı listesi ve sağ argüman olarak bir karakter olarak işleci; Soldan sağa çalışan, ilgili operatör tarafından ayrılan sayıları değerlendirdikten sonra giriş listesini döndürür.

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

Ana link

İşleçlerle değişen değişkenlerin / tam sayıların listesini alır (karakter olarak)

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

Python 2 , 182 172 bayt

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

Çevrimiçi deneyin!

"Satırlar dolaylı olarak ayrıştırılan diller için satırlar ile değiştirilebilir" ifadesine göre yüzer olarak biçimlendirilmiş girdilerle girdi alır.


1

Julia 1.2 , 88 (82) bayt

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

Bir sayı vektörü ve bir ek fonksiyonu gibi bir bant alır, her bir işlev çağrısını değerlendirir ve sonuçta elde edilen her bir bantı sadece tek bir sayı kalana kadar tekrar eder. Ne yazık ki, get(t, (), ...)Julia 1.0'da düzgün çalışmıyor, bu nedenle daha yeni bir sürüm gerekir.

Bir demet iç içe dizi bir çıktı olarak kabul edilebilirse, altı bayt kaydedilebilir:

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

Çıktı:

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 bayt

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

TIO

veya benzersiz değerler, 99 bayt

my%H;map{$H{$`.(eval$&.$1).$2}++while/\d+[-+*\/](?=(\d+)(.*))/g}@F;$_=join$",keys%H;/[-+*\/]/&&redo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.