19
\$\begingroup\$

Your task is to create a program that, when run, returns itself as output (this is known as a quine). However, this quine must, when it is copied n times, returns the quine, but with each of its characters duplicated in place n times, where n is a positive integer.

If your original program is Derp:

Derp -> Derp (must return itself as output to be a quine)

DerpDerp -> DDeerrpp
(the "Derp" is copied twice, so each character in the output has to be copied twice)

DerpDerpDerp -> DDDeeerrrppp
etc. etc.

Keep in mind you're allowed to have whitespace in your "base" program, but they are counted when "interweaving". Say your program is

Derp 
{newline}

(The newline signifies a trailing newline, and there's an extra space after the Derp). When duplicated to become

Derp 
Derp 
{newline}

You must output

DDeerrpp  
{newline}
{newline}

Keep in mind that there's 2 extra spaces after the DDeerrpp.

Rules and Specs:

  • Your program must contain at least two distinct characters (which implies that your code must be at least 2 bytes long).
  • Standard quine rules apply.

This is , so shortest code in bytes wins!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ "Standard rules apply" - does that mean no reading the source code? \$\endgroup\$
    – FlipTack
    Dec 28, 2016 at 20:47
  • \$\begingroup\$ @FlipTack It does mean that - read the link for more information. \$\endgroup\$
    – clismique
    Dec 29, 2016 at 14:35

10 Answers 10

17
\$\begingroup\$

Fission, 6 bytes

'!+OR"

Try it online! Try two copies! Try three!

Explanation

This is just the Fission standard quine. It happens to work for this challenge, because Fission has explicit entry points into the program. In particular, by duplicating the program, we add another R which adds another atom (instruction pointer). Since the source code is toroidal, the effective code being executed doesn't change otherwise — to each atom, the code still looks the same locally. However, the atoms are executed in lock step, so that the things they print are interleaved and we get an additional copy of each character in the output.

For completeness' sake I'll just shortly reiterate how the program itself works. Regardless of whether we repeat the program or not (e.g. '!+OR"'!+OR"'!+OR"), each atom sees the following code:

R"'!+OR"'!+O

The " toggles string printing mode, so that the program starts by printing '!+OR directly to STDOUT, which is all of the quine except the quote. Then '! sets the atom's mass to the character code of !, + increments it, which gives ", and O prints it while simultaneously destroying the atom. The program then terminates, because there are no atoms left.

\$\endgroup\$
12
\$\begingroup\$

Python 2.7, 377 310 304 194 191 bytes!

This is my first golf, so I didn't expect it to be too good. But I thought the concept in the solution I came up with was somewhat funny, so I'm posting it anyway.

def f():
 import threading as T,inspect as i;global t,a,i
 try:t.cancel()
 except:a=0
 a+=1;t=T.Timer(1,d);t.start()
def d():print''.join(c*a for c in i.getsource(f)+i.getsource(d)+"f()")
f()

Indeed, this is a quine; you can try it here. It abuses the inspect module pretty hard.

If we try running it with the same source code x2, we get the right output as well; you can try that here. x3, x4, etc. all work as expected.

Ungolfed with explanation:

def f():                                   # Defines a central function f
    import threading as T,inspect as i     # Imports threading and inspect
    global t,a,i                           # Global vars
    try:
        t.cancel()                         # Tries to cancel Timer from previous code
    except:
        a = 0                              # Reached when code is 1st copy; initializes a.
    a += 1                                 # a++; this is the number of copies thus far.
    t = T.Timer(1,d)               # Creates, then starts a timer to call function
    t.start()                              # d in 1 second.

def d():                                   # Prints out the source code; the quine part.
    print''.join(c*a for c in i.getsource(f)+i.getsource(d)+"f()")

f()                                        # Calls f()!
\$\endgroup\$
6
  • \$\begingroup\$ Isn't this a cheating quine, as it reads the source code of its own functions using inspect? (see relevant meta post). On PPCG we have specific definitions of what makes a quine valid, and 'reading the source' is usually regarded as cheating. \$\endgroup\$
    – FlipTack
    Dec 29, 2016 at 14:45
  • 1
    \$\begingroup\$ @FlipTack I'm not sure inspecting a function is the same as reading the source code. Quines in JavaScript and stack-based languages do this all the time. \$\endgroup\$
    – Dennis
    Dec 29, 2016 at 17:27
  • \$\begingroup\$ Ok :). I've added syntax highlighting for your post. Nice idea using threading! \$\endgroup\$
    – FlipTack
    Dec 29, 2016 at 18:03
  • \$\begingroup\$ import threading,inspect as i can be import threading as T,inspect as i \$\endgroup\$
    – nedla2004
    Dec 29, 2016 at 18:12
  • \$\begingroup\$ @FlipTack Oops, thank you. \$\endgroup\$
    – Calconym
    Dec 29, 2016 at 23:48
3
\$\begingroup\$

CJam, 19 bytes

{]W=s"_~"+T):Te*}_~

Try it online!

How it works

{               }_~  Define an anonymous code block (function).
                 _~  Push a copy, and execute the copy.
 ]W=                 Wrap the entire stack in an array and select its last element.
                     This discards whatever was on the stack before the original
                     code block, which is needed for subsequent iterations.
    s"_~"+           Cast the code block to string, push "_~", and concatenate.
                     This pushes the stringified source code on the stack.
          T):T       Push T (initially 0), increment it, and save the result in T.
              e*     Repeat each character in the stringified source code T times.
\$\endgroup\$
2
  • \$\begingroup\$ What... how... so fast... please explain the code, so you can teach me the ways of CJam. \$\endgroup\$
    – clismique
    Dec 28, 2016 at 5:55
  • \$\begingroup\$ @Qwerp-Derp I've added an explanation. \$\endgroup\$
    – Dennis
    Dec 28, 2016 at 6:00
3
\$\begingroup\$

RProgN, 66 bytes

Significant Whitespace be the death of me

[ "[ %q ] F 0 1 + `0 = `. { 0 m } R " ] F 0 1 + `0 = `. { 0 m } R 

Explained

[ "[ %q ] F 0 1 + `0 = `. { 0 m } R " ] F 0 1 + `0 = `. { 0 m } R   #
[                                                                   # Pop whatever is already on the stack, if anything.
  "[ %q ] F 0 1 + `0 = `. { 0 m } R "                               # This string contains basically the entire function.
                                      ] F                           # ] F duplicates the string, and then F formats it, which in this case puts the first string into the second at %q, surrounded by qoutes.
                                          0 1 + `0 =                # I needed an Incrementer, so I chose 0. 0, is conveniently, pre initilized at 0. And because RProgN is horrifying, you can remap the number functions as they're just more variables. So this increments 0 every time the group is called.
                                                     `. { 0 m } R   # Replace each character with itself repeated '0' times. Because '0' is an incrementer, each time the script is called, the amount of times the characters are repeated increase.

Good lord I'm a monster...

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Also, although ~["[%q]F01+`0=`.{0m}R"]F01+`0=`.{0m}R works fine in generally, it's not a valid solution, because there is no way to replicate the ZSS marker. \$\endgroup\$
    – ATaco
    Dec 28, 2016 at 6:23
3
\$\begingroup\$

Python 3, 122 121 112 bytes

s='try:from atexit import*;n+=1\nexcept:n=1;register(lambda:[print(end=c*n)for c in"s=%r;exec(s);"%s])';exec(s);

Try It Online: one copy | two copies | three copies | four copies, with automatic verification

How it works

This uses the standard Python quine: Store the code you want to execute in a variable (as a string); include some logic in that string to print itself, everything before it, and everything after it; then execute that string.

The code that is executed via the string s is the following.

try:from atexit import*;n+=1
except:n=1;register(lambda:[print(end=c*n)for c in"s=%r;exec(s);"%s])

The first line unconditionally imports the atexit module, which will allow us to register an exit handler. Trying to import the same module multiple times doesn't affect the script in any way. Then it tries to increment the variable n, to keep track of how many copies of the source code were executed.

The second line is executed only if the first one contains an error. This will be the case in the first iteration, since n is still undefined. In this case, we initialize n as 1 and register a lambda that performs the actual magic.

The registered exit handler

lambda:[print(end=c*n)for c in"s=%r;exec(s);"%s]

will be called right before the program finishes. The lambda itself creates the string "s=%r;exec(s);"%s%r creates a string representation of the right argument (s), which includes everything between the single quotes and the quotes themselves – then iterates over its characters. For each character c, we simply print n copies of c. Passing c*n as the named argument end to print means that no linefeed will be appended.

\$\endgroup\$
3
\$\begingroup\$

Python 3.8 (pre-release), 68 bytes

for c in(s:='for c in(s:=%r)%%s:\n print(end=c)#')%s:
 print(end=c)#

Try it online!

How it works:

  • Based on the quine print((s:='print((s:=%r)%%s)')%s)
  • when repeated multiple time, the code become something like:
for c in "string for the quine":
 print(end=c)#comment
 print(end=c)#comment
 print(end=c)#
\$\endgroup\$
2
\$\begingroup\$

Perl 5, 107 bytes

$_=q[$_=q[S];s/S/$_/;$a++;END{s/./$&x$a/eg;print if$a;$a=0}];s/S/$_/;$a++;END{s/./$&x$a/eg;print if$a;$a=0}

Ungolfed:

$_ = '...INSERT_SOURCE_HERE...';      # Standard quine
s/INSERT_SOURCE_HERE/$_;
$a++;                                 # Count the number of repetitions
END {
    s/./$&x$a/eg;                     # Interweave
    print if $a;                      # Print...
    $a=0;                             # ...but only once
}

Try it online!

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

CJam, 14 bytes

{s"_~"+]:.+}_~

Try it online!

Explanations

{s"_~"+]:.+}_~
{s"_~"+    }_~ Basic quine operator.
       ]:.+    Append each character to corresponding element of the previous result if existed.
\$\endgroup\$
1
\$\begingroup\$

Vyxal D, 18 bytes

`£_›:¥q\`:Ė\`+•`:Ė

Try it Online! | Try it Double! | Try it x5!

`              `:Ė # Evaluate the following piece of code on itself:
 £                 # Store (itself) to the register
  _                # Pop
                   # The previous copy (if there is one) will've left its code on top of the stack; we don't want that, so we pop it
                   # This exposes the counter to the top of stack
   ›:              # Increment the counter
     ¥             # Push the code
      q            # Unevaluate (stringify) it
       \`:Ė\`+     # Append an eval (this is the quine bit)
              •    # Repeat each character (counter) times
                   # Now [counter, output] is left on the stack

Vyxal D, 25 bytes

`q\`:Ė\`+$:["21/÷Y∑|_]`:Ė

Try it Online!

A quite neat solution that interleaves its code with the previous iteration

`                     `:Ė # Evaluate on itself...
 q\`:Ė\`+                 # Quine part - uneval, append code to eval
         $                # Get the previous code
          :[              # If it exists (There's a copy of the code before it)
            "21/          # Divide each into 21 pieces
                ÷Y        # Interleave them
                  ∑       # Summate
                   |_]    # Else (If this is the first copy) pop (the 0 on top) leaving the source 
\$\endgroup\$
1
\$\begingroup\$

Vyxal D, 8 bytes

`I!•`I!•

Try it Online! | Try it Online!Try it Online! | Try it Online!Try it Online!Try it Online!

Explanation

`I!•`    # push `I!•` to the stack => [ I!• ]
     I   # quote and prepend => [ `I!•`I!• ] 
      !  # push the len of the stack => [ `I!•`I!• , 1 ]
       • # duplicate each char of the string by => [ `I!•`I!• ]
         # implicit output

# each time the program repeat, the length of the stack increment and the end become :

      !  # push the len of the stack => [ `I!•`I!• , `I!•`I!• , 2 ]
       • # duplicate each char of the string by => [ `I!•`I!• , ``II!!••``II!!•• ]
         # implicit output the top element of the stack

Vyxal D, 11 bytes

`q‛:Ė+!•`:Ė

Try it Online! | Try it Online!Try it Online! | Try it Online!Try it Online!Try it Online!

Explanation :

`q‛:Ė+!•`   # push `q‛:Ė+!•` to the stack => [ q‛:Ė+!• ]
         :  # duplicate the element on top of the stack => [ q‛:Ė+!• , q‛:Ė+!• ]
          Ė # pop and execute the element on top of the stack => [ q‛:Ė+!• ]
 q          # quote => [ `q‛:Ė+!•` ]
  ‛:Ė+      # add `:Ė` to the top of the stack =>  [ `q‛:Ė+!•`:Ė ]
      !     # push the len of the stack => [ `q‛:Ė+!•`:Ė , 1 ]
       •    # multiply each char by => [ `q‛:Ė+!•`:Ė ]
            # implicit output

# each time the program repeat, the length of the stack increment and the end become :

      !     # push the len of the stack => [ `q‛:Ė+!•`:Ė , `q‛:Ė+!•`:Ė , 2 ]
       •    # multiply each char by => [ `q‛:Ė+!•`:Ė , ``qq‛‛::ĖĖ++!!••``::ĖĖ ]
            # implicit output
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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