Найдовший ітераційний квіточок


10

Як ми знаємо, quine - це програма, яка виводить власний вихідний код. Однак можливо також написати програму, яка виводить іншу, іншу програму, яка виводить першу програму знову. Наприклад, програма Python 2

x = '''x = {}
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3'''
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3

під час запуску виведе такий текст:

print """x = '''x = {}
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3'''
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3"""

Якщо запустити програму Python, це знову виведе початковий код. Це називається ітераційною квіточкою . Оскільки вам потрібно запустити його двічі, щоб повернути початковий код, ми кажемо, що у нього є період 2 . Але, звичайно, можливі набагато більш високі періоди.

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

Зверніть увагу на наступні правила та пояснення:

  • Застосовуються звичайні правила quine, тобто ваша програма не може використовувати мовні функції, які дозволять їй отримувати прямий доступ до власного вихідного коду.
  • Ітералізовані виходи повинні з часом повернутись до вашого оригінального коду, і ви повинні включити демонстрацію чи доказ того, що це буде.
  • Ви також повинні включити пояснення, чому цикл триває до тих пір, поки ви скажете, що це. Це не повинно бути на рівні математичного доказу, але це має бути переконливим для того, хто знайомий з вашою мовою. (Це правило є тут, тому що я очікую, що деякі відповіді включатимуть дуже-дуже велику кількість.)
  • Добре сказати щось на кшталт "принаймні 1 000 000 повторень", а не вказувати точну кількість, поки ви зможете довести, що це принаймні так довго. У цьому випадку ваш рахунок склав би 1 000 000. В іншому випадку ваш рахунок - це період вашої родини.
  • Обмеження 100 байт застосовується лише до вашої початкової програми - програми, які вона виводить, можуть бути довшими, хоча, звичайно, їм доведеться повернутися до 100 байт, щоб вивести свій вихідний код.
  • Ви можете припустити, що ваша машина має нескінченну оперативну пам’ять і нескінченний час виконання, але ви не можете припускати необмежену кількість типів даних точності (наприклад, цілі числа), якщо їх мова не має. Ви можете припустити, що немає обмеження в довжині вводу, з яким може працювати ваш аналізатор.
  • Виграє найвищий бал.

Зверніть увагу: існує існуюча проблема, яка називається " кинути ридання"; Почніть Квінінг, що також включає ітерацію лайків. Однак, окрім того, що вони базуються на одній і тій же концепції, це зовсім різні типи проблем. Інший - це гольф прямого коду, тоді як цей (навмисне!) Справді зайнятий проблемою бобра. Методи, необхідні для отримання гарної відповіді на це питання, ймовірно, сильно відрізняються від того, що потрібно для відповіді на інше питання, і це дуже сильно замислює.


1
@LeakyNun Я не знаю, чи це ви чи мод видалили вашу відповідь, але, можливо, якщо я поясню, що з цим було не так, ви зрозумієте, чому це не дублікат. Це питання визначає обмеження в 100 байт по довжині джерела, тому ви фактично не можете піднятися "так високо, як вам потрібно", використовуючи цей метод. В цьому і полягає вся суть цього питання. Щоб відповісти на це, що вам доведеться зробити, це опублікувати найдовшу версію, що вміщується в 100 символів, і сказати, який її період. Те, що ви опублікували, було б хорошою першою спробою, але малоймовірно, що воно буде переможцем.
Натаніел

1
@Перекладіть виклик саме в тому, щоб вказати велику кількість в невеликій кількості байтів, так. Це весь принцип, навколо якого він був розроблений. Питання в тому, чи 3 ^^^ 3 - це найбільше число, яке ви можете вказати в 100 байтах вашою мовою, чи є більша? Ось в чому полягає цей виклик. Це суть її. Це те, що я хотів бачити, як люди роблять. Це супер, супер фрустративно, щоб закрити його на основі поверхневої схожості на виклик, який не має нічого з цієї структури.
Натаніел

1
@Dave (другий коментар), але якщо ви розумні, вам зовсім не потрібно обмежуватись машинною точністю. Я б очікував, що конкурентоспроможні відповіді матимуть період, який значно більший за 2 ^ (2 ^ 64).
Натаніел

3
Тож ви хочете, щоб він був закритим як дублікат codegolf.stackexchange.com/q/18028/194 ?
Пітер Тейлор

1
@PeterTaylor - це набагато ближча тема, але це все ще зовсім інше завдання - друкувати номер зовсім інше, ніж робити щось велику кількість разів. Я, звичайно, вважаю за краще, щоб це взагалі не було закритим.
Натаніел

Відповіді:


10

PHP, період 2 100 000 000 000

Хто б міг подумати, що це можливо в PHP ?! :-)

Це насправді моя перша в світі квіта, і вона має 99 байт:

<?$i=1;$i*=21e8>$i;printf($a='<?$i=%d;$i*=21e8>$i;printf($a=%c%s%c,++$i,39,$a,39);',++$i,39,$a,39);

Хоча PHP підтримує більшу кількість, ніж 2 * 10^8при переході integerна double, збільшення не більше працює (призводить до нескінченного циклу), і я не знайшов іншого рішення, яке вписується в 100 байт. І все-таки.

Доведення досить просте, оскільки воно просто підраховує кожну ітерацію, поки не досягне точки скидання в 2,1 мільярда.

Кредити Дейву , який розмістив у коментарях підхід у псевдокоді та Боб Твеллсу , від якого я скопіював код для мінімальної квоти PHP.

Тестова програма (sloooooow):

<?php
$o = file_get_contents('quine.php');
for ($i = 0; $i < 22e8; $i++) {
    if ($i%2==0) exec('php q > p'); else exec('php p > q');
    $a = file_get_contents(($i%2==0) ? 'p' : 'q');
    echo "\r" . str_pad($i,6,' ') . ":\t$a";
    if ($a == $o) {
        die;
    }
}

Ну, принаймні я перший відповів.


1
Побічна примітка: це на порядку ~ 10 ^ 9.322219295.
LegionMammal978

8

Математика, період E8.5678 №3 E2.1923 # 4 ~ E6.2695 # 3 # 2

Print[ToString[#0, InputForm], "[", #1 - 1 /. 0 -> "Nest[#!,9,9^9^99!]", "]"] & [Nest[#!,9,9^9^99!]]

Зауважте, що бали описані в позначеннях Hyper-E . Ітерації замінюють фінал Nest[#!,9,9^9^99!]десятковими розширеннями Nest[#!,9,9^9^99!]- 1, Nest[#!,9,9^9^99!]- 2, Nest[#!,9,9^9^99!]- 3, ..., 3, 2, 1 і назад до Nest[#!,9,9^9^99!].


Чи не зростали б фабрики швидше?
Мальтісен

1
Я не знаю Mathematica, але чи це не порушення правил для quine - читання власного вихідного коду? ToString[#0, InputForm]
daniero

так, всього 9 !!!! не працює? idk, тому що у мене немає математики rpi зараз зі мною.
Мальтісен

@Maltysen Що обчислює подвійний факторіал подвійного факторіалу з дев'яти, або (9 !!) !! ≈ 2.116870635 · 10¹²⁰²
LegionMammal978

@daniero Я маю на увазі, ідея схожа на стандартний CJam {"_~"}_~, тому я гадаю, що він повинен бути дійсним ...
LegionMammal978

5

R, випадковий період з очікуванням 2 ^ 19936-0,5

f=function(){
    options(scipen=50)
    body(f)[[4]]<<-sum(runif(623))
    0
    cat("f=")
    print(f)
}

Генератор випадкових чисел за замовчуванням R має період 2 ^ 19937-1 та рівнорозподіл у 623 послідовних вимірах. Таким чином, десь (але лише один раз) у його період буде 623-довгий вектор нулів. Коли ми потрапимо туди (і вирівняємося з початком послідовності), сума наступних 623 випадкових чисел U [0,1] буде дорівнює нулю, і ми повернемося до нашої початкової програми.

Зауважте, що програма з дуже високою ймовірністю пройде через той самий ненульовий стан кілька разів перед поверненням до нуля. Наприклад, найвірогіднішою є сума 311,5, і існує дуже багато способів, але RNG дозволяє періоду на 0 бути більшим, ніж період 311,5.


Не впевнений, який рахунок ви хочете призначити цьому запису: P
JDL

1
Згідно з правилами: "Добре сказати щось на кшталт" принаймні 1 000 000 ітерацій ", а не вказувати точну цифру" Тож, на мою думку, це "принаймні 1 ітерація", тому що якщо ми з першої спроби отримаємо справжнє щастя ...;)
YetiCGN

На відміну від багатьох стандартних лазів, таких як "Я можу створити якийсь випадковий ввід, відповідь є", це дійсно акуратний доказ того, що точна відповідь має відбуватися, і дається дуже хороша оцінка. Приємно!
Андрей Костирка

1
Після того, як програма повернеться до свого базового стану один раз, тоді у неї буде випадковий період рівно 2 ^ 19937-1.
JDL

Вихід цього не відповідає дійсній програмі (не вистачає трохи пробілів). Також стан не зберігатиметься між програмними дзвінками, тому період не буде точним числом, а також не буде послідовним
Jo King

1

JavaScript, період 9,007,199,254,700,000

Не вигравати, але працювати із JavaScript над цим викликом було цікаво:

a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)

Дотримується наступного циклу:

a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254700000-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254699999-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254699998-1||90071992547e5)
// etc...
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),3-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),2-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254700000-1||90071992547e5)
// and so on

Примітка. Ви можете зробити це на 18 байт коротше, при цьому видаливши лише ~ 0,08% балу, як-от так:

a="a=%s;console.log(a,uneval(a),%.0f-1||9e15)";console.log(a,uneval(a),1-1||9e15)

1

C, період 2 100 000 000 000

unsigned long long i;main(a){i=1;i*=21e8>i;printf(a="ungisned long long i;main(a){i=%d;i*=21e8>i;printf(a=%c%s%2$c,++i,34,a);}",++i,34,a);}

Виходячи з відповіді PHP (очевидно). Оновлюсь із поясненням, коли встигну.



1

Пітон 2

Період: 9((99↑↑(9((99↑↑(9((99↑↑(9↑↑5-1))9)-1))9)-1))9)+1

Дякуємо @Bubbler за збільшення періоду від 99(99↑↑12)+1 до тепер

b=0;s="print'b=%d;s=%r;exec s'%(-~b%eval('9**9'*eval('9**9'*eval('9**9'*9**9**9**9**9))),s)";exec s

Спробуйте в Інтернеті!

У коді на b=0зміни , b=1то b=2і так далі , поки він не досягне b=decimal expansion of the periodпотім скидається назадb=0


1
9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9набагато вище, ніж 9**9**99**99**99**99**99**99**99**99**99**99**99**99. Це означає, що ви можете зробити щось на кшталт eval('9**9'*eval('9**9'*eval('9**9'*9**9**9**9**9)))набагато більших чисел.
Бубон

Що означає пероїд?
СС Енн


1
@Mukundan Я думаю, ти можеш означати період, але я не впевнений. Я розумію, що таке тетрація.
СС Енн

@SSAnne вибачте, що це була помилка, дякую, що вказали на це
Mukundan

0

Gol> <> , 70 байт, період 325883196621297064957600206175719056476804879488288708188003274919860959534770101079512433396348062803055739640225395758790852315876868469390603793729639715908136196505908165227136154287969475839017544811926036808089596209081885772040898530121921794489026069641113281250

Інші мудрі, відомі як справді великі (3.25E270)

":1=l8:*6+=S&Q~:'~'=Q~~'H#'||lPffXfX=?1:1=Q$~$~|:1)lPffXfX(Q?:|r2ssH##

Це насправді змінена версія відповіді, яку я поставив на ітератор 500 байтів

":1=l8:*6+=S&Q~:'~'=Q~~'H#'||//if last is equal to 1 and length is 71, delete the delete char, if the last char is '~', delete and push 'H#', which will later return to 'H##', completing the cycle!
lPffXfX=?1:1=Q$~$~|          //if length is equal to 15^15^15, then start delete process(append ascii one)
:1)lPffXfX(Q?:|              //if the last character is not 1 (the delete checker), and length is less than 15^15^15, duplicate the last value and append
r2ssH##                      //push the " to the front and output the whole thing

Сподіваюся, я правильно отримав рахунок, і помилок немає. Реального способу фактично обчислити це значення немає, воно теоретичне. Але людина, це величезна кількість !!!

Спробуйте в Інтернеті!

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