Самый длинный период итерации


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 байтам, чтобы вывести ваш исходный код.
  • Вы можете предположить, что ваша машина имеет бесконечную оперативную память и бесконечное время выполнения, но вы не можете предполагать, что типы данных с неограниченной точностью (например, целые числа), если у вашего языка их нет. Вы можете предположить, что нет ограничений на длину ввода, которую может обработать ваш парсер.
  • Самый высокий балл побеждает.

Обратите внимание: существует проблема, которая называется Quit Whining; Начните Quining, который также включает в себя итерацию Quines. Однако, помимо того, что они основаны на одной и той же концепции, это совершенно разные типы задач. Другой - прямой гольф, в то время как этот (намеренно!) Действительно замаскированная проблема бобра. Методы, необходимые для получения хорошего ответа на этот вопрос, вероятно, будут сильно отличаться от того, что необходимо для ответа на другой вопрос, и это очень сильно задумано.


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

Кто бы мог подумать, что это возможно в PHP ?! :-)

Это на самом деле мой первый в истории quine длиной 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 миллиарда.

Кредиты Дэйва , который разместил подход в псевдокоде в комментариях и на Боб Twells , от которого я скопированного кода для минимального 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

Mathematica, период 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, но не является ли это нарушением правил для квин - чтение его собственного исходного кода? ToString[#0, InputForm]
Даньеро

итак, просто 9 !!!! не работает? IDK Потому что у меня нет моей математики RPI со мной прямо сейчас.
Maltysen

@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 является наиболее вероятной, и существует множество способов, которые могут произойти, но ГСЧ допускает, чтобы период для 0 был длиннее периода для 311,5.


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

1
Согласно правилам: «Хорошо говорить что-то вроде« по крайней мере 1 000 000 итераций », а не указывать точное число». Так что, на мой взгляд, это «по крайней мере 1 итерация», потому что если нам действительно повезет с первой попытки ...;)
YetiCGN

В отличие от многих стандартных лазеек, таких как «Я мог бы генерировать какой-то случайный ввод, ответ есть», это действительно точное доказательство того, что точный ответ обязательно произойдет, и дана очень хорошая оценка. Ницца!
Андрей Костырка

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

Вывод этого не соответствует фактической программе (немного пробелов отсутствует). Кроме того, состояние не будет сохраняться между вызовами программы, поэтому период не будет точным числом и не будет постоянным
Джо Кинг,

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

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

Python 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)))гораздо больших чисел.
Барботер

Что значит пероид?
SS Anne


1
@Mukundan Я думаю, ты имеешь в виду период, но я не уверен. Я понимаю, что такое тетрация.
SS Anne

@SSAnne жаль, что это была опечатка, спасибо за указание на это
Мукундан

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.