Newtons Method by Recursive Quines

33

3

Your task is to calculate the square root of 2 using Newton's Method - with a slight twist. Your program is to calculate an iteration using Newton's Method, and output the source code for the following iteration (which must be able to do the same).

Newton's method is fairly exhaustively described on Wikipedia

To calculate square root 2 using Newtons method, you:

  • Define f(x) = x^2 - 2
  • Define f'(x) = 2x
  • Define x[0] (the initial guess) = 1
  • Define x[n+1] = x[n] - (f[n] / f'[n])

Each iteration will move x[n] closer to the square root of two. So -

  • 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
  • and so on

Your program will:

  • Calculate x[n] where n is the amount of times the program has been run
  • Output the source code to a valid program in the same language which must calculate x[n+1] and satisfy the same criteria of this question.
  • The first line of the source code must be the calculate result, properly commented. If the source requires something particular (such as a shebang) on the first line, the result may be put on the second line.

Note that

  • Your program must use an initial guess of x[0] = 1
  • The Standard Loopholes apply
  • Any in-build power, square root or xroot functions are forbidden
  • Your program must not accept any input whatsoever. It must be entirely self contained.

Your score is the size of your initial program in UTF-8 bytes. The lowest score wins.

lochok

Posted 2014-06-18T13:00:45.887

Reputation: 3 139

Do we have to define the functions, or can we simplify by writing x = x-(x*x-2)/(2*x)? – Kyle Kanos – 2014-06-18T13:31:11.887

That simplification looks valid to me. As long as it performs the calculation using Newton's Method – lochok – 2014-06-18T22:02:41.110

Does the program output the approximation, or just the source code? Can it take as its input the previous solution? – Emily – 2014-06-19T16:03:35.277

It has to output the approximation (commented) on the first line, with the source code for the next iteration. The approximation may be preceded by a shebang if the language requires it. The program (nor the program it produces) must not accept any input. – lochok – 2014-06-22T07:26:42.080

Answers

19

Common Lisp, 223 95 68 66

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

Now that I read the problem statement more carefully (thanks, primo!) I noticed that the first line must be the result of calculation, not that it needs to contain the result. Thus, I think my earlier attempts did not quite follow the rules. This one should.

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

Posted 2014-06-18T13:00:45.887

Reputation: 836

I've been mostly testing with CCL, but it works similarly with both SBCL and CLISP. – jlahd – 2014-06-19T05:42:26.133

1This is more like I was expecting. +1 – primo – 2014-06-19T13:53:10.760

17

Python 53 bytes

Saved 7 bytes due to @Mukundan.

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

I've simplified the formula slightly, using the following substitutions:

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

I hope that's not an issue.

The program proceeds in the following manner:

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

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

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

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

etc.

primo

Posted 2014-06-18T13:00:45.887

Reputation: 30 891

1you can shorten you code by 7 bytes by using exec x=1. o='print"x=%s\\no=%r;exec o"%(x/2+1/x,o)';exec o – Mukundan – 2020-01-28T06:57:12.323

@Mukundan that's a great improvement, thanks! – primo – 2020-01-28T07:36:03.790

I don't know if this is legal or not, but you can shorten your initial code to g="x=%s;o=%r;print o%%(x/2+1/x,o)";print g%(1.5,g) @ 50 chars. – cjfaure – 2014-06-18T16:11:35.297

@Trimsty I think it's slightly problematic that 1) it doesn't actually calculate the first iteration, and that 2) the first line doesn't contain the current result. As I understand the problem description, both the original program and later generations should satisfy these criteria. – primo – 2014-06-18T16:41:05.953

13

CJam, 20 bytes

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

Try it online.

Output

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

How it works

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

Posted 2014-06-18T13:00:45.887

Reputation: 196 637

2Well that's impressive. +1 – Kyle Kanos – 2014-06-18T18:01:44.787

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)

This is the same as the above, for older browsers.

Zaq

Posted 2014-06-18T13:00:45.887

Reputation: 1 525

1Sometimes I'm just amazed how simple javascript can make things. +1 – seequ – 2014-06-19T08:34:43.927

This seems to be lacking any sort of output (print, putstr, console.log, etc.). – primo – 2014-06-20T04:22:51.927

@primo - When JavaScript is run in a console, the returned value is automatically printed. – Derek 朕會功夫 – 2014-08-17T01:30:00.233

@Derek朕會功夫 Very many languages can be run as REPL - this is an expression, and not a complete program. See: Standard “loopholes” which are no longer funny.

– primo – 2014-08-28T10:41:26.747

@primo - This is a complete program. The compiler can compile and execute this with no problem. What's considered a snippet is a piece of code that needs extra codes in order to make it work. One such example can be found in your link. When Zaq's answer is run in a console (the environment), it compiles and needs no extra code around it. The automatically returned string is implemented right in the "environment", so no rules are violated, and indeed this isn't any kind of loophole. – Derek 朕會功夫 – 2014-08-28T14:22:24.080

@Derek朕會功夫 The 'interactive console' provided with many browsers is an REPL: "a simple, interactive computer programming environment that takes single user inputs (i.e. single expressions), evaluates them, and returns the result to the user; a program written in a REPL environment is executed piecewise." Run as a script with a command line JS interpreter, this 'program' outputs nothing. By the standard you suggest, code written in any language for which an REPL even exists need not output anything.

– primo – 2014-08-28T14:53:24.243

@primo - What are making you to think those "expressions" do not output anything? In this specific environment, it will output anything the "expression" has returned. Same goes to things like "print(text)". Depending on which environment you are executing your code in, you code behaves differently. – Derek 朕會功夫 – 2014-08-28T15:03:52.160

1

@Derek朕會功夫 The problem description specifically asks for a program - in several places. The program supplied does nothing. Witness: http://i.stack.imgur.com/Te7Vf.png The above is an expression that evaluates to an expression. It has merit of its own, but it is not a program.

– primo – 2014-08-28T15:29:32.990

@primo - It did does something. It caused the environment (the console) to generate an output on the screen. This is a legit program, not simply an expression. – Derek 朕會功夫 – 2014-08-28T16:08:01.103

Can both of you give it a rest? You're filling my inbox with your little spat. This question/answer hasn't had any activity in 2 months and I don't really care who of you is right. – Zaq – 2014-08-28T22:59:03.813

6

Lua 129

Probably way too long, but the Lua quine sucks because the nested [[ ]] is a deprecated feature. But it works regardless:

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)

It's a bit nicer to see if you add newlines instead of colons:

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

Posted 2014-06-18T13:00:45.887

Reputation: 4 270

4

J - 102 88 bytes

This is as horrible as I'm at making quines (I will probably revise this when I get better ideas). J's floats are limited to 5 decimal places, but by replacing first line with x=:1x it would be a fraction with infinite precision.

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

First few iterations:

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

Explanation

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

Posted 2014-06-18T13:00:45.887

Reputation: 1 714

1%x is the same as %x. Instead of (x%2)+1%x, you can do (%&2+%)x. – Conor O'Brien – 2017-02-10T15:57:31.527

1I actually love how simple this program is (for serious). – seequ – 2014-06-18T19:45:58.030

If I get more time, I'm going to see if I can modify the above for Kona. – Kyle Kanos – 2014-06-19T16:10:46.587

@KyleKanos At least the digit-rotation-thingy was similar enough, but I don't know Kona. Good luck! :) – seequ – 2014-06-19T16:35:37.360

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

As too often happens, this is almost a straight port of the Python solution.

histocrat

Posted 2014-06-18T13:00:45.887

Reputation: 20 600

1

Perl 5, (-M5.01) 58 bytes

$x=1.;$_=q(say'$x='.($x/2+1/$x).qq(;\$_=q($_);eval));eval

Try it online!

Nahuel Fouilleul

Posted 2014-06-18T13:00:45.887

Reputation: 5 582