Je vois votre BIDMAS et vous élève un BADMIS


21

Je vois votre BIDMAS et vous élève un BADMIS

Défi

Etant donné un ensemble de nombres avec des opérateurs entre eux: "5 + 4 * 9/3 - 8", retourne tous les résultats possibles de l'expression pour chaque permutation de l'ordre des opérations de base: [/, *, +, -].

Règles

  • Failles standard interdites
  • E / S
    • L'entrée doit être ordonnée avec des opérations d'infixe, mais cependant c'est plus simple (chaîne ou tableau)
    • Vous n'êtes pas tenu de prendre en charge les opérateurs unaires (par exemple, "-3 * 8 / +2")
    • Les entiers peuvent être remplacés par des flottants pour les langues qui analysent implicitement le type (par exemple 45 ⟶ 45.0)
    • La sortie doit être tous les résultats possibles de l'expression, aucun format ni ordre spécifié
  • Toutes les entrées sont valides (par exemple n'ont pas besoin de traiter avec "7/3 + *"). Cela signifie également que vous n'aurez jamais besoin de diviser par zéro.
  • Les opérateurs sont tous associatifs à gauche, donc "20/4/2" = "(20/4) / 2"
  • C'est Code Golf, donc le moins d'octets gagne

Cas de test (avec explication)

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

Cas de test (sans explication)

  • "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
Bon premier défi cependant.
Shaggy


Cas de test suggéré 2 - 3 + 4=>[-5, 3]
Jo King

Cas de test suggéré:, 2*3-6+2-9/6*8+5/2-9donnant 24 résultats distincts.
Arnauld

Réponses:



3

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

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

Essayez-le en ligne!

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

Je l'ai corrigé afin que vous n'ayez pas besoin d'omettre les doublons car ce n'est pas une partie fondamentale du problème comme indiqué.
Freddie R

1
@Arnauld Fixé au coût de 4 octets, c'était parce que mon algorithme de permutations était un peu faux
Incarnation de l'ignorance

3

JavaScript (Node.js) , 132 octets

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

Essayez-le en ligne!

Cela permet des sorties dupliquées.

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

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)

Essayez-le en ligne!

Prend une chaîne avec des espaces entre les opérateurs et les nombres.

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 Implémentation du correctif que j'ai indiqué précédemment, devrait sortir [3, -5]maintenant.
Shieru Asakoto

2

Perl 6 , 92 90 88 octets

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

Essayez-le en ligne!

Prend une chaîne avec un espace après tout opérateur et renvoie un ensemble de nombres. Cela fonctionne principalement en substituant toutes les instances de n op navec le résultat évalué à toutes les permutations des opérateurs.

Explication:

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

Vous pouvez supprimer le set, car la condition pour éliminer les doublons a été supprimée. Beau code.
Freddie R

2

Python 3 , 108 octets

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]

Essayez-le en ligne!

La fonction prend une seule chaîne en entrée et renvoie une liste de résultats possibles.

Non golfé

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]

Essayez-le en ligne!


1

Gelée , 30 octets

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

Essayez-le en ligne!

Une paire de liens. Le second est le lien principal, et prend comme argument une liste Jelly de flottants / entiers entrecoupés avec les opérateurs comme caractères. Il s'agit d'une version aplatie de la façon dont Jelly prend son entrée lorsqu'il est exécuté en tant que programme complet avec des arguments de ligne de commande. La valeur de retour du lien est une liste de listes de listes de membres uniques, chacune étant une valeur possible pour l'expression.

Explication

Lien d'aide

Prend une liste de flottants / entiers alternant avec des opérateurs (sous forme de caractères) comme argument de gauche et un opérateur sous forme de caractère comme argument de droite; renvoie la liste d'entrée après avoir évalué les nombres séparés par l'opérateur approprié, en travaillant de gauche à droite.

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

Lien principal

Prend une liste de flottants / entiers alternant avec des opérateurs (sous forme de caractères)

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

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

Essayez-le en ligne!

Prend l'entrée avec des nombres entiers formatés comme des flottants, selon "Les nombres entiers peuvent être remplacés par des flottants pour les langues qui analysent implicitement le type".


1

Julia 1.2 , 88 (82) octets

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

Prend une bande sous la forme d'un vecteur de nombres et de fonctions d'infixe, évalue chaque appel de fonction unique et passe récursivement chaque bande résultante à elle-même jusqu'à ce qu'il ne reste qu'un seul numéro. Malheureusement,get(t, (), ...) ne fonctionne pas correctement dans Julia 1.0, une nouvelle version est donc nécessaire.

Six octets peuvent être enregistrés, si un groupe de tableaux imbriqués est acceptable en sortie:

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

Sortie:

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 octets

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

TIO

ou valeurs uniques, 99 octets

my%H;map{$H{$`.(eval$&.$1).$2}++while/\d+[-+*\/](?=(\d+)(.*))/g}@F;$_=join$",keys%H;/[-+*\/]/&&redo
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.