Implement the Fibonacci-quine

13

2

A Quine is a program which outputs its source when run.

In this challenge, You should make a Fibonacci-quine, a variant of the quine.


What is a Fibonacci-quine?

A Fibonacci-quine is a program, which outputs a modification of the source by the following rule:

The initial source should be ...2.... In other words, the source should contain 2. (Why 2? If it was 1, Nobody would know if it was the first 1 or the second, Even the program itself)

When run, You should output the source, but only the specific number (In this stage, 2) changed to the next number of the fibonacci sequence. For example, ...3.... Same goes for the output, and the output of the output, etc. You may support integers for up to 2^32-1. For integers over that limit, the next output is on your choice.

OP's note

I would really like to see a creative solution for this. I couldn't think of a single solution for this, since Both of the two important aspects of the challenge, fibonacci and quine, is not easy. I'll be waiting then!

Matthew Roh

Posted 2017-05-08T09:31:02.060

Reputation: 5 043

Related. – Leaky Nun – 2017-05-08T11:25:07.237

4The quine part doesn't add much to this challenge. This is just "next value in Fibonacci sequence" plus a universal quine constructors, as the answers show. – None – 2017-05-08T17:08:26.220

I agree. I would like to see a creative solution for this as well. But if you want a creative solution so bad, then why not make it a code-challenge instead of code-golf. The winning criteria could be the highest number of votes after some time interval or something. – Fixed Point – 2017-05-08T18:52:23.427

@FixedPoint What about a 'Second criteria'? Someone makes a creative solution, I give them bounty. – Matthew Roh – 2017-05-09T00:17:36.687

@FixedPoint That's a [tag:popularity-contest] – boboquack – 2017-05-09T10:40:50.253

Answers

8

Mathematica, 61 bytes

ToString[#0 /. v:2 :> RuleCondition[Round[GoldenRatio v]]] & 

Note that there is a trailing space. This is a function quine, i.e. the above code evaluates to an unnamed function which, if called returns the code itself as a string (with 2 changed to the next Fibonacci number).

This was suprisingly tricky to get to work. The basic idea is to take the function itself (with #0) and replace a number in that function with the next one using /. v:2 :> nextFib[v]. However, nextFib wouldn't get evaluated at this stage so we wouldn't really end up with the new number in the source code. After searching around for a while to figure out how to force immediate evaluation, I found this great post on Mathematica.SE. The "standard" technique uses a With block which forces evaluation, but the second answer by WReach contains a shorter alternative using the undocumented built-in RuleCondition which also forces evaluation.

The way we compute the next Fibonacci number is by making use of the fact that the ratio of consecutive numbers is roughly the golden ratio 1.618... and this is accurate up to rounding. So we don't need to keep track of the last two numbers and can simply do Round[GoldenRatio v]. This will never lose precision since Mathematica's GoldenRation is a symbolic value and therefore Round can always compute an accurate result.

In summary:

... #0 ... &

An unnamed function, where #0 refers to the function object itself.

... /. v:2 :> ...

Find a 2 in the expression tree of the function (this 2 of course only matches itself), call it v and replace it with...

... RuleCondition[Round[GoldenRatio v]]

... the next Fibonacci number.

ToString[...]

And convert the resulting expression tree to its string representation.

Martin Ender

Posted 2017-05-08T09:31:02.060

Reputation: 184 808

It's nice to know you have to work hard at these sometimes :) – Greg Martin – 2017-05-09T06:11:39.990

Isn't there a symbol for the golden ratio? – caird coinheringaahing – 2017-06-18T23:53:03.640

@cairdcoinheringaahing no. – Martin Ender – 2017-06-19T04:45:29.987

7

CJam, 26 bytes

2{0X{_@+_W$>!}go;\;"_~"}_~

Try it online!

Probably not quite optimal. We simply iterate the Fibonacci sequence until the value is greater than the last one and use the result as the new value at the beginning of the program.

Martin Ender

Posted 2017-05-08T09:31:02.060

Reputation: 184 808

6Thi..This early? – Matthew Roh – 2017-05-08T09:48:17.613

7

Python 3, 95 bytes

a=b=1
while a<2:a,b=b,a+b
s='a=b=1\nwhile a<%i:a,b=b,a+b\ns=%r;print(s%%(b,s))';print(s%(b,s))

Try it online!

Obviously a fork of Martin Ender's CJam answer.

Leaky Nun

Posted 2017-05-08T09:31:02.060

Reputation: 45 011

6

CJam, 20 bytes

2{\5mq)*)Y/io"_~"}_~

Try it online!

jimmy23013

Posted 2017-05-08T09:31:02.060

Reputation: 34 042

Wow, 20 bytes: I'm speechless... – Mr. Xcoder – 2017-05-08T12:18:39.343

5

Actually, 19 bytes

2⌠è@fuF$+";ƒ"@+⌡;ƒ

Try it online!

Obviously a fork of Martin Ender's CJam answer.

Leaky Nun

Posted 2017-05-08T09:31:02.060

Reputation: 45 011

5

Python 3, 81 79 bytes

s='s=%r;print(s%%(s,round(%s*(1+5**.5)/2)))';print(s%(s,round(2*(1+5**.5)/2)))

Try it online!
Uses the golden ratio to calculate the next number

Rod

Posted 2017-05-08T09:31:02.060

Reputation: 17 588

4

Jelly, 14 bytes

“×Øp+.ḞṭØv”Ṙv2

Try it online! or verify all required iterations.

How it works

“×Øp+.ḞṭØv”Ṙv2  Main link. No arguments.

“×Øp+.ḞṭØv”     Set the left argument and return value to the string "×Øp+.ḞṭØv".
           Ṙ    Print a string representation of the return value and yield the
                unaltered return value.
            v2  Evaluate the return value as a Jelly program with left argument 2.
 ×Øp                Multiply the left argument by the golden ratio.
    +.              Add 0.5 to the resulting product.
      Ḟ             Floor; round the resulting sum down to the nearest integer.
        Øv          Yield the string "Øv".
       ṭ            Tack; append the result to the left to the result to the right.

Dennis

Posted 2017-05-08T09:31:02.060

Reputation: 196 637

1

Swift, 251 bytes

A bit verbose for me, but I can't figure out how to get it shorter:

import Foundation;var n="\"";var u="\\";var s="import Foundation;var n=%@%@%@%@;var u=%@%@%@%@;var s=%@%@%@;print(String(format:s,n,u,n,n,n,u,u,n,n,s,n,(round(%f*(1+sqrt(5))/2))))";print(String(format:s,n,u,n,n,n,u,u,n,n,s,n,(round(2*(1+sqrt(5))/2))))

Ungolfed:

import Foundation
var n="\""
var u="\\"
var s="import Foundation;var n=%@%@%@%@;var u=%@%@%@%@;var s=%@%@%@;print(String(format:s,n,u,n,n,n,u,u,n,n,s,n,(round(%f*(1+sqrt(5))/2))))"
print(String(format:s,n,u,n,n,n,u,u,n,n,s,n,(round(2*(1+sqrt(5))/2))))

My trouble is trying to get the quotes around the new version of s.

Caleb Kleveter

Posted 2017-05-08T09:31:02.060

Reputation: 647

1

Javascript (ES6), 151 60 bytes

New version, credits to @Leaky Nun

x=i=>console.log('x='+x+';x('+(i*(5**.5+1)/2+.5|0)+')');x(2)

Old version :

x=i=>{var s=Math.sqrt(5),a=1;f=n=>{return Math.ceil((((1+s)/2)**n-((1-s)/2)**n)/s)};while(f(++a)<=i);console.log('x='+String(x)+';x('+f(a)+')');};x(2)

Based on this.

rbntd

Posted 2017-05-08T09:31:02.060

Reputation: 111

1Welcome to PPCG! We hope that you will have a great time here. – Leaky Nun – 2017-05-08T14:56:46.013

@LeakyNun Hopefully fixed now ! – rbntd – 2017-05-08T15:15:54.690

Golfed version: x=i=>console.log('x='+x+';x('+(i*(5**.5+1)/2+.5|0)+')');x(2) – Leaky Nun – 2017-05-08T15:21:38.843

@LeakyNun wow, that's short ! But isn't it too approximate ? it outputs 50159 for i = 31000 although the right answer should be 46368 – rbntd – 2017-05-08T15:28:05.573

I don't understand. 31000 isn't a Fibonacci number. – Leaky Nun – 2017-05-08T15:31:44.787

@LeakyNun Yep, i think I misunderstood the question. I thought you needed to output the next Fibonnaci number greater than the input, whether the input is one or not. – rbntd – 2017-05-09T05:32:24.223

So you can use my suggestion now \o/ – Leaky Nun – 2017-05-09T05:33:55.623

1

Cheddar, 136 bytes

let b=1;for(let a=1;a<2;a=b-a){b+=a};let s='let b=1;for(let a=1;a<%i;a=b-a){b+=a};let s=%s;print s%b%@"39+s+@"39';print s%b%@"39+s+@"39

Try it online!

Leaky Nun

Posted 2017-05-08T09:31:02.060

Reputation: 45 011

1

dc, 35 bytes

2[r9k5v1+2/*.5+0k1/n91PP93P[dx]P]dx

A version with iteration (56 bytes):

2[rsP1dsN[lN+lNrsNdlP[s.q]s.=.lFx]dsFxlNn91PP93P[dx]P]dx

eush77

Posted 2017-05-08T09:31:02.060

Reputation: 1 280

1

Swift, 235 bytes

This is an improved version of Caleb's answer.

import Foundation;var n="\"",u="\\",s="import Foundation;var n=%@%@%@%@,u=%@%@%@%@,s=%@%@%@;print(String(format:s,n,u,n,n,n,u,u,n,n,s,n,(round(%f*(1+sqrt(5))/2))))";print(String(format:s,n,u,n,n,n,u,u,n,n,s,n,(round(2*(1+sqrt(5))/2))))

Nathan Piercy

Posted 2017-05-08T09:31:02.060

Reputation: 11

0

Java (OpenJDK 8), 239 bytes

interface a{static void main(String[]p){int a=1,b=1;for(;a<2;a=b-a)b+=a;String s="interface a{static void main(String[]p){int a=1,b=1;for(;a<%d;a=b-a)b+=a;String s=%c%s%c;System.out.printf(s,b,34,s,34);}}";System.out.printf(s,b,34,s,34);}}

Try it online!

Leaky Nun

Posted 2017-05-08T09:31:02.060

Reputation: 45 011