Exponentiation à la multiplication à l'addition

17

La multiplication entre 2 entiers peut être réduite en une série d'addition comme ça

3 * 5 = 3 + 3 + 3 + 3 + 3 = 5 + 5 + 5

L'exponentiation (élevant a à la puissance b ) peut également être réduite en une série de multiplications:

5 ^ 3 = 5 * 5 * 5

Par conséquent, l'exponentiation peut être réduite en une série d'additions, en créant une expression de multiplication, puis en une série d'additions. Par exemple, 5 ^ 3(5 cubes) peut être réécrit en

5 ^ 3 = 5 * 5 * 5
      = (5 + 5 + 5 + 5 + 5) * 5
      = (5 + 5 + 5 + 5 + 5) + (5 + 5 + 5 + 5 + 5) + (5 + 5 + 5 + 5 + 5) + (5 + 5 + 5 + 5 + 5) + (5 + 5 + 5 + 5 + 5)
      = 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5

Votre tâche consiste, compte tenu des expressions additionnées consistant en l'exponentiation, la multiplication et l'addition, à la réduire à la plus courte série d'additions. L'expression "la plus courte" est définie comme l'expression avec le moins de +symboles, en utilisant toujours un seul des deux nombres dans l'expression d'origine. Par exemple, l'expression la plus courte de 10 * 2est 10 + 10.

Les nombres impliqués dans l'entrée seront tous des entiers positifs, et l'expression consistera uniquement en +(addition), *(multiplication) et ^(exponentiation), ainsi que des entiers et des crochets ( ()) pour indiquer la priorité.

La sortie doit être constituée +uniquement d' entiers positifs et de symboles. Vous ne devez pas sortir les étapes individuelles des réductions, juste la sortie finale. La sortie peut ne pas être composée de chiffres qui n'apparaissent pas dans l'entrée. Cependant, vous pouvez utiliser 3 symboles distincts au lieu de +*^, mais veuillez indiquer de quels symboles il s'agit.

Les espaces séparant les entrées et les sorties peuvent ou non être utilisés dans vos programmes, c'est-à-dire qu'ils 3 * 5peuvent être sortis en tant que 5 + 5 + 5ou 5+5+5.

Notez que dans la plupart des cas, l'ajout n'est pas réellement effectué. Le seul cas où l'addition doit être effectuée est lorsque vous avez quelque chose comme 5 ^ (1 + 2), auquel cas, l'addition est nécessaire pour continuer -> 5 ^ 3 -> 5 * 5 * 5 -> .... Voir le cas de test n ° 4.

Votre code n'a pas besoin de gérer les entrées qui arrivent à une expression ambiguë. Par exemple (2 + 2) * (4 + 1),. En raison des règles énoncées jusqu'à présent, l'objectif n'est pas de calculer la réponse, l'objectif est de simplifier les ajouts. Ainsi, le résultat pourrait être différent selon l'ordre dans lequel les expressions sont résolues ou commutées (quels ajouts simplifier, lesquels laisser?). Un autre exemple invalide: ((3 + 2) ^ 2) ^ 3 -> ((3 + 2) * (3 + 2)) ^ 3 -> ???.

C'est le donc le code le plus court gagne

Cas de test

Input => output

5 ^ 3 + 4 * 1 ^ 5 => 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 4
2 ^ 1 * 2 + 3 + 9 => 2 + 2 + 3 + 9
2 ^ 1 * (2 + 3) + 9 => 2 + 3 + 2 + 3 + 9
2 ^ (1 * (2 + 3)) + 9 => 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 9
10 + 3 * 2 + 33 ^ 2 => 10 + 3 + 3 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33
100 * 3 => 100 + 100 + 100
2 ^ 1 + 2 ^ 1 + 2 ^ 2 + 8 ^ 1 => 2 + 2 + 2 + 2 + 8
(1 + 2 + 5 * 8 + 2 ^ 4) * 2 => 1 + 2 + 8 + 8 + 8 + 8 + 8 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + 2 + 8 + 8 + 8 + 8 + 8 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2
caird coinheringaahing
la source
Pouvons-nous utiliser à la **place de ^?
Erik the Outgolfer
@EriktheOutgolfer oui, cela semble juste.
caird coinheringaahing
En relation.
Martin Ender
1
Je suis toujours confus quant à ce qui constitue une sortie valide. Dans la question que vous dites, using only one of the two numbers in the original expression.mais l'expression originale peut avoir plus de deux nombres. Je ne comprends pas pourquoi 8 + 8n'est pas une sortie valide pour 2 ^ 1 + 2 ^ 1 + 2 ^ 2 + 8 ^ 1. Cette question n'est toujours pas très claire pour moi.
Post Rock Garf Hunter

Réponses:

6

Rétine , 302 octets

Je suis sûr que cela peut être joué au golf, mais à ce stade, je suis juste content que cela fonctionne. Les sections d'exponentiation et de multiplication sont toutes deux très similaires, mais comme l'ordre des opérations est important, je ne sais pas comment les combiner.

y- Exponentiation
x- Multiplication
p- Addition

\d+
$*
{1`(\(\w+\)|1+)y(\(\w+\)|1+)
>$0<
(?<=>(\(\w+\)|1+)y1*)1
$1x
>(\(\w+\)|1+)y
(
x<
)
\((1+(x1+)*)\)(?!y)
$1
(?<!1)(1+)x(\(\w+\)|1+\1)(?!1)
$2x$1
1`(\(\w+\)|1+)x1+
>$0<
(?<=>(\(\w+\)|1+)x1*)1
$1p
>(\(\w+\)|1+)x
(
p<
)
(?<!x|y)\((1+(p1+)*)\)(?!x|y)
$1
y\((1+)p([1p]*\))
y($1$2
}`y\((1+)\)
y$1
1+
$.0

Essayez-le en ligne - tous les cas de test

Convertisseur de cas de test

Explication

\d+                             Convert to unary
$*
{1`(\(\w+\)|1+)y(\(\w+\)|1+)    Begin loop: Delimit current exponentiation group
>$0<
(?<=>(\(\w+\)|1+)y1*)1          Replace exponentiation with multiplication
$1x
>(\(\w+\)|1+)y                  Replace garbage with parentheses
(
x<
)
\((1+(x1+)*)\)(?!y)             Remove unnecessary parentheses around multiplication
$1
(?<!1)(1+)x(\(\w+\)|1+\1)(?!1)  Maybe swap order of multiplicands
$2x$1
1`(\(\w+\)|1+)x1+               Delimit current multiplication group
>$0<
(?<=>(\(\w+\)|1+)x1*)1          Replace multiplication with addition
$1p
>(\(\w+\)|1+)x                  Replace garbage with parentheses
(
p<
)
(?<!x|y)\((1+(p1+)*)\)(?!x|y)   Remove unnecessary parentheses around addition
$1
y\((1+)p([1p]*\))               Handle the 4th test case by adding if necessary
y($1$2
}`y\((1+)\)                     End of loop
y$1
1+                              Convert unary back to decimal
$.0

Vous pouvez également remarquer que le groupe le plus utilisé est (\(\w+\)|1+). Cela correspond à une expression interne avec des parenthèses ou un entier. J'ai choisi d'utiliser les symboles que j'ai faits pour pouvoir utiliser \wplutôt qu'une classe de caractères. Je ne sais pas s'il serait préférable d'utiliser des symboles autres que des mots et de remplacer certains contournements par des bordures de mots ( \b).

mbomb007
la source
5

Mathematica, 250 218 183 170 octets

f~(s=SetAttributes)~HoldAll;{a,t}~s~Flat;f@n_:=Infix[Hold@n//.{a_~Power~b_:>t@@Hold@a~Table~b,Times->t,Plus->a,Hold->Dot}/.t->(a@@Table[#,1##2]&@@Reverse@Sort@{##}&),"+"]

Ça marche! Finalement!

Définit la fonction dans f.

L'entrée est une expression mathématique simple. (c'est-à-dire 1 + 2non "1 + 2").

Essayez-le en ligne!

Notez que le lien TIO a un code légèrement différent, comme TIO (qui, je suppose, utilise le noyau Mathematica) n'aime pas Infix. J'ai utilisé à la Riffleplace pour obtenir la même apparence que Mathematica REPL.

Non golfé

f~(s = SetAttributes)~HoldAll;  (* make f not evaluate its inputs *)

{a, t}~s~Flat;  (* make a and t flat, so that a[a[1,a[3]]] == a[1,3] *)

f@n_ :=  (* define f, input n *)

 Infix[

  Hold@n  (* hold the evaluation of n for replacement *)

    //. {  (* expand exponents *)

     (* change a^b to t[a,a,...,a] (with b a's) *)
     a_~Power~b_ :> t @@ Hold@a~Table~b,

     (* Replace Times and Plus with t and a, respectively *)
     Times -> t, 
     Plus -> a, 

     (* Replace the Hold function with the identity, since we don't need
         to hold anymore (Times and Plus are replaced) *)
     Hold -> Dot 

     } /.  (* Replace; expand all t (= `Times`) to a (= `Plus`) *)

        (* Take an expression wrapped in t. *)
        (* First, sort the arguments in reverse. This puts the term
            wrapped in `a` (if none, the largest number) in the front *)
        (* Next, repeat the term found above by <product of rest
            of the arguments> times *)
        (* Finally, wrap the entire thing in `a` *)
        (* This will throw errors when there are multiple elements wrapped
           in `a` (i.e. multiplying two parenthesized elements) *)
        t -> (a @@ Table[#, 1 ##2] & @@
               Reverse@Sort@{##} &),

  "+"]  (* place "+" between each term *)
JungHwan Min
la source
6
Ok, je suis heureux d'avoir créé un défi pour lequel Mathematica n'a pas intégré: P
caird coinheringaahing
3

Mathematica, 405 406 octets

f~SetAttributes~HoldAll;p=(v=Inactive)@Plus;t=v@Times;w=v@Power;f@x_:=First@MinimalBy[Inactivate@{x}//.{w[a___,b_List,c___]:>(w[a,#,c]&/@b),t[a___,b_List,c___]:>(t[a,#,c]&/@b),p[a___,b_List,c___]:>(p[a,#,c]&/@b),p[a_]:>a,w[a_,b_]:>t@@Table[a,{Activate@b}],t[a___,t[b__],c___]:>t[a,b,c],p[a___,p[b__],c___]:>p[a,b,c],{a___,{b__},c___}:>{a,b,c},t[a__]:>Table[p@@Table[i,{Activate[t@a/i]}],{i,{a}}]},Length];f

Non golfé et expliqué

SetAttributes[f, HoldAll]
p = Inactive[Plus]; t = Inactive[Times]; w = Inactive[Power];
f[x_] := First@MinimalBy[
   Inactivate[{x}] //. {
     w[a___, b_List, c___] :> (w[a, #, c] & /@ b),
     t[a___, b_List, c___] :> (t[a, #, c] & /@ b),
     p[a___, b_List, c___] :> (p[a, #, c] & /@ b),
     (* distribute lists of potential expansions over all operations *)
     p[a_] :> a,
     (* addition of a single term is just that term *)
     w[a_, b_] :> t @@ Table[a, {Activate@b}],
     (* a^b simplifies to a*a*...*a b times no matter what b is *)
     t[a___, t[b__], c___] :> t[a, b, c],
     p[a___, p[b__], c___] :> p[a, b, c],
     {a___, {b__}, c___} :> {a, b, c},
     (* operations are associative *)
     t[a__] :> Table[p @@ Table[i, {Activate[t@a/i]}], {i, {a}}]
     (* for a product, generate a list of potential expansions *)}
   , Length]
f

Je suis allé à beaucoup de mal pour obtenir l'effet suivant: cette fonction prend en entrée une expression standard Mathematica, avec l'habitude +, *et les ^opérations (et entre parenthèses) en elle, et les sorties ce qui ressemble à une expression classique Mathematica (mais avec "désactivé" plus signes) comme réponse.

La fonction ci-dessus commence par désactiver toutes les opérations dans l'entrée. Ensuite, il applique les règles d'extension à plusieurs reprises jusqu'à ce que rien ne puisse plus être simplifié. Chaque fois qu'il rencontre un produit tel que 2 * 3 * 4, qui peut être étendu de plusieurs façons, il fait une liste des extensions possibles et continue. À la fin, nous obtenons une liste de réponses finales possibles, et la plus courte est choisie.

Misha Lavrov
la source