Metode Newton oleh Quurs Rekursif

32

Tugas Anda adalah menghitung akar kuadrat dari 2 menggunakan Metode Newton - dengan sedikit twist. Program Anda adalah menghitung iterasi menggunakan Metode Newton, dan mengeluarkan kode sumber untuk iterasi berikut (yang harus dapat melakukan hal yang sama).

Metode Newton dijelaskan secara mendalam di Wikipedia

Untuk menghitung akar 2 menggunakan metode Newtons, Anda:

  • Menetapkan f(x) = x^2 - 2
  • Menetapkan f'(x) = 2x
  • Tentukan x[0](tebakan awal)= 1
  • Menetapkan x[n+1] = x[n] - (f[n] / f'[n])

Setiap iterasi akan bergerak x [n] lebih dekat ke akar kuadrat dari dua. Jadi -

  • x[0] = 1
  • x[1] = x[0] - f(x[0])/f'(x[0]) = 1 - (1 ^ 2 - 2) / (2 * 1) = 1.5
  • x[2] = x[1] - f(x[1])/f'(x[1]) = 1.5 - (1.5 ^ 2 - 2) / (2 * 1.5) = 1.416666667
  • x[3] = x[2] - f(x[2])/f'(x[1]) = 1.416666667 - (1.416666667 ^ 2 - 2) / (2 * 1.416666667) = 1.414215686
  • dan seterusnya

Program Anda akan:

  • Hitung di x[n]mana nadalah berapa kali program telah dijalankan
  • Keluarkan kode sumber ke program yang valid dalam bahasa yang sama yang harus menghitung x[n+1]dan memenuhi kriteria yang sama dari pertanyaan ini.
  • Baris pertama dari kode sumber harus hasil perhitungan, dikomentari dengan benar. Jika sumber membutuhkan sesuatu yang khusus (seperti shebang) pada baris pertama, hasilnya dapat diletakkan pada baris kedua.

Catat itu

  • Program Anda harus menggunakan tebakan awal x[0] = 1
  • The Standard Celah berlaku
  • Setiap fungsi built-in, root kuadrat atau xroot dilarang
  • Program Anda tidak boleh menerima input apa pun. Itu harus sepenuhnya mandiri.

Skor Anda adalah ukuran program awal Anda dalam UTF-8 byte. Skor terendah menang.

lochok
sumber
Apakah kita harus mendefinisikan fungsi, atau dapatkah kita menyederhanakan dengan menulis x = x-(x*x-2)/(2*x)?
Kyle Kanos
Penyederhanaan itu terlihat valid bagi saya. Selama melakukan perhitungan menggunakan Metode Newton
lochok
Apakah program menampilkan perkiraan, atau hanya kode sumber? Bisakah ini sebagai masukan dari solusi sebelumnya?
Emily
Itu harus menampilkan perkiraan (berkomentar) pada baris pertama, dengan kode sumber untuk iterasi berikutnya. Perkiraan dapat didahului oleh shebang jika bahasa tersebut membutuhkannya. Program (atau program yang dihasilkannya) tidak boleh menerima input apa pun.
lochok

Jawaban:

19

Common Lisp, 223 95 68 66

(#1=(lambda(x p)(format t"~S~%~S"p`(,x',x,(+(/ p 2)(/ p)))))'#1#1)

Sekarang saya membaca pernyataan masalah lebih hati-hati (terima kasih, primo !) Saya perhatikan bahwa baris pertama harus merupakan hasil perhitungan, bukan karena itu perlu mengandung hasilnya. Jadi, saya pikir upaya saya sebelumnya tidak cukup mengikuti aturan. Yang ini seharusnya.

Contoh penggunaan (SBCL 1.1.15):

$ sbcl --script nq.lisp | tee nq2.lisp
1
((LAMBDA (X P) (FORMAT T "~S~%~S" P `(,X ',X ,(+ (/ P 2) (/ P)))))
 '(LAMBDA (X P) (FORMAT T "~S~%~S" P `(,X ',X ,(+ (/ P 2) (/ P))))) 3/2)
$ sbcl --script nq2.lisp | tee nq3.lisp
3/2
((LAMBDA (X P) (FORMAT T "~S~%~S" P `(,X ',X ,(+ (/ P 2) (/ P)))))
 '(LAMBDA (X P) (FORMAT T "~S~%~S" P `(,X ',X ,(+ (/ P 2) (/ P))))) 17/12)
$ sbcl --script nq3.lisp | tee nq4.lisp
17/12
((LAMBDA (X P) (FORMAT T "~S~%~S" P `(,X ',X ,(+ (/ P 2) (/ P)))))
 '(LAMBDA (X P) (FORMAT T "~S~%~S" P `(,X ',X ,(+ (/ P 2) (/ P))))) 577/408)
$ sbcl --script nq4.lisp | tee nq5.lisp
577/408
((LAMBDA (X P) (FORMAT T "~S~%~S" P `(,X ',X ,(+ (/ P 2) (/ P)))))
 '(LAMBDA (X P) (FORMAT T "~S~%~S" P `(,X ',X ,(+ (/ P 2) (/ P)))))
 665857/470832)
$ sbcl --script nq5.lisp | tee nq6.lisp
665857/470832
((LAMBDA (X P) (FORMAT T "~S~%~S" P `(,X ',X ,(+ (/ P 2) (/ P)))))
 '(LAMBDA (X P) (FORMAT T "~S~%~S" P `(,X ',X ,(+ (/ P 2) (/ P)))))
 886731088897/627013566048)
$
jlahd
sumber
Saya sebagian besar telah menguji dengan CCL, tetapi bekerja sama dengan SBCL dan CLISP.
jlahd
1
Ini lebih seperti yang kuharapkan. +1
primo
17

Python 60 byte

x=1.
o='x=%s\no=%r;print o%%(x/2+1/x,o)';print o%(x/2+1/x,o)

Saya sedikit menyederhanakan formula, menggunakan penggantian berikut:

  x-(x²-2)/(2x)
= (2x²)/(2x)-(x²-2)/(2x)
= (2x²-x²+2)/(2x)
= (x²+2)/(2x)
= (x+2/x)/2
= x/2+1/x

Saya harap itu bukan masalah.

Program berlanjut dengan cara berikut:

$ python newton-quine.py
x=1.5
o='x=%s\no=%r;print o%%(x/2+1/x,o)';print o%(x/2+1/x,o)

$ python newton-quine.py
x=1.41666666667
o='x=%s\no=%r;print o%%(x/2+1/x,o)';print o%(x/2+1/x,o)

$ python newton-quine.py
x=1.41421568627
o='x=%s\no=%r;print o%%(x/2+1/x,o)';print o%(x/2+1/x,o)

$ python newton-quine.py
x=1.41421356237
o='x=%s\no=%r;print o%%(x/2+1/x,o)';print o%(x/2+1/x,o)

dll.

primo
sumber
Saya tidak tahu apakah ini legal atau tidak, tetapi Anda dapat mempersingkat kode awal menjadi g="x=%s;o=%r;print o%%(x/2+1/x,o)";print g%(1.5,g)@ 50 karakter.
cjfaure
@Rimsty Saya pikir itu sedikit bermasalah bahwa 1) tidak benar-benar menghitung iterasi pertama, dan bahwa 2) baris pertama tidak berisi hasil saat ini. Ketika saya memahami uraian masalah, baik program asli dan generasi selanjutnya harus memenuhi kriteria ini.
Primo
13

CJam, 20 byte

1
{\d_2/1@/+p"_~"}_~

Cobalah online.

Keluaran

$ cjam <(echo -e '1\n{\d_2/1@/+p"_~"}_~'); echo
1.5
{\d_2/1@/+p"_~"}_~
$ cjam <(cjam <(echo -e '1\n{\d_2/1@/+p"_~"}_~')); echo
1.4166666666666665
{\d_2/1@/+p"_~"}_~
$ cjam <(cjam <(cjam <(echo -e '1\n{\d_2/1@/+p"_~"}_~'))); echo
1.4142156862745097
{\d_2/1@/+p"_~"}_~
$ cjam <(cjam <(cjam <(cjam <(echo -e '1\n{\d_2/1@/+p"_~"}_~')))); echo
1.4142135623746899
{\d_2/1@/+p"_~"}_~

Bagaimana itu bekerja

1       " Push the initial guess.                                                 ";
{       "                                                                         ";
  \d    " Swap the code block with the initial guess and cast to Double.          ";
  _2/   " Duplicate the initial guess and divide the copy by 2.                   ";
  1@/   " Push 1, rotate the initial guess on top and divide.                     ";
  +p    " Add the quotients and print.                                            ";
  "_~"  " Push the string '_~'.                                                   ";
}       "                                                                         ";
_~      " Duplicate the code block (to leave a copy on the stack) and execute it. ";
Dennis
sumber
2
Ya, itu mengesankan. +1
Kyle Kanos
8

ECMASkrip 6, 38 36

(f=x=>"(f="+f+")("+(x/2+1/x)+")")(1)
(f=x=>"(f="+f+")("+(x/2+1/x)+")")(1.5)
(f=x=>"(f="+f+")("+(x/2+1/x)+")")(1.4166666666666665)
(f=x=>"(f="+f+")("+(x/2+1/x)+")")(1.4142156862745097)
(f=x=>"(f="+f+")("+(x/2+1/x)+")")(1.4142135623746899)

JavaScript, 51

(function f(x){return "("+f+")("+(x/2+1/x)+")"})(1)

Ini sama dengan di atas, untuk browser lama.

Zaq
sumber
1
Kadang-kadang saya hanya kagum bagaimana javascript sederhana dapat membuat sesuatu. +1
seequ
Hal ini tampaknya kurang apapun output ( print, putstr, console.log, dll).
Primo
@primo - Ketika JavaScript dijalankan di konsol, nilai yang dikembalikan secara otomatis dicetak.
Derek 朕 會 功夫
@Derek 朕 會 功夫 Sangat banyak bahasa dapat dijalankan sebagai REPL - ini adalah ekspresi, dan bukan program yang lengkap. Lihat: "celah" standar yang tidak lagi lucu .
primo
1
@Derek 朕 會 功夫 Deskripsi masalah secara khusus meminta program - di beberapa tempat. Program yang disediakan tidak melakukan apa-apa. Saksi: i.stack.imgur.com/Te7Vf.png Di atas adalah ekspresi yang mengevaluasi ekspresi. Ini memiliki kelebihannya sendiri, tetapi itu bukan program.
primo
6

Lua 129

Mungkin terlalu lama, tetapi Lua quine menyebalkan karena bersarang [[ ]]adalah fitur yang sudah ketinggalan zaman . Tapi itu berhasil terlepas dari:

x=1.0;x=x/2.+1./x;l=[[io.write('x=',x,';x=x/2.+1./x;l=[','[',l,']','];',l)]];io.write('x=',x,';x=x/2.+1./x;l=[','[',l,']','];',l)

Agak lebih baik untuk melihat apakah Anda menambahkan baris baru daripada titik dua:

x=1.0
x=x/2.+1./x
l=[[io.write('x=',x,'\nx=x/2.+1./x\nl=[','[',l,']','];',l)]];io.write('x=',x,'\nx=x/2.+1./x\nl=[','[',l,']','];',l)
Kyle Kanos
sumber
4

J - 102 88 byte

Ini sama mengerikannya dengan saya membuat quines (saya mungkin akan merevisi ini ketika saya mendapatkan ide yang lebih baik). Mengapung J terbatas pada 5 tempat desimal, tetapi dengan mengganti baris pertama dengan x=:1xitu akan menjadi sebagian kecil dengan presisi tak terbatas.

Edit 1: I got better idea. Also added the explanation.

x=:1
((3&{.,[:":(x%2)+1%x"_),:3&}.,],{:,{:)'x=:((3&{.,[:":(x%2)+1%x"_),:3&}.,],{:,{:)'''

Beberapa iterasi pertama:

x=:1.5
((3&{.,[:":(x%2)+1%x"_),:3&}.,],{:,{:)'x=:((3&{.,[:":(x%2)+1%x"_),:3&}.,],{:,{:)'''

x=:1.41667
((3&{.,[:":(x%2)+1%x"_),:3&}.,],{:,{:)'x=:((3&{.,[:":(x%2)+1%x"_),:3&}.,],{:,{:)'''

x=:1.41422
((3&{.,[:":(x%2)+1%x"_),:3&}.,],{:,{:)'x=:((3&{.,[:":(x%2)+1%x"_),:3&}.,],{:,{:)'''

Penjelasan

((3&{.,[:":(x%2)+1%x"_),:3&}.,],{:,{:)'x=:((3&{.,[:":(x%2)+1%x"_),:3&}.,],{:,{:)'''
((3&{.,[:":(x%2)+1%x"_),:3&}.,],{:,{:) The quine-function
                         3&}.,],{:,{:  Build the second row
                         3&}.          Get everything but the first 3 characters from the string
                             ,]        Get the whole string and concat
                               ,{:     Get the last item (') and concat
                                  ,{:  -||-
 (3&{.,[:":(x%2)+1%x"_)                Build the first row
       [:":(x%2)+1%x"_                 Calculate x/2 + 1/x (stolen from Pythoneer) and stringify
  3&{.                                 Take the first 3 characters from the string (x=:)
      ,                                Concatenate 'x=:' and the result
                       ,:              Concatenate the two rows
seequ
sumber
1
Saya sebenarnya suka betapa sederhananya program ini (untuk yang serius).
seequ
Jika saya mendapatkan lebih banyak waktu, saya akan melihat apakah saya dapat memodifikasi di atas untuk Kona.
Kyle Kanos
@KyleKanos Setidaknya digit-rotasi-benda cukup mirip, tapi saya tidak tahu Kona. Semoga berhasil! :)
seequ
1%xsama dengan %x. Alih-alih (x%2)+1%x, Anda bisa melakukannya (%&2+%)x.
Conor O'Brien
3

Ruby, 65

x=1.0
puts"x=#{x/2+1/x}",<<'1'*2,1
puts"x=#{x/2+1/x}",<<'1'*2,1
1

Seperti yang sering terjadi, ini hampir merupakan port langsung dari solusi Python.

histokrat
sumber