Hole 2 - Prime Quine

9

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!

Stretch Maniac

Posted 2014-10-15T11:29:09.943

Reputation: 3 971

No one answered hole 1, so what score does everyone answering this one get for the first hole ? – Optimizer – 2014-10-15T11:48:19.967

1Could you clarify the part with the prime functions? Can we use them or can we not use them? – Martin Ender – 2014-10-15T12:02:36.600

3What 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 – proud haskeller – 2014-10-15T12:09:55.910

@Optimizer: Everyone has a score of 0 for the first hole until someone answers it. – Stretch Maniac – 2014-10-15T21:38:40.777

@MartinBüttner modulo is fine, and in this case Divides would also be fine (sorry for the confusion). I am just excluding functions in which it outputs either a) the next prime or b) if a number is prime. – Stretch Maniac – 2014-10-15T21:53:08.607

@MartinBüttner That effectively tells you if a number is prime and is not allowed. Sorry. – Stretch Maniac – 2014-10-15T22:16:22.203

2@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. – Optimizer – 2014-10-16T05:29:42.893

Answers

5

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.

Dennis

Posted 2014-10-15T11:29:09.943

Reputation: 196 637

mp (is prime?) exists now, so in the latest version of CJam, one could golf this down a little more. – Lynn – 2015-08-22T05:08:02.767

1@Mauris It existed in the first public version, IIRC. However, the question forbids built in prime and factorization operators. – Dennis – 2015-08-22T05:09:57.810

How did you find that method of checking prime o.O – Optimizer – 2014-10-16T15:49:04.520

3Remembered would be more accurate. It's known as Wilson's theorem. – Dennis – 2014-10-16T16:06:14.620

1

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.

Martin Ender

Posted 2014-10-15T11:29:09.943

Reputation: 184 808

@MartinBüttner the question should be edited – proud haskeller – 2014-10-15T12:14:09.250

Heh, I can also use Wilson's Theorem to bring my entry at par with Denis' ;) – Optimizer – 2014-10-17T10:07:25.997

@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 ;) – Martin Ender – 2014-10-17T10:08:42.620

@MartinBüttner I know :D That is why I did not use it :) – Optimizer – 2014-10-17T10:09:28.187

1

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

Optimizer

Posted 2014-10-15T11:29:09.943

Reputation: 25 836

0

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

algorithmshark

Posted 2014-10-15T11:29:09.943

Reputation: 8 144

Could you modify your code to meet the new specs? Methods that output the next prime are not allowed. Thanks. – Stretch Maniac – 2014-10-16T22:22:44.283

0

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)
#

dieter

Posted 2014-10-15T11:29:09.943

Reputation: 2 010