再帰クインによるニュートン法


32

あなたの仕事は、ニュートンの方法を使用して2の平方根を計算することです。プログラムは、ニュートン法を使用して反復を計算し、次の反復のソースコードを出力します(これは同じことを実行できる必要があります)。

ニュートンの方法は、ウィキペディアでかなり網羅的に説明されています

ニュートン法を使用して平方根2を計算するには、次のようにします。

  • 定義する f(x) = x^2 - 2
  • 定義する f'(x) = 2x
  • 定義x[0](最初の推測)= 1
  • 定義する x[n+1] = x[n] - (f[n] / f'[n])

各反復は、x [n]を2の平方根に近づけます。そう -

  • 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
  • 等々

あなたのプログラムは:

  • 計算は、x[n]どこnのプログラムが実行された倍の量であります
  • x[n+1]この質問と同じ基準を計算し、満たす必要がある同じ言語の有効なプログラムにソースコードを出力します。
  • ソースコードの最初の行は、適切にコメント化された計算結果でなければなりません。ソースの最初の行に特定の何か(シバンなど)が必要な場合、結果は2行目に表示される場合があります。

ご了承ください

  • プログラムは、次の初期推測を使用する必要があります x[0] = 1
  • 標準的な抜け穴が適用されます
  • 組み込みのパワー、平方根またはxroot機能は禁止されています
  • あなたのプログラムはいかなる入力も受け付けてはいけません。完全に自己完結している必要があります。

スコアは、初期プログラムのサイズをUTF-8バイトで表したものです。最も低いスコアが勝ちます。


関数を定義する必要がありますか、または書くことで単純化できx = x-(x*x-2)/(2*x)ますか?
カイルカノス14年

この単純化は私には妥当なようです。であればニュートン法を用いて計算を行うよう
lochok

プログラムは近似値を出力しますか、それともソースコードのみを出力しますか?以前のソリューションを入力として使用できますか?
エミリー14年

次の反復のソースコードと共に、最初の行に(コメント化された)近似値を出力する必要があります。言語がそれを必要とする場合、近似の前にシバンを付けることができます。プログラム(またはそれが生成するプログラム)は入力を受け付けてはなりません。
lochok 14年

回答:


19

Common Lisp、223 95 68 66

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

今私は(おかげで、より慎重に問題文を読んでいることプリモ!)私は、最初の行がなければならないことに気づいたこと、それはする必要がないことを、計算の結果含まれていた結果を。したがって、私は以前の試みが規則に完全に従わなかったと思います。これが必要です。

使用例(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)
$

私はほとんどCCLでテストしてきましたが、SBCLとCLISPの両方で同様に動作します。
jlahd

1
これは私が期待していたようなものです。+1
プリモ14年

17

Python 60バイト

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

次の置換を使用して、数式を少し簡略化しました。

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

それが問題にならないことを願っています。

プログラムは次のように進行します。

$ 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)


これが合法かどうかはわかりませんが、初期コードをg="x=%s;o=%r;print o%%(x/2+1/x,o)";print g%(1.5,g)@ 50文字に短縮できます。
cjfaure 14年

@Trimsty 1)最初の反復を実際に計算しないこと、2)最初の行に現在の結果が含まれていないことは少し問題があると思います。問題の説明を理解すると、元のプログラムとそれ以降の世代の両方がこれらの基準を満たす必要があります。
プリモ14年

13

CJam、20バイト

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

オンラインでお試しください。

出力

$ 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"_~"}_~

使い方

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. ";

2
まあそれは印象的です。+1
カイルカノス14年

8

ECMAScriptの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)

これは、古いブラウザーの場合、上記と同じです。


1
時々、私は単純なjavascriptが物事を作ることができることに驚いています。+1
seequ 14年

これは、(出力の任意の並べ替え欠けているようだprintputstrconsole.log、など)。
プリモ14年

@primo-JavaScriptがコンソールで実行されると、戻り値が自動的に出力されます。
デレク朕會功夫14

@Derek朕會功夫非常に多くの言語をREPLとして実行できます-これは表現であり、完全なプログラムではありません。参照:もはや面白くない標準の「抜け穴」
primo 14

1
@Derek朕會功夫問題の説明は、特にプログラムを求めています-いくつかの場所で。提供されたプログラムは何もしません。証人:i.stack.imgur.com/Te7Vf.png上記は式に評価される式です。独自のメリットがありますが、プログラムではありません。
primo 14

6

ルア129

おそらく長すぎるかもしれ[[ ]]ませんが、ネストは非推奨の機能であるため、Luaのクイネはダメです。しかし、それは関係なく動作します:

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)

コロンの代わりに改行を追加するかどうかを確認するのは少し良いです:

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)

4

J- 102 88バイト

これは私がクインを作るのと同じくらい恐ろしいことです(より良いアイデアが得られたら、おそらくこれを修正します)。Jの浮動小数点数は小数点以下5桁に制限されていますが、最初の行をx=:1xそれに置き換えると、精度が無限の小数になります。

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&}.,],{:,{:)'''

最初の数回の反復:

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&}.,],{:,{:)'''

説明

((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

1
私は実際、このプログラムがどれほどシンプルであるかが大好きです(本気で)。
seequ 14年

もっと時間があれば、コナの上記を変更できるかどうかを確認します。
カイルカノス14年

@KyleKanos少なくとも数字の回転は十分似ていましたが、コナは知りません。がんばろう!:)
seequ 14年

1%xはと同じ%xです。代わりに(x%2)+1%x、できます(%&2+%)x
コナーオブライエン

3

ルビー、65

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

あまりにも頻繁に起こるように、これはほとんどPythonソリューションの移植版です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.