Buktikan bahwa suatu Angka adalah Aljabar

10

Terinspirasi oleh jawaban ini (penekanan pada saya):

Kami akan memainkan game. Misalkan Anda memiliki nomor x . Anda mulai dengan x dan kemudian Anda dapat menambah, mengurangi, mengalikan, atau membagi dengan bilangan bulat apa pun, kecuali nol. Anda juga bisa mengalikan dengan x . Anda dapat melakukan hal-hal ini sebanyak yang Anda inginkan. Jika total menjadi nol, Anda menang.

Misalnya, anggap x adalah 2/3. Kalikan dengan 3, lalu kurangi 2. Hasilnya adalah nol. Kamu menang!

Misalkan x adalah 7 ^ (1/3). Kalikan dengan x , lalu x lagi, lalu kurangi 7. Anda menang!

Misalkan x adalah √2 + √3. Di sini tidak mudah untuk melihat bagaimana menang. Tetapi ternyata jika Anda mengalikan x , kurangi 10, kalikan x dua kali, dan tambah 1, maka Anda menang. (Ini seharusnya tidak jelas; Anda dapat mencobanya dengan kalkulator Anda.)

Tetapi jika Anda mulai dengan x = π, Anda tidak bisa menang. Tidak ada cara untuk beralih dari π ke 0 jika Anda menambahkan, mengurangi, mengalikan, atau membagi dengan bilangan bulat, atau mengalikan dengan π, tidak peduli berapa banyak langkah yang Anda ambil. (Ini juga tidak seharusnya jelas. Itu adalah hal yang sangat rumit!)

Angka seperti √2 + √3 dari mana Anda bisa menang disebut aljabar . Angka seperti π yang tidak dapat Anda menangkan disebut transendental.

Mengapa ini menarik? Setiap angka aljabar terkait secara hitung dengan bilangan bulat, dan gerakan yang menang dalam permainan menunjukkan kepada Anda bagaimana hal itu terjadi. Jalan menuju nol mungkin panjang dan rumit, tetapi setiap langkah sederhana dan ada jalan. Tetapi bilangan transendental berbeda secara mendasar: bilangan transendental tidak terkait secara hitung dengan bilangan bulat melalui langkah-langkah sederhana.


Pada dasarnya, Anda akan menggunakan langkah-langkah yang digunakan dalam pertanyaan yang dikutip di atas untuk "memenangkan" game untuk input yang diberikan.

Dengan konstanta aljabar nyata, xkonversikan bilangan menjadi nol dengan menggunakan operasi yang diizinkan berikut ini:

  • Tambahkan atau Kurangi bilangan bulat.
  • Lipat gandakan atau Bagi dengan bilangan bulat bukan nol.
  • Kalikan dengan konstanta asli x.

Input adalah string yang mungkin mengandung bilangan bulat, penjumlahan, pengurangan, perkalian, pembagian, eksponensial (pilihan Anda **atau ^, eksponen digunakan untuk mewakili akar), dan tanda kurung. Spasi dalam input adalah opsional, tetapi tidak dalam output. Anda harus menampilkan langkah-langkah yang diperlukan untuk mendapatkan hasil nol, jadi mengalikan dengan 7satu langkah akan menjadi hasil sebagai *7. Ruang tambahan dan / atau baris baru diizinkan.

Contohnya

0               ->  +0 (or any other valid, or empty)
5/7 + 42        ->  -42 *7 -5 (or shorter: *7 -299)
2^(1/3)         ->  *x *x -2
5*(3**(1/4))    ->  *x *x *x -1875
2^(1/2)+3^(1/2) ->  *x -10 *x *x +1

Kode terpendek menang.

mbomb007
sumber
Seberapa dekat dengan 0hasil yang perlu dilakukan? Mengingat kesalahan pembulatan dan presisi float, saya dapat dengan mudah melihat situasi bermasalah ...
AdmBorkBork
2
@ TimmyD Jawabannya harus tepat, sehingga saya bisa melakukan operasi dan mendapatkan nol. Lihat contoh yang disediakan. Tidak ada aritmatika floating point.
mbomb007
1
Bagaimana √2 + √3 aljabar? Jika Anda mengalikan angka dengan sendirinya, Anda akan mendapatkan 5 + 2√6 ... kecuali jika saya melewatkan sesuatu, Anda tidak akan pernah bisa mengeluarkan radikal.
Mario Ishac
@ mbomb007 Ups, permintaan maaf saya, tidak menangkap itu di OP.
Mario Ishac
1
Ini solusi untuk persamaan x^4-10*x^2+1. Lihat WolframAlpha
mbomb007

Jawaban:

3

SageMath , 108 byte

def f(s):p=map('{:+} '.format,numerator(minpoly(sage_eval(s)/1)));return'*'+p[-1][1:]+'*x '.join(p[-2::-1])

Cobalah di SageMathCell .

Penjelasan:

Mengevaluasi string secara simbolis sebagai angka aljabar ( sage_eval()). Setiap angka aljabar adalah nol dari beberapa polinomial a [0] + a [1] x ^ 1 + a [2] x ^ 2 + ⋯ + a [n] x ^ n dengan koefisien rasional a [0], ..., a [ n ] ( minpoly()). Lipat gandakan semua koefisien dengan penyebut bersama untuk mengubahnya menjadi bilangan bulat ( numerator()), lalu tulis polinomial ini dalam format output yang diinginkan,

*a[n] +a[n-1] *x +a[n-2] *x … *x +a[1] *x +a[0]

SageMath, 102 byte, hampir

lambda s:(lambda a,*p:'*%d'%a+'*x'.join(map(' {:+} '.format,p)))(*numerator(minpoly(1/sage_eval(s))))

Ini berfungsi untuk semua input kecuali 0, karena polinomial untuk 1 / α adalah polinomial untuk α dengan koefisien yang dibalik. :-(

Anders Kaseorg
sumber
1

Mathematica, 194 224 192 byte

""<>Cases[HornerForm@MinimalPolynomial[ToExpression@#,x]//.{Times->t,x^a_:>Fold[#2~t~#&,x~Table~a],a_~t~b_~t~c_:>a~t~t[b,c]},a_~b_~_:>{b/.t:>"*"/.Plus:>If[a>0,"+",""],ToString@a," "},{0,∞}]&

Berikut adalah karakter unicode tiga byte yang merepresentasikan infinity dalam Mathematica.

Karena input adalah string, 13 byte hilang ToExpression@yang menginterpretasikan input string sebagai ekspresi aljabar.

HornerForm@MinimalPolynomial[2^(1/2)+3^(1/2), x]

Akan mengembalikan sesuatu seperti

1 + x^2 (-10 + x^2)

Aturan penggantian selanjutnya memijat ini menjadi sesuatu yang seperti struktural

1 + (x * (x * (-10 + (x * (x)))))

Bentuk Horner ini dapat divisualisasikan seperti pohon:

TreeForm

Kami, dengan aturan OP mulai dengan daun terdalam di sebelah kanan.

Cases pergi melalui ekspresi, mulai dari level terdalam, mengambil setiap simpul orangtua dan daun kirinya dan merakit ini ke dalam tabel seperti

"*" "x"   " "
""  "-10" " "
"*" "x"   " "
"*" "x"   " "
"+" "1"   " "

""<> menggabungkan semuanya dengan string kosong.

LLlAMnYP
sumber
Ini salah mengembalikan -299untuk 5/7 + 42.
Anders Kaseorg
@ Dan Jadi itu menghilangkan * 7 ... Saya akan memeriksa sekali setelah saya di rumah
LLlAMnYP
@AndersKaseorg ini berfungsi, tapi sekarang saya 30 byte ke bawah.
LLlAMnYP