Toplama ile çarpmanın üslenmesi


17

2 tamsayı arasındaki çarpma, bu şekilde bir dizi ilaca indirgenebilir

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

Üs (yükselterek bir güç için b da çarpma bir dizi halinde azaltılabilir):

5 ^ 3 = 5 * 5 * 5

Bu nedenle, üs alma işlemi, bir çarpma ifadesi yaratılarak, daha sonra bir dizi ilaveler haline getirilerek bir dizi ilavelere indirgenebilir. Örneğin, 5 ^ 3(5 küp) şu şekilde yeniden yazılabilir:

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

Senin görevin, üs, çarpma ve toplamadan oluşan ifadeler bir araya getirildiğinde, onu en kısa eklemeler serisine indirgemek. "En kısa" ifade, +orijinal ifadedeki iki sayıdan yalnızca birini kullanan , en az sayıda simgeye sahip ifade olarak tanımlanır . Örneğin, kısa sentezleme 10 * 2olup 10 + 10.

Girdide yer alan sayıların tümü pozitif tamsayılar olacaktır ve ifade, önceliği belirtmek için tamsayılar ve köşeli parantezler ( ) ile birlikte yalnızca +(toplama), *(çarpma) ve ^(üs alma) 'dan oluşacaktır ().

Çıktı +yalnızca pozitif tamsayılardan ve sembollerden oluşmalıdır . İndirimlerin bireysel adımlarını değil, yalnızca nihai çıktıyı çıkarmalısınız. Çıkış, girişte görünmeyen hiçbir sayıdan oluşmayabilir. Ancak, bunun yerine 3 farklı simge kullanabilirsiniz +*^, ancak lütfen hangi sembollerin olduğunu söyleyin

Girdileri ve çıktıları ayıran boşluklar programlarınızda kullanılabilir ya da kullanılmayabilir, yani 3 * 5ya 5 + 5 + 5ya çıktı olarak alınabilir 5+5+5.

Çoğu durumda, toplama işleminin gerçekten yapılmadığını unutmayın. Toplamanın gerçekleştirileceği tek durum, böyle bir şeye sahip olduğunuz zamandır 5 ^ (1 + 2), bu durumda toplamaya devam etmek gerekir -> 5 ^ 3 -> 5 * 5 * 5 -> .... Bkz. Test örneği # 4.

Kodunuzun belirsiz bir ifadeye ulaşan girdileri işlemesi gerekmez. Örneğin (2 + 2) * (4 + 1),. Şimdiye kadar ortaya konan kurallar nedeniyle, amaç cevabı hesaplamak değil, amaç eklemeler için basitleştirmektir. Dolayısıyla, ifadelerin çözülme veya değiştirilme sırasına bağlı olarak sonuç farklı olabilir (basitleştirmek için hangi eklemeler, hangileri bırakılacak?). Başka geçersiz örnek: ((3 + 2) ^ 2) ^ 3 -> ((3 + 2) * (3 + 2)) ^ 3 -> ???.

Bu bu yüzden en kısa kod kazanır

Test senaryoları

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

**Bunun yerine kullanabilir miyiz ^?
Outgolfer Erik

@EriktheOutgolfer evet, bu adil görünüyor.
caird coinheringaahing


1
Hala geçerli çıktıyı neyin oluşturduğuna dair kafam karıştı. Söylediğiniz soruda, using only one of the two numbers in the original expression.ancak orijinal ifadede ikiden fazla sayı olabilir. Neden 8 + 8geçerli bir çıktı değil anlamıyorum 2 ^ 1 + 2 ^ 1 + 2 ^ 2 + 8 ^ 1. Bu soru benim için hala belirsiz.
Rock Garf Hunter Post

Yanıtlar:


6

Retina , 302 bayt

Eminim bu golf olabilir, ama bu noktada, işe yaradığı için memnunum. Üstel ve çarpma bölümlerinin her ikisi de çok benzer, ancak işlem sırası önemli olduğundan, bunları nasıl birleştireceğimizi bilmiyorum.

y- Üs
x- Çarpma
p- Toplama

\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

Çevrimiçi deneyin - tüm test örnekleri

Test çantası dönüştürücü

açıklama

\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

Ayrıca en sık kullanılan grubun olduğunu fark edebilirsiniz (\(\w+\)|1+). Bu, iç ifadeyi parantez veya bir tamsayı ile eşleştirir. \wKarakter sınıfından ziyade kullanabileceğim sembolleri kullanmayı seçtim . Kelime olmayan semboller kullanmak ve bazı kenarlıkları kelime kenarlıkları ( \b) ile değiştirmek daha iyi olur emin değilim .


5

Mathematica 250 218 183 170 bayt

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

İşe yarıyor! En sonunda!

İçindeki işlevi tanımlar f .

Giriş düz bir matematik ifadesidir. (yani 1 + 2değil"1 + 2" ).

Çevrimiçi deneyin!

TIO bağlantısının biraz farklı bir kodu olduğunu unutmayın, çünkü TIO (sanırım Mathematica çekirdeğini kullanır) beğenmez Infix. kullandımRiffle yerine Mathematica REPL ile aynı görünümü elde .

Ungolfed

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
Tamam, Mathematica'nın yerleşik olmadığı bir zorluk yarattığım için mutluyum: P
caird coinheringaahing

3

Mathematica, 405 406 bayt

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

Açık ve açık

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

Bu fonksiyon her zamanki ile, girdi olarak standart bir Mathematica ifade alır: Aşağıdaki etkiyi elde etmek sorun büyük anlaşma gitti +, *ve ^operasyonlar (ve parantez) içinde ve çıkışlar ne standart Mathematica ifadesi gibi görünüyor (ama ile "devre dışı bırakıldı" artı işaretleri).

Yukarıdaki fonksiyon, girişteki tüm işlemleri devre dışı bırakarak başlar. Ardından, artık hiçbir şey basitleştirilinceye kadar genişletme kurallarını tekrar tekrar uygular. 2 * 3 * 4Birden fazla şekilde genişletilebilen gibi bir ürünle karşılaştığında , olası genişletmelerin bir listesini yapar ve devam eder. Sonunda, olası nihai cevapların bir listesini alırız ve en kısa olanı seçilir.

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.