Отвір 2 - Prime Quine


9

Знайдіть отвір 1 тут .

Зробіть quine, яка при запуску видає свій власний блок вихідного коду кілька разів. Фактично, він повинен виводити його n разів, де n у наступному простому числі.

Я думаю, що приклад це найкраще показує.

[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]

Кожна програма виводить свій базовий "блок" (таким чином, [МОЙ КВІТ]) наступне просте число разів.

Вбудовані функції для обчислення того, чи є число простим (як функція isPrime), або для визначення наступного простого (наприклад, функції nextPrime ()) не дозволяються.

  • Це означає, що функції переліку кількості дільників заборонені
  • Функції, що повертають основну факторизацію, також заборонені

Це має бути справжньою королевою (за винятком деякої свободи, див. Наступний пункт), тому не слід читати власний вихідний код.

Оскільки такі мови, як Java та C #, вже не вигідні, вам не потрібно виводити повністю працюючий код. Якщо це може бути введено у функцію (що називається) і вивести наступну quine, ви добре.

Це код-гольф, тому найкоротший код виграє!


Ніхто не відповів на отвір 1, і який бал отримують всі, хто відповідає на цю відповідь, за першу лунку?
Оптимізатор

1
Не могли б ви уточнити частину за допомогою простих функцій? Чи можемо ми їх використовувати чи не можемо ми ними не користуватися?
Мартін Ендер

3
Що вважається основною перевіркою, а що ні? Враховуючи, що основну перевірку можна побудувати за допомогою будь-якої лайки, якщо такий сорт, правила недостатньо зрозумілі
гордий haskeller

@Optimizer: Кожен має оцінку 0 за першу лунку, поки хтось не відповість на неї.
Стретч-маніяк

2
@StretchManiac Ви повинні чітко зазначити у питанні, що і список методів основної факторизації, і перелік методів ділення також не допускаються. Будь ласка, опублікуйте це питання в пісочниці наступного разу.
Оптимізатор

Відповіді:


5

CJam, 31 байт

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

Спробуйте його в Інтернеті в інтерпретаторі CJam .

Ідея

Для перевірки первинності ми будемо використовувати теорему Вілсона , яка стверджує, що ціле число n> 1 є простим тоді і лише тоді, коли (n - 1)! ≡ -1 (mod n) , що істинно, якщо і лише тоді, коли (n - 1)! + 1% n == 0 .

Код

{                           }_~ 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.

Як ви знайшли цей метод перевірки основного OO
оптимізатор

3
Згадане було б точніше. Це відома як теорема Вілсона.
Денніс

mp(це прем'єр?) існує зараз, тому в останній версії CJam можна було б трохи більше пограти.
Лінн

1
@Mauris Він існував у першій публічній версії, IIRC. Однак питання забороняє вбудовуватися в оператори прайму та факторизації.
Денніс

1

CJam, 36 35 байт

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

Це, безумовно, можна додатково гольфувати.

Як це працює:

{                               }_~   "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";

Дякую Мартіну, що нагадав мені ]W=трюк :)

Спробуйте його онлайн тут


1

Математика, 248 222 байти

Редагувати: виправлено використання функції, пов’язаної з основним режимом, але також трохи покращило квілінг.

Редагувати: Дякую Деннісу за те, що він познайомив мене з теоремою Вілсона.

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]

Це передбачає, що ядро ​​закривається між наступними запусками quine (або, принаймні n, скидається), оскільки воно покладається на nневизначення до [MyQuine]запуску першого примірника .

Це, ймовірно, може бути значно скорочено, але я не маю багато досвіду роботи з лайками, особливо в Mathematica.

Ось пояснення:

1;

Це нічого не робить, але якщо об'єднатись у кінець попередньої квинтини, вона множить результат останнього виразу на 1(що не відповідає) і крапка з комою придушує вихід. Це гарантує, що тільки остання копія [MyQuine]нічого не друкує.

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

Це инициализирует nдо 1в першій копії , [MyQuine]а потім збільшує його на 1кожній наступній копії - тобто це тільки підраховує , скільки копій є в n.

Пропустити вперед до кінця зараз:

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

Це знаходить наступний простір, використовуючи теорему Вілсона .

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

Це власне квітка. Він створює NextPrime@nкопії самого коду. Це теж трохи дивно. Так, я перемножую два рядки там, і жодна, яка не має значущого результату. QUINE_PREFIXмістить весь код перед двома рядками і QUINE_SUFFIXмістить увесь код після двох рядків. Зараз зазвичай ви використовуєте Apply(або @@) для перетворення списку в ряд аргументів. Але ви можете замінити будь-яке Headна Apply- наприклад, множення. Тому, незважаючи на те, що це продукт, я все ще можу перетворити його на два аргументи своєї функції. Ця функція виконує:

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

Де #перший аргумент (рядок префікса), #2другий аргумент (рядок суфікса), ##це послідовність обох аргументів. Мені потрібно заздалегідь 1зберегти множення - інакше ##було б потрапити до списку аргументів до ToString. У будь-якому випадку, ToString[1##,InputForm]&@@("abc"*"def")повертається "abc"*"def"... просто те, що мені потрібно!

Я думаю, що з усіма необхідними мені речами навколо лайки, evalтут більш доречним буде квітка, що базується. Я вивчу це пізніше чи завтра.


@ MartinBüttner питання слід відредагувати
гордий haskeller

Хе, я також можу використовувати Теорему Вілсона, щоб вирівняти свій запис нарівні з Денісом;)
Оптимізатор

@Optimizer Але в моєму випадку не було небезпеки когось образити, тому що я все ще використовую в 7 разів більше байтів, ніж ви двоє;)
Мартін Ендер

@ MartinBüttner Я знаю: D Ось чому я не користувався ним :)
Optimizer

0

J - 60 char

Використовує метод наступного прайму, як і інші відповіді. (Це 4 p:біт.)

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

Милий маленький трюк J - це те, що f :gдіє, fколи дається один аргумент, а gколи два. Отже, якщо ви виписуєте, скажіть, f :;'a'f :;'a'f :;'a'що це діє, як f'a';'a';'a'це чудово, тому що це список, який міститься у коробці, чиї елементи є, 'a'а довжина яких - кількість подій.

Тож ми можемо підняти це на справжню штуку. Використовуване fнами виглядає так (foo $~ bar), де fooбудується частина рядка, яку ми повторюємо знову і знову, barзнаходить наступне просте число і помножує його на 60, довжину рядка в 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

Чи можете ви змінити свій код, щоб відповідати новим специфікаціям? Методи, що виводять наступну просту, заборонені. Дякую.
Маніяк Стретч

0

Пітон 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)
#
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.