Eksponen ke multiplikasi ke penjumlahan

17

Perkalian antara 2 bilangan bulat dapat direduksi menjadi serangkaian tambahan seperti itu

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

Eksponensial (menaikkan a ke daya b ) juga dapat dikurangi menjadi serangkaian perkalian:

5 ^ 3 = 5 * 5 * 5

Oleh karena itu, eksponensial dapat direduksi menjadi serangkaian penambahan, dengan membuat ekspresi multiplikasi, kemudian menjadi serangkaian penambahan. Misalnya, 5 ^ 3(5 potong dadu) dapat ditulis ulang sebagai

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

Tugas Anda adalah, mengingat ekspresi yang ditambahkan bersama-sama yang terdiri dari eksponensial, perkalian, dan penambahan, kurangi menjadi serangkaian penambahan terpendek. Ekspresi "terpendek" didefinisikan sebagai ekspresi dengan jumlah +simbol paling sedikit , masih menggunakan hanya satu dari dua angka dalam ekspresi asli. Misalnya, ekspresi terpendek 10 * 2adalah 10 + 10.

Angka-angka yang terlibat dalam input semuanya akan bilangan bulat positif, dan ekspresi hanya terdiri dari +(penambahan), *(perkalian) dan ^(eksponensial), bersama dengan bilangan bulat dan tanda kurung ( ()) untuk menunjukkan prioritas.

Output harus terdiri dari bilangan bulat positif dan +simbol saja. Anda seharusnya tidak mengeluarkan langkah-langkah individual dari pengurangan, hanya hasil akhir. Output mungkin tidak terdiri dari angka yang tidak muncul di input. Namun, Anda dapat menggunakan 3 simbol berbeda, bukan +*^, tapi tolong katakan simbol apa itu

Ruang-ruang yang memisahkan input dan output mungkin atau tidak dapat digunakan dalam program Anda, yaitu 3 * 5dapat dikeluarkan sebagai salah satu 5 + 5 + 5atau 5+5+5.

Perhatikan bahwa dalam kebanyakan kasus, penambahan sebenarnya tidak dilakukan. Satu-satunya kasus di mana penambahan harus dilakukan adalah ketika Anda memiliki sesuatu seperti 5 ^ (1 + 2), dalam hal ini, penambahan diperlukan untuk melanjutkan -> 5 ^ 3 -> 5 * 5 * 5 -> .... Lihat test case # 4.

Kode Anda tidak perlu menangani input yang sampai pada ekspresi yang ambigu. Misalnya (2 + 2) * (4 + 1),. Karena aturan yang ditetapkan sejauh ini, tujuannya bukan untuk menghitung jawabannya, tujuannya adalah untuk menyederhanakan penambahan. Jadi hasilnya bisa berbeda tergantung pada urutan bahwa ekspresi diselesaikan atau diringankan (penambahan mana yang disederhanakan, yang harus ditinggalkan?). Contoh valid lain: ((3 + 2) ^ 2) ^ 3 -> ((3 + 2) * (3 + 2)) ^ 3 -> ???.

Ini adalah sehingga kode terpendek menang

Uji kasus

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
sumber
Bisakah kita menggunakan **bukan ^?
Erik the Outgolfer
@EriktheOutgolfer ya, sepertinya adil.
caird coinheringaahing
Terkait
Martin Ender
1
Saya masih bingung apa yang merupakan output yang valid. Dalam pertanyaan yang Anda katakan using only one of the two numbers in the original expression.tetapi ekspresi asli dapat memiliki lebih dari dua angka. Saya tidak mengerti mengapa 8 + 8ini bukan keluaran yang valid untuk 2 ^ 1 + 2 ^ 1 + 2 ^ 2 + 8 ^ 1. Pertanyaan ini masih belum jelas bagi saya.
Post Rock Garf Hunter

Jawaban:

6

Retina , 302 byte

Saya yakin ini bisa bermain golf, tetapi pada titik ini, saya senang itu berfungsi. Bagian eksponensial dan multiplikasi keduanya sangat mirip, tetapi karena urutan operasi itu penting, saya tidak tahu cara menggabungkannya.

y- Eksponensial
x- Perkalian
p- Penambahan

\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

Coba online - semua test case

Konverter kasus uji

Penjelasan

\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

Anda juga dapat memperhatikan bahwa grup yang paling umum digunakan adalah (\(\w+\)|1+). Ini cocok dengan ekspresi batin dengan tanda kurung, atau bilangan bulat. Saya memilih untuk menggunakan simbol yang saya lakukan sehingga saya bisa menggunakan \wdaripada kelas karakter. Saya tidak yakin apakah akan lebih baik menggunakan simbol non-kata dan mengganti beberapa lookaround dengan batas kata ( \b).

mbomb007
sumber
5

Mathematica, 250 218 183 170 byte

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

Berhasil! Akhirnya!

Menentukan fungsi dalam f.

Inputnya adalah ekspresi matematika biasa. (Yaitu 1 + 2tidak "1 + 2").

Cobalah secara Online!

Perhatikan bahwa tautan TIO memiliki kode yang sedikit berbeda, karena TIO (yang, saya duga, menggunakan kernel Mathematica) tidak suka Infix. RiffleSebagai gantinya saya menggunakan untuk mendapatkan penampilan yang sama dengan Mathematica REPL.

Tidak disatukan

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
sumber
6
Ok, saya senang saya menciptakan tantangan yang Mathematica tidak punya built in untuk: P
caird coinheringaahing
3

Mathematica, 405 406 byte

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

Tidak diikat dan dijelaskan

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

Aku pergi ke banyak kesulitan untuk mendapatkan efek berikut: fungsi ini mengambil sebagai masukan ekspresi Mathematica standar, dengan biasa +, *dan ^operasi (dan tanda kurung) di dalamnya, dan output apa yang tampak seperti ekspresi Mathematica standar (tapi dengan "dinonaktifkan" ditambah tanda-tanda) sebagai jawabannya.

Fungsi di atas dimulai dengan menonaktifkan semua operasi di input. Kemudian, ia menerapkan aturan ekspansi berulang kali hingga tidak ada yang bisa disederhanakan lagi. Setiap kali bertemu dengan produk seperti 2 * 3 * 4, yang dapat diperluas dengan berbagai cara, ia membuat daftar kemungkinan ekspansi, dan terus berjalan. Pada akhirnya, kami mendapatkan daftar jawaban akhir yang mungkin, dan yang paling pendek diambil.

Misha Lavrov
sumber