การยกกำลังเพื่อการคูณเพื่อการบวก


17

การคูณระหว่างจำนวนเต็ม 2 ตัวสามารถลดลงเป็นชุดการบวกได้

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

การยกกำลัง (ยกกำลังaไปยังพลังงานb ) สามารถลดลงเป็นชุดของการคูณ:

5 ^ 3 = 5 * 5 * 5

ดังนั้นการยกกำลังจะลดลงเป็นชุดของการเพิ่มเติมโดยการสร้างการแสดงออกคูณจากนั้นเป็นชุดของการเพิ่ม ตัวอย่างเช่น5 ^ 3(5 cubed) สามารถเขียนใหม่เป็น

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

งานของคุณคือให้นิพจน์ที่รวมเข้าด้วยกันประกอบด้วยการยกกำลังการคูณและการเพิ่มลดให้เป็นชุดการย่อที่สั้นที่สุด นิพจน์ "shortest" ถูกกำหนดเป็นนิพจน์ที่มีจำนวน+สัญลักษณ์น้อยที่สุดโดยยังคงใช้เพียงหนึ่งในสองหมายเลขในนิพจน์ดั้งเดิม ยกตัวอย่างเช่นการแสดงออกที่สั้นที่สุดของคือ10 * 210 + 10

ตัวเลขที่เกี่ยวข้องในการป้อนข้อมูลทั้งหมดจะเป็นจำนวนเต็มบวกและนิพจน์จะประกอบด้วยเฉพาะ+(เพิ่มเติม), *(การคูณ) และ^(การยกกำลัง) พร้อมด้วยจำนวนเต็มและวงเล็บ ( ()) เพื่อระบุความสำคัญ

ผลลัพธ์ควรประกอบด้วยจำนวนเต็มและ+สัญลักษณ์บวกเท่านั้น คุณไม่ควรส่งออกแต่ละขั้นตอนของการลดเพียงผลลัพธ์สุดท้าย ผลลัพธ์อาจไม่ประกอบด้วยตัวเลขใด ๆ ที่ไม่ปรากฏในอินพุต อย่างไรก็ตามคุณสามารถใช้สัญลักษณ์ที่แตกต่างกัน 3 แบบแทน+*^แต่โปรดพูดว่าเป็นสัญลักษณ์ใด

ช่องว่างแยกปัจจัยการผลิตและผลอาจจะหรืออาจจะไม่ได้ถูกนำมาใช้ในโปรแกรมของคุณคือ3 * 5สามารถออกมาเป็นอย่างใดอย่างหนึ่งหรือ5 + 5 + 55+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

เราขอใช้**แทนได้^ไหม
Erik the Outgolfer

@EriktheOutgolfer ใช่ที่ดูเหมือนยุติธรรม
caird coinheringaahing


1
ฉันยังคงสับสนกับสิ่งที่ถือว่าเป็นผลลัพธ์ที่ถูกต้อง ในคำถามที่คุณพูดusing only one of the two numbers in the original expression.แต่การแสดงออกดั้งเดิมสามารถมีได้มากกว่าสองตัวเลข ฉันไม่ได้รับเหตุผลที่ไม่ได้เป็นที่ถูกต้องสำหรับการส่งออก8 + 8 2 ^ 1 + 2 ^ 1 + 2 ^ 2 + 8 ^ 1คำถามนี้ยังไม่ชัดเจนสำหรับฉัน
โพสต์ Rock Garf Hunter

คำตอบ:


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มากกว่าคลาสตัวละคร ฉันไม่แน่ใจว่าจะเป็นการดีกว่าถ้าใช้สัญลักษณ์ที่ไม่ใช่คำและแทนที่ lookarounds บางส่วนด้วยเส้นขอบคำ ( \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 มีรหัสที่แตกต่างกันเล็กน้อยเป็น TIO (ซึ่งผมเข้าใจใช้ Mathematica เคอร์เนล) Infixไม่ชอบ ฉันใช้Riffleแทนเพื่อให้ได้ลักษณะเดียวกันกับ Mathematica REPL

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
ตกลงฉันมีความสุขฉันได้สร้างความท้าทายที่ Mathematica ไม่มีในตัวสำหรับ: P
caird coinheringaahing

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

Ungolfed และอธิบาย

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

ผมไปจัดการที่ดีของปัญหาที่จะได้รับผลกระทบต่อไปนี้: ฟังก์ชั่นนี้จะใช้เวลาเป็น input แสดงออก Mathematica มาตรฐานกับปกติ+, *และ^การดำเนินงาน (และวงเล็บ) ในนั้นและเอาท์พุทสิ่งที่ดูเหมือนว่าการแสดงออก Mathematica มาตรฐาน ( แต่มี "ปิดการใช้งาน" และเครื่องหมายบวก) เป็นคำตอบ

ฟังก์ชั่นด้านบนเริ่มต้นด้วยการปิดการทำงานทั้งหมดในอินพุต จากนั้นจะใช้กฎการขยายตัวซ้ำ ๆ จนกว่าจะไม่มีสิ่งใดมาทำให้ง่ายขึ้นอีกต่อไป เมื่อใดก็ตามที่พบผลิตภัณฑ์เช่น2 * 3 * 4ซึ่งสามารถขยายได้หลายวิธีมันจะทำให้รายการของการขยายตัวที่เป็นไปได้และยังคงดำเนินต่อไป ในตอนท้ายเราจะได้รับรายการคำตอบสุดท้ายที่เป็นไปได้และเลือกสั้นที่สุด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.