7
\$\begingroup\$

Goal:

Write a function or program that, given an integer n, will output a program in the same language that is a quine with a period of n.

Description of Output Program:

The output program needs to be a program that, when run, ... will output a program... that will output a program... etc, until the nth program is the original (first) output program. So this is, in a way, a modular quine. That's how I think of it, anyway.

The resulting programs should all be distinct.

Example:

Input: 2

Program: modulus_quine(n)

Output: PQP → ...

Scoring:

This is , so shortest code (for the generating program) wins.

Brownie points (-0 bytes, +1 thumbs up?) are given to anyone whose generating program IS their modular quine. This is where your program takes the input and outputs the first modular quine in the sequence, which outputs the next, etc. The resulting output programs must not prompt the user for input (until it gets back to the generator.)

\$\endgroup\$
8
  • 1
    \$\begingroup\$ @vihan1086 Nope. This was discussed in the sandbox. Taking an input and generating the quine is completely different. The program you're golfing isn't required to be a quine, but is rather the generator program/function. \$\endgroup\$
    – mbomb007
    Jul 29, 2015 at 20:39
  • 4
    \$\begingroup\$ The answer to the previous question doesn't take much modification (I managed it with a Levenshtein distance of 7) to get an answer to this one. \$\endgroup\$ Jul 29, 2015 at 20:57
  • 2
    \$\begingroup\$ @PeterTaylor Good for you. Not everyone will find it so easy. Maybe try a different language. \$\endgroup\$
    – mbomb007
    Jul 29, 2015 at 21:49
  • 1
    \$\begingroup\$ Should the generator and the quine programs be in the same language? \$\endgroup\$
    – randomra
    Jul 29, 2015 at 21:59
  • \$\begingroup\$ @randomra Yes. Clarification added. \$\endgroup\$
    – mbomb007
    Jul 30, 2015 at 14:08

5 Answers 5

6
\$\begingroup\$

GolfScript, 16 bytes

{%}+")1$~":x`+0x

Try it online in Web GolfScript.

Example run

$ echo -n 3 | golfscript quining.gs      
{3 % ")1$~"}0)1$~
$ echo -n 3 | golfscript quining.gs | golfscript 
{3 % ")1$~"}1)1$~
$ echo -n 3 | golfscript quining.gs | golfscript | golfscript 
{3 % ")1$~"}2)1$~
$ echo -n 3 | golfscript quining.gs | golfscript | golfscript | golfscript 
{3 % ")1$~"}0)1$~

Generator

                 # (implicit) Read from STDIN.
{%}+             # Concatenate the read input with the block.
                 # For example, "3"{%}+ -> {3 %}.
    ")1$~":x     # Push that string and save it in the the variable `x'.
            `+   # Inspect the string and concatenate it with the block.
                 # For example, {3 %}'")1$~"'+ -> {3 % ")1$~"}
              0x # Push a 0 and the string stored in `x'.

Modular quine

For example, the modular quine {3 % ")1$~"}0)1$~ works as follows.

{          }      # Define a block.
 3 %              # Take the integer on the stack modulo 3.
     ")1$~"       # Push that string.
            0)    # Push 0 and increment. Pushes 1.
              1$~ # Copy the block from the bottom of the stack and execute it.

The original copy of the block, the modified integer and the string the block pushed are printed, resulting in {3 % ")1$~"}1)1$~.

All printed programs have a trailing linefeed, which GolfScript prints automatically.

\$\endgroup\$
1
  • \$\begingroup\$ {%}+")1$~":n`+0 would be one byte shorter, but the original output program would lack the trailing newline present in all subsequent output programs. \$\endgroup\$
    – Dennis
    Jul 30, 2015 at 14:39
3
\$\begingroup\$

Ruby, 100 bytes + brownie points

Generating program/zero-state:

;puts <<2.sub(/2*/){$&[/./]?$':?2*gets.to_i}*2,2
;puts <<2.sub(/2*/){$&[/./]?$':?2*gets.to_i}*2,2
2

Output for input of 3:

222;puts <<2.sub(/2*/){$&[/./]?$':?2*gets.to_i}*2,2
222;puts <<2.sub(/2*/){$&[/./]?$':?2*gets.to_i}*2,2
2

This program, when run, will not ask for input but output itself with the initial 222 on the first 2 rows replaced with 22. That will output a version where each row begins with 2, which will output the original program.

"2" lives a varied life here as (in order of appearance) a repeated digit in a no-op numeric literal, a HEREDOC reference, a regex literal, a character literal, a numeric argument to String#*, a numeric argument to puts, a character in a HEREDOC string, and finally a HEREDOC delimiter.

\$\endgroup\$
1
  • \$\begingroup\$ This is close, but not quite correct, since an input of 1 does not cause your program to print itself. Your program appends one too many 2s to the front of each of the first two lines for each n. \$\endgroup\$
    – mbomb007
    Jul 30, 2015 at 21:15
3
\$\begingroup\$

Underload, 29 bytes

(a(S)*)~^(a(:^)*)~*(^)*a(:^)*

Underload has no method to take input from the user, so I wrote a function rather than a complete program. The input is taken from the stack, the output is placed onto the stack (and can be printed with S).

Here's how to call it for an input of 1, ():

()(a(S)*)~^(a(:^)*)~*(^)*a(:^)*S

and it produces the following quine:

(a(:^)*a(S)*^):^

which runs like this:

(a(:^)*a(S)*^):^
(a(:^)*a(S)*^)(a(:^)*a(S)*^)^
(a(:^)*a(S)*^)a(:^)*a(S)*^
((a(:^)*a(S)*^))(:^)*a(S)*^
((a(:^)*a(S)*^):^)a(S)*^
(((a(:^)*a(S)*^):^))(S)*^
(((a(:^)*a(S)*^):^)S)^
((a(:^)*a(S)*^):^)S
program exits, with output (a(:^)*a(S)*^):^

As you can see, the modular quine of order 1 (i.e. just a normal quine) works by first generating a copy of itself, then generating a function to print that output, then running that function.

For higher orders, we just repeat the "generating a function to print that output" step (which is written in Underload as a(S)*). Here's how we call it for order 4 ((:::***) is 4):

(:::***)(a(S)*)~^(a(:^)*)~*(^)*a(:^)*S

Here's the program produced:

(a(:^)*a(S)*a(S)*a(S)*a(S)*^):^

which, when run, produces the following programs in turn:

((((a(:^)*a(S)*a(S)*a(S)*a(S)*^):^)S)S)S
(((a(:^)*a(S)*a(S)*a(S)*a(S)*^):^)S)S
((a(:^)*a(S)*a(S)*a(S)*a(S)*^):^)S
(a(:^)*a(S)*a(S)*a(S)*a(S)*^):^

The same technique probably works in other languages, although maybe not so concisely.

As a side note, Underload only has eight commands, so a hypothetical golfing version that represented each using 3 bits would use 29×3÷8 = 10⅞ bytes. That would make it the shortest solution here. Although it only has nine commands, one (()) uses two different characters, so the previous calculation isn't quite correct.

\$\endgroup\$
2
\$\begingroup\$

Python 3.8 (pre-release), 59 bytes

b=0;exec(s:=f"print('b=%d;exec(s:=%r)'%(-~b%{input()},s))")

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ You're right, my bad! \$\endgroup\$
    – Jitse
    Jan 27, 2020 at 14:53
2
\$\begingroup\$

Python 3.8 (pre-release), 54 bytes

a=f'a=%r,-~%d%%{input()};print(a[0]%%a)';exec(a%(a,0))

Try it online!

Let say input is 3 this will output :

a='a=%r,-~%d%%3;print(a[0]%%a)',-~1%3;print(a[0]%a)

which will output :

a='a=%r,-~%d%%3;print(a[0]%%a)',-~2%3;print(a[0]%a)

which will output :

a='a=%r,-~%d%%3;print(a[0]%%a)',-~0%3;print(a[0]%a)

... and so on

How it works :

This solution uses the same idea than an other solution of mine on an other challenge

The main idea is to modify the second element of the tuple a each iterration inside the string with '-~%d'%a. -~x corresponds to an incrementation of 1.

Then we loop using a modulo equal to our input (using f-string to replace it in the base program)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.