Challenge: A Self-Replicating App

William Lancee

Well-Known Member
Licensed User
Longtime User
@aeric Thank you for the link. That was my sentiment exactly. My early experience with this phenomenon was in 1971. Also I love Hofstadter's book, I am looking at now on my shelf.

I just finished reading the material in the link. Fascinating!
 
Last edited:

sorex

Expert
Licensed User
Longtime User
I handled the double quote in inelegant way by using Replace.

you could save a line if you used the QUOTE constant ;)

in case the readers didn't notice yet my routine even uses some sort of iteration to make it work :)
in the long line the same call is used again to feed data.
 

aeric

Expert
Licensed User
Longtime User
@aeric Thank you for the link. That was my sentiment exactly. My early experience with this phenomenon was in 1971. Also I love Hofstadter's book, I am looking at now on my shelf.

I just finished reading the material in the link. Fascinating!
I didn't read all the page. :p I just refer to the sample given and get the idea. Thanks for introducing this concept as a quiz. I found it interesting and just tried out.
 

aeric

Expert
Licensed User
Longtime User
you could save a line if you used the QUOTE constant ;)

in case the readers didn't notice yet my routine even uses some sort of iteration to make it work :)
in the long line the same call is used again to feed data.
Ya, I believe my code can be improved further. It was 1am when I feel boring with my project and I saw this thread. I almost gave up when I can't figure out the quotation marks. I run my code, copy the Textarea content into another test window, and B4J immediately highlight the read lines. That time around 5am i just decided to use some tricks to make it works (at least once).

In fact, if you copy the textarea content again from the second compile, it is not working! ?
 

sorex

Expert
Licensed User
Longtime User
yeah, that's the hard part of it. you need to do the run>copy>paste>run 2 or 3 times to be sure it's working right.
 

William Lancee

Well-Known Member
Licensed User
Longtime User
Thank you @udg @sorex @aeric for participating. I certainly enjoyed seeing how you did it. I also learned from the link @aeric posted

https://en.wikipedia.org/wiki/Quine_(computing)

that this is a well-known puzzle, solved in most programming languages - now it is solved in B4X!

If you read the Wiki article, you'll find a Java program that outputs a C++ program that outputs the original Java program.

This feat has an official name: "ouroboros programs" or "quine-relays".
 

sorex

Expert
Licensed User
Longtime User
I had a look at the page and see some simularities in William's & @aeric 's code. Both of you use this kind of chunck copying loops like in the article.
 

William Lancee

Well-Known Member
Licensed User
Longtime User
This my last word on this topic. I thought that if anyone looks at this thread in the future, they may be interested in a streamlined version that is able to replicate on B4A and B4J and then it will run on either platform. It is also transparent enough to be understood by all.

B4X:
Sub Process_Globals
    Private sb(3) As StringBuilder
    Private startName As String = "Activity_Create(FirstTime As Boolean)"
End Sub
#if B4J
Sub AppStart (Form1 As Form, Args() As String)
    startName = "AppStart (Form1 As Form, Args() As String)"
#else if B4A
Sub Globals
End Sub
Sub Activity_Create(FirstTime As Boolean)
#end if
    sb(0).initialize: sb(1).initialize: sb(2).initialize
    toLines(0, "Sub Process_Globals")
    toLines(0, "    Private sb(3) As StringBuilder")
    toLines(0, "    Private startName As String = 'Activity_Create(FirstTime As Boolean)'")
    toLines(0, "End Sub")
    toLines(0, "#if B4J")
    toLines(0, "Sub AppStart (Form1 As Form, Args() As String)")
    toLines(0, "    startName = 'AppStart (Form1 As Form, Args() As String)'")
    toLines(0, "#else if B4A")
    toLines(0, "Sub Globals")
    toLines(0, "End Sub")
    toLines(0, "Sub Activity_Create(FirstTime As Boolean)")
    toLines(0, "#end if")
    toLines(0, "    sb(0).initialize: sb(1).initialize: sb(2).initialize")
    toLines(2, "    Log(sb(0).Append(sb(1).ToString).Append(sb(2).toString).toString)")
    toLines(2, "End Sub")
    toLines(2, "Sub toLines(i As Int, s As String)")
    toLines(2, "    If i = 0 Then s = s.Replace('*', startName)")
    toLines(2, "    sb(i).Append(s.Replace(Chr(39), QUOTE) & CRLF)")
    toLines(2, "    sb(1).Append(TAB & 'toLines(' & i & ', ' & QUOTE & s & QUOTE & ')' & CRLF)")
    toLines(2, "End Sub")
    Log(sb(0).Append(sb(1).ToString).Append(sb(2).toString).toString)
End Sub
Sub toLines(i As Int, s As String)
    If i = 0 Then s = s.Replace("*", startName)
    sb(i).Append(s.Replace(Chr(39), QUOTE) & CRLF)
    sb(1).Append(TAB & "toLines(" & i & ", " & QUOTE & s & QUOTE & ")" & CRLF)
End Sub
 
Top