10
\$\begingroup\$

Find Hole 1 here.

Make a quine that, when run, outputs its own source code block multiple times. In fact, it must output it n times, where n in the next prime number.

I think an example shows it best.

[MY QUINE][MY QUINE]
[MY QUINE][MY QUINE][MY QUINE]
[MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE]
[MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE]
[MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE][MY QUINE]

Each Program will output its base "block" (so [MY QUINE]) the next prime number times.

Built in functions to calculate whether a number is prime, (like an isPrime function), or to determine the next prime (like a nextPrime() function) are not allowed.

  • This means that functions to list the number of divisors is not allowed
  • Functions that return the prime factorization are likewise disallowed

This should be a true quine (except for some leeway, see next point), so you should not read your own source code.

Because languages like Java and C# are already at a disadvantage, You need not output totally working code. If it could be put in a function (that is called) and output the next quine, you are good.

This is code-golf, so shortest code wins!

\$\endgroup\$
7
  • \$\begingroup\$ No one answered hole 1, so what score does everyone answering this one get for the first hole ? \$\endgroup\$
    – Optimizer
    Commented Oct 15, 2014 at 11:48
  • 1
    \$\begingroup\$ Could you clarify the part with the prime functions? Can we use them or can we not use them? \$\endgroup\$ Commented Oct 15, 2014 at 12:02
  • 3
    \$\begingroup\$ What is considered prime checking and what is not? Considering that prime checking can be built using any quine if this sort, the rules are not clear enough \$\endgroup\$ Commented Oct 15, 2014 at 12:09
  • \$\begingroup\$ @Optimizer: Everyone has a score of 0 for the first hole until someone answers it. \$\endgroup\$ Commented Oct 15, 2014 at 21:38
  • 2
    \$\begingroup\$ @StretchManiac You should clearly mention in the question that both list of prime factorization methods and list of divisors methods are also not allowed. Please post the question in the Sandbox next time. \$\endgroup\$
    – Optimizer
    Commented Oct 16, 2014 at 5:29

5 Answers 5

5
\$\begingroup\$

CJam, 31 bytes

{'_'~]-3>U):U{)__,1>:*)\%}g*}_~

Try it online in the CJam interpreter.

Idea

To check for primality, we'll use Wilson's theorem, which states that an integer n > 1 is prime if and only if (n - 1)! ≡ -1 (mod n), which is true if and only if (n - 1)! + 1 % n == 0.

Code

{                           }_~ e# Define a block and execute a copy.
                                e# The original block will be on top of the stack.
 '_'~]                          e# Push those characters and wrap the stack in an array.
      -3>                       e# Keep only the last three elements (QUINE).
         U):U                   e# Increment U (initially 0).
             {           }g     e# Do-while loop:
              )__               e# Increment the integer I on the stack (initially U).
                 ,1>            e#   Push [1 ... I-1].
                    :*          e#   Multiply all to push factorial(I-1).
                      )\%       e#   Push factorial(I-1) + 1 % I.
                                e# While the result is non-zero, repeat.
                                e# This pushes the next prime after U.
                           *    e# Repeat QUINE that many times.
\$\endgroup\$
4
  • \$\begingroup\$ How did you find that method of checking prime o.O \$\endgroup\$
    – Optimizer
    Commented Oct 16, 2014 at 15:49
  • 3
    \$\begingroup\$ Remembered would be more accurate. It's known as Wilson's theorem. \$\endgroup\$
    – Dennis
    Commented Oct 16, 2014 at 16:06
  • \$\begingroup\$ mp (is prime?) exists now, so in the latest version of CJam, one could golf this down a little more. \$\endgroup\$
    – lynn
    Commented Aug 22, 2015 at 5:08
  • 1
    \$\begingroup\$ @Mauris It existed in the first public version, IIRC. However, the question forbids built in prime and factorization operators. \$\endgroup\$
    – Dennis
    Commented Aug 22, 2015 at 5:09
1
\$\begingroup\$

CJam, 36 35 bytes

{]W="_~"]U):U{)_,{)1$\%!},,2>}g*}_~

This can definitely be golfed further.

How it works:

{                               }_~   "Copy this code block and execute the copy";
 ]W=                                  "Take just the last element from the stack";
                                      "The other thing on stack is the block from above";
    "_~"]                             "Put "_~" on stack and wrap the 2 things in an array";
                                      "At this point, the string representation of stack"
                                      "elements is identical to the source code";
         U):U                         "Increment U and update U's value. This  variable"
                                      "actually counts the number of [Quine] blocks";
             {)_,{)1$\%!},,2>}g       "Find the next prime number"
                               *      "Repeat the array that many times, thus repeat the"
                                      "[Quine] block, the next prime times";

Thanks to Martin for reminding me the ]W= trick :)

Try it online here

\$\endgroup\$
0
1
\$\begingroup\$

Mathematica, 248 222 bytes

Edit: Fixed the usage of a prime-related function, but also improved the quining a bit.

Edit: Thanks to Dennis for introducing me to Wilson's theorem.

1;n=If[ValueQ@n,n+1,1];StringJoin@Array[#<>ToString[1##,InputForm]<>#2&@@\("1;n=If[ValueQ@n,n+1,1];StringJoin@Array[#<>ToString[1##,InputForm]<>#\2&@@("*"&,For[i=n,Mod[++i!/i+1,i]>0,0];i]")&,For[i=n,Mod[++i!/i+1,i]>0,0];i]

This assumes that the kernel is quit between subsequent runs of the quine (or at least n is reset), because it relies on n being undefined before the first instance of [MyQuine] is run.

This can probably be shortened a lot, but I don't have a lot of experience with quines, especially in Mathematica.

Here is an explanation:

1;

This doesn't do anything, but if concatenated onto the end of the previous quine, it multiplies the result of the last expression by 1 (which is a no-op) and the semicolon suppresses output. This ensures that only the last copy of [MyQuine] prints anything.

n=If[ValueQ@n,n+1,1];

This initialises n to 1 in the first copy of [MyQuine] and then increments it by 1 in each further copy - i.e. this just counts how many copies there are in n.

Skip ahead to the end now:

For[i=n,Mod[++i!/i+1,i]>0,0];i

This finds the next prime using Wilson's theorem.

StringJoin@Array[#<>ToString[1##,InputForm]<>#2&@@\("QUINE_PREFIX"*"QUINE_SUFFIX")&,NEXTPRIME[n]]

This is the actual quine. It creates NextPrime@n copies of the code itself. It's also a bit weird. Yes, I'm multiplying two strings there, and no that doesn't have a meaningful result. QUINE_PREFIX contains all the code before the two strings and QUINE_SUFFIX contains all the code after the two strings. Now usually you use Apply (or @@) to turn a list into a series of arguments. But you can replace any Head with Apply - e.g. multiplication. So despite this being a product I can still turn it into into two arguments to my function. That function does:

#<>ToString[1##,InputForm]<>#2

Where # is the first argument (the prefix string), #2 is the second argument (the suffix string), ## is a sequence of both arguments. I need to prepend 1 to preserve the multiplication - otherwise ## would splat into the argument list to ToString. Anyway, ToString[1##,InputForm]&@@("abc"*"def") returns "abc"*"def"... just what I need!

I think with all the stuff I need around the quine, an eval-based quine would be more appropriate here. I'll look into that later or tomorrow.

\$\endgroup\$
4
  • \$\begingroup\$ @MartinBüttner the question should be edited \$\endgroup\$ Commented Oct 15, 2014 at 12:14
  • \$\begingroup\$ Heh, I can also use Wilson's Theorem to bring my entry at par with Denis' ;) \$\endgroup\$
    – Optimizer
    Commented Oct 17, 2014 at 10:07
  • \$\begingroup\$ @Optimizer But in my case there was no danger of offending anyone because I'm still using 7 times as many bytes as the two of you ;) \$\endgroup\$ Commented Oct 17, 2014 at 10:08
  • \$\begingroup\$ @MartinBüttner I know :D That is why I did not use it :) \$\endgroup\$
    – Optimizer
    Commented Oct 17, 2014 at 10:09
0
\$\begingroup\$

J - 60 char

Uses the next-prime method like the other answers. (That's the 4 p: bit.)

((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''

A cute little J trick is that f :g acts like f when given one argument and g when given two. So, if you write out, say f :;'a'f :;'a'f :;'a' then that acts like f'a';'a';'a', which is great because that's a boxed list whose items are 'a' and whose length is the number of occurrences.

So we can lift that into a quiney sort of thing. The f we use looks like (foo $~ bar), where foo constructs the string part that we repeat over and over, bar finds the next prime number and multiplies it by 60, the length of the string in foo.

   ((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
   # ((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
180
   ((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
   # ((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''((58&$,2#{:)@;$~60*4 p:#) :;'((58&$,2#{:)@;$~60*4 p:#) :;'''
300
\$\endgroup\$
1
  • \$\begingroup\$ Could you modify your code to meet the new specs? Methods that output the next prime are not allowed. Thanks. \$\endgroup\$ Commented Oct 16, 2014 at 22:22
0
\$\begingroup\$

Python 2.7, 214

from sys import*;R,s=range,chr(35)
def N(n):
 if n<3:return n+1
 for p in R(n+1,n+n):
    for i in R(2, p):
     if p%i==0:break
     else:return p
P=file(argv[0]).read();print(P.split(s)[0]+s)*N(P.count(chr(37)));exit(0)
#
\$\endgroup\$

Your Answer

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

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