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 code-golf, so shortest code in bytes wins!
-
1\$\begingroup\$ "Standard rules apply" - does that mean no reading the source code? \$\endgroup\$FlipTack– FlipTack2016年12月28日 20:47:29 +00:00Commented Dec 28, 2016 at 20:47
-
\$\begingroup\$ @FlipTack It does mean that - read the link for more information. \$\endgroup\$clismique– clismique2016年12月29日 14:35:28 +00:00Commented Dec 29, 2016 at 14:35
10 Answers 10
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.
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()!
-
\$\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– FlipTack2016年12月29日 14:45:21 +00:00Commented 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– Dennis2016年12月29日 17:27:18 +00:00Commented Dec 29, 2016 at 17:27
-
\$\begingroup\$ Ok :). I've added syntax highlighting for your post. Nice idea using threading! \$\endgroup\$FlipTack– FlipTack2016年12月29日 18:03:53 +00:00Commented Dec 29, 2016 at 18:03
-
\$\begingroup\$
import threading,inspect as ican beimport threading as T,inspect as i\$\endgroup\$nedla2004– nedla20042016年12月29日 18:12:47 +00:00Commented Dec 29, 2016 at 18:12 -
\$\begingroup\$ @nedla2004 Thank you for 3 less bytes ;) \$\endgroup\$Calconym– Calconym2016年12月29日 23:53:16 +00:00Commented Dec 29, 2016 at 23:53
CJam, 19 bytes
{]W=s"_~"+T):Te*}_~
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.
-
\$\begingroup\$ What... how... so fast... please explain the code, so you can teach me the ways of CJam. \$\endgroup\$clismique– clismique2016年12月28日 05:55:22 +00:00Commented Dec 28, 2016 at 5:55
-
\$\begingroup\$ @Qwerp-Derp I've added an explanation. \$\endgroup\$Dennis– Dennis2016年12月28日 06:00:10 +00:00Commented Dec 28, 2016 at 6:00
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...
-
\$\begingroup\$ Also, although
~["[%q]F01+`0=`.{0m}R"]F01+`0=`.{0m}Rworks fine in generally, it's not a valid solution, because there is no way to replicate the ZSS marker. \$\endgroup\$ATaco– ATaco2016年12月28日 06:23:35 +00:00Commented Dec 28, 2016 at 6:23
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.
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)#
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)#
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
}
CJam, 14 bytes
{s"_~"+]:.+}_~
Explanations
{s"_~"+]:.+}_~
{s"_~"+ }_~ Basic quine operator.
]:.+ Append each character to corresponding element of the previous result if existed.
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∑|_]`:Ė
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
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