乗算から加算への累乗


17

2つの整数間の乗算は、次のように一連の加算に減らすことができます。

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

べき乗(上昇電力にbが)また、乗算のシリーズに低減することができます。

5 ^ 3 = 5 * 5 * 5

したがって、乗算式を作成することにより、べき乗を一連の加算に減らしてから、一連の加算に減らすことができます。たとえば、5 ^ 3(5立方体)は次のように書き換えることができます。

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

あなたのタスクは、累乗、乗算、加算で構成される式が加算されると、それを最短の加算系列に減らします。「最短」式は、+シンボルの数が最も少ない式として定義されますが、元の式の2つの数字のうち1つだけを使用します。たとえば、の最短表現は10 * 2です10 + 10

入力に含まれる数値はすべて正の整数であり、式は整数と大括弧(+)に加えて、*(加算)、(乗算)、および^(指数)のみで構成されます(())が優先順位を示します。

出力は、正の整数と+記号のみで構成される必要があります。削減の個々のステップを出力するのではなく、最終出力のみを出力する必要があります。出力は、入力に表示されない数字で構成することはできません。ただし、の代わりに3つの異なる記号を使用できますが、+*^それらの記号は何かを言ってください

入力と出力を区切るスペースは、プログラムで使用される場合と使用されない場合があります。つまり3 * 55 + 5 + 5またはとして出力できます5+5+5

ほとんどの場合、追加は実際には実行されないことに注意してください。加算が実行されるのは、のようなものがある場合のみです。5 ^ (1 + 2)その場合、続行するには加算が必要です-> 5 ^ 3 -> 5 * 5 * 5 -> ...です。です。テストケース#4を参照してください。

コードは、あいまいな式に到達する入力を処理する必要はありません。たとえば、(2 + 2) * (4 + 1)。これまでに説明した規則のため、目標は答えを計算することではなく、追加に単純化することです。そのため、結果は、式が解決または変換される順序に応じて異なる可能性があります(どの追加を単純化するか、どれを残すか)。別の無効な例:((3 + 2) ^ 2) ^ 3 -> ((3 + 2) * (3 + 2)) ^ 3 -> ???

これはので、最短コードが勝ちます

テストケース

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

**代わりに使用でき^ますか?
エリックアウトゴルファー

@EriktheOutgolferええ、それは公平なようです。
caird coinheringaahing


1
何が有効な出力を構成するのかについて、私はまだ混乱しています。あなたが言う質問ではusing only one of the two numbers in the original expression.、元の式は3つ以上の数字を持つことができます。の8 + 8有効な出力ではない理由がわかりません2 ^ 1 + 2 ^ 1 + 2 ^ 2 + 8 ^ 1。この質問は私にはまだかなり明確ではありません。
ポストロックガーフハンター

回答:


6

網膜、302バイト

私はこれがゴルフできると確信していますが、この時点で、私はそれがうまくいって嬉しいです。べき乗と乗算の両方のセクションは非常に似ていますが、演算の順序が重要であるため、それらを結合する方法がわかりません。

y-べき乗
x-乗算
p-加算

\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

オンラインで試す -すべてのテストケース

テストケースコンバーター

説明

\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

また、最も一般的に使用されるグループがであることに気付くかもしれません(\(\w+\)|1+)。これは、括弧または整数を持つ内部式と一致します。\w文字クラスではなく使用できるように、使用したシンボルを使用することにしました。単語以外のシンボルを使用し、一部の見回しを単語の境界(\b)に置き換える方が良いかどうかはわかりません。


5

Mathematica、250 218 183 170バイト

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@{##}&),"+"]

できます!最後に!

関数を定義します f

入力は単純な数式です。(つまり1 + 2ない"1 + 2")。

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

TIO(私はMathematicaカーネルを使用していると思われます)が気に入らないので、TIOリンクはわずかに異なるコードを持っていることに注意してくださいInfix。私は使ったRiffle代わりにMathematica REPLと同じ外観を得るためました。

非ゴルフ

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

6
OK、Mathematicaに組み込まれていない課題を作成したことを嬉しく思います:P
共犯

3

Mathematica、405 406バイト

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

非ゴルフと説明

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

この機能は、通常で、入力としての標準的なMathematicaの式を取ります。私は、次のような効果を得るために、トラブルの多大に行き+*、および^それに操作(括弧)、そしてどのようなルックスの標準的なMathematicaの式(しかし、とのような出力回答として「非アクティブ化」プラス記号)。

上記の機能は、入力のすべての操作を非アクティブ化することから始まります。その後、単純化できるものがなくなるまで、展開ルールを繰り返し適用します。2 * 3 * 4複数の方法で展開できるなどの製品に遭遇するたびに、可能な展開のリストを作成し、継続します。最後に、可能な最終回答のリストを取得し、最も短いものを選択します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.