Напишіть найдовший ітераційний проміжок, обмежений 500 байтами


16

Ваше завдання - створити найдовший ітераційний період , коли довжина кожної програми в послідовності обмежена 500 байтами.

Тобто, якщо ви повторите такі кроки:

  1. Почніть зі своєї початкової програми
  2. Запустіть поточну програму
  3. Поверніться до кроку 2

Ви з часом повернетесь до своєї початкової програми. Кількість програм у циклі - це ваша оцінка, яку ви намагаєтеся максимально збільшити.

Жодна з програм не може призвести до помилок. Кожну програму також слід запускати однаково (наприклад, відсутні різні версії, реалізації, параметри компілятора, платформи тощо) (EDIT: Так, будь-який зовнішній стан, такий як генератор псевдо випадкових чисел, був включений в останню заява. Зовнішній стан повинен бути "скинутий" після кожного запуску. Якщо ви використовуєте справжні випадкові числа, передбачається найгірший випадок.)

Що відрізняє цей виклик від найдовшого ітераційного квита (крім 100 проти 500), це те, що кожна програма в циклі також повинна бути 500 байт або менше. Це означає, що найдовший можливий цикл становить (256 ^ 501 - 1) / 255 або менше. Звичайно, це велика кількість, але не така велика з точки зору того, скільки коду потрібно обчислити. Таким чином, завдання полягає у використанні якомога більшої кількості можливостей (256 ^ 501 - 1) / 255, а не зайнятого бобра.

Програми не мають доступу до власного вихідного коду. Проте порожня програма буде дозволена , якщо ви хочете ( до тих пір , поки ви будете слідувати іншим правилам).

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

Це , тому найвищий бал виграє!

EDIT: Рекомендується написати наукову номенклатуру, щоб відповіді були легше порівняти. Цілком чудово мати й інші форми партитури, особливо якщо вони більш чітко підключені до вашої програми. Також читачам рекомендується редагувати попередні відповіді, щоб виконати це.


2
"найдовший можливий цикл (256 ^ 501 - 1) / 255 або менше" --- це не обов'язково вірно, програма може проходити через один і той же стан кілька разів, перш ніж повернутися до початкового, якщо вона маніпулює зовнішнім об'єктом ( наприклад, держава або насіння РНГ)
JDL

2
@JDL, що має суперечити правилам, IMHO - якщо він зберігає стан в іншому місці, ніж у вихідному коді, то це не є належною ітераційною лінією.
Натаніел

1
@Nathaniel Я б не відносив його до зберігання стану в іншому місці, він просто використовує вхідні точки, які є дійсною частиною мови програмування, в яку реалізовано. Можливо, все, що викликає іншу функцію в мові програмування - це доступ до станів, які зберігаються поза власний вихідний код.
JDL

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

3
@JDL, як я впевнений, ви знаєте, детермінованою мовою вказівник інструкції зберігає стан лише під час виконання програми, а не між викликами її. Ваш 5-державний приклад неможливий, якщо вихід програми є детермінованою функцією його джерела.
Натаніел

Відповіді:


12

Perl 6 , 1263988,86×10835 ітерацій

$!=Q~~;<say "\$!=Q~{chrs(my@a=[R,] polymod :126[$!.ords]+1: 126 xx*)x?(@a-399)}~;<$_>~~.EVAL">~~.EVAL

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

Це повторює всі можливі комбінації перших 126 байт довжиною 398 і нижче (виключаючи рядки з провідними байтами NUL). Якщо ви хочете побачити, що він фактично повертається до першої ітерації, ви можете зменшити довжину до 1, змінивши подібний межа .

Пояснення:

Кожна ітерація збільшує рядок, що зберігається в базовій формі 126, а потім перетворює її назад в базу 126. Це робиться до тих пір, поки не досягне рядка довжиною 399, а потім скидає рядок назад до порожнього знову. Якщо у вас виникають проблеми з концептуалізацією числа, уявіть це замість цього десяти байтів. Починаючи з 0, збільшуйте до 4 цифр 1000та скидайте. Це 1041 ітерацій (включаючи 0або порожній рядок у випадку моєї програми).

$!=Q~~;         # Start with an empty string
< ... >~~.EVAL  # Set a string to $_ and EVAL it
  say "\$!=Q~{...}~;<$_>~~.EVAL"   # Print the program with the string replaced by
                       :126[$!.ords]   # The string converted from base 126
                                    +1 # Incremented
          [R,] polymod                : 126 xx*  # Back to base 126
chrs(                                )  # Back to a string
     my@a=                            x?(@a-399)  # Only if it isn't 399 characters

1
Нічого собі, ти зробив це дуже швидко, я майже закінчував свою, але я, мабуть, закінчую її завтра (моя буде в Голі> <>)
KrystosTheOverlord

Цей підрахунок говорить про те, що ви перевершили свій результат. Чисельник - це кількість рядків довжиною 397, використовуючи 126 символів. (Мені довелося розподілити дріб на суму, оскільки вольфрам альфа діяв дивно.)
PyRulez

@PyRulez Я думаю, що мій номер правильний, оскільки в основному це повторення базового 126 числа до 399 цифр ... Я думаю, що моє пояснення було вимкнено
Jo King

@JoKing ах, так, я думаю, що пояснення було проблемою. Ви змінили 397 на 398, що робить ваш рахунок вже не завищеним. Ви, можливо, недооцінюєте це (оскільки в бал ви включили лише рядки довжиною рівно 398), але це добре.
PyRulez

2

Рунічні чари , 64654 106 ; 122 387 -1 ≈ 2.638 × 10 807 ітерацій

"3X4+kSq'ƃZ,r{1?{1[:1Z%1+:a=+:d=+:3X4+=+:6X2+=+:'€(c*?~1-1kq}͍f1+0Bl1=6*?S1-Skql͗2=4*?{͍]}B͍l1=6*?kS1-Sq]}@

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

Попередження: неправильно відображається, він повинен бути `` (0x80).

Замість того, щоб стек, використовуйте рядок і оператори стека, модифіковані за допомогою, ͍щоб змінити рядок, а не стек (див. Попередню редакцію). Таким чином, кожен знак обмежений 1 байтом (діапазон 0-127, мінус проблемні символи), але з більш ніж 3-кратною кількістю їх (через те, що оброблювальна плита менше обробляється через те, що не потрібно пропускати Unicode, що поєднує символи, як як і деякі інші байтові заощадження) вона досягає більшої кількості ітерацій.

Якщо дозволено кодування як справжнього великого ендіана (тобто, маючи значення байтів понад 127 без втручання 0x00байтів), це може досягти 251 387 -1 ≈ 4.717 × 10 928 ітерацій. Однак латинське кодування TIO перешкоджає цьому, як зазначає Ерік Випереджальний у своїй відповіді Python 2. Мені потрібно перевірити, чи працює він локально, перш ніж вимагати цей бал.

Мав би бути в змозі замінити f1+0Bна '0B(там є роздруківка 0x16), але він боровся зі мною (речі не хотіли розгалужувати / пропускати / повертати правильно), тому я залишив це в спокої. Це призвело б до підняття структури з великого ендіану з 387 до 388.


1

DOS COM, 49 байт, період 2 ^ 3608

00000000  be 31 01 89 f7 b9 f4 02  f9 ac 14 00 aa 39 ce 72  |.1...........9.r|
00000010  f8 31 c9 b4 3c ba 2b 01  cd 21 89 c3 b4 40 b9 f4  |.1..<.+..!...@..|
00000020  01 ba 00 01 cd 21 b4 3e  cd 21 c3 71 2e 63 6f 6d  |.....!.>.!.q.com|
00000030  00                                                |.|

Оригінальна збірка для створення:

 BITS 16
 ORG 0100h
   mov si, l
   mov di, si
   mov cx, 500 + 0100h
   stc
n: lodsb
   adc al, 0
   stosb
   cmp si, cx
   jb n
   xor cx, cx
   mov ah, 3ch
   mov dx, f
   int 21h
   mov bx, ax
   mov ah, 40h
   mov cx, 500
   mov dx, 0100h
   int 21h
   mov ah, 3eh
   int 21h
   ret
f: db "q.com", 0
l: db 0

Ця маленька коштовність записує наступну фазу на q.com, а не на стандартний вихід через нулі та інші речі, якими термінал не може впоратися. Техніка кореневої квінки еквівалентна стратифікації, і кімната корисної навантаження використовується як лічильник 3608 біт. Завдяки тому, як працює DOS, початковий стан лічильника містить сміття з того, що було в пам’яті до його першого виконання.

Оригінальний 49-байтний вхід недоступний, тому, якщо ви хочете отримати це, так як 500 байтів йти вперед.


1

C # (Visual C # Interactive Compiler) , прапори: /u:System.Numerics.BigIntegerі/r:System.Numerics

Оцінка: 10 332

Завдяки JoKing, який збільшив мою оцінку з 10 255 * 2 - 1 дотепер!

var i=Parse("0");var s="var i=Parse({0}{2}{0});var s={0}{1}{0};Write(s,(char)34,s,(++i).ToString().Length<333?i:0);";Write(s,(char)34,s,(++i).ToString().Length<333?i:0);

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

Пояснення

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

//The BigInteger that will be incremented
var i=Parse("0");
//The string that encodes the quine
var s="var i=Parse({0}{2}{0});var s={0}{1}{0};Write(s,(char)34,s,(++i).ToString().Length<333?i:0);";
//Print out the string, with every {0} replaced with quotes and the {1} replaced with the original string
Write(s,(char)34,s,
//And the {2} is replaced to the BigInteger+1 if the BigInteger wouldn't be too long, else 0
(++i).ToString().Length<333?i:0);

1

252219

#coding=L1
s=""""""
for i in range(220-len(s.lstrip("ÿ")))[:219]:s=s[:i]+chr(ord(s[i])%255-~(s[i]in"!$&"))+s[i+1:]
S='#coding=L1\ns="""%s"""\nfor i in range(220-len(s.lstrip("\xff")))[:219]:s=s[:i]+chr(ord(s[i])%%%%255-~(s[i]in"!$&"))+s[i+1:]\nS=%%r;print S%%%%s%%%%S';print S%s%S

Зауважте, що існує зворотний новий рядок. Він може бути видалений вище, якщо підсвітка синтаксису пробивається в нього.

На жаль, ви не можете виконати цю програму в TIO, оскільки вона закодована в Latin-1.

Вище sмістить 219 0x01 байт. Після запуску програми її джерело друкується, за винятком однієї різниці: sзбільшується, як номер базового 252 з великим ендіанієм, тому його крайній лівий символ "збільшується" до 0x02. Байти 0x00, 0x22, 0x25 і 0x5C уникають, тому, якщо будь-який символ рядка стає одним із таких після збільшення, сам символ знову збільшується.

  • 0x00 (null): вихідний файл Python не може містити нульових символів.
  • 0x22 ( "): існує небезпека утворення трьох байтів 0x22 підряд, тобто""" , або стає останній символ рядка ", тому рядок буде закрито передчасно.
  • 0x25 ( %): форматування рядків у формі printf використовується перед завершенням скелета quine, тому %не є сусіднім з іншим %вs може спричинити проблеми. На жаль, змінити форматування неможливо, щоб уникнути цього застереження.
  • 0x5C ( \): Існує ймовірність, що \в рядок замість дословного символу використовується як знак втечі, тому його уникають.

Тому 252 з 256 байт є корисними. Якщо sмістить 219 0xFF ( ÿ) байт, він просто повертається до 219 0x01 байт, отже, завершується цикл.

252219

252219=8067118401622543607173815381864126969021321378412714150085501148172081568355283332551767558738710128769977220628694979838777041634307806013053042518663967641130129748108465109552157004184441957823830340121790768004370530578658229253323149648902557120331892465175873053680188287802536817909195292338112618632542000472094347226540339409672851252596442228662174845397731175044304251123874046626291460659909127172435776359148724655575878680270692451120531744950544969860952702932354413767504109600742385916705785109741289800204288


1

2512262.1×10542

  • 251 39 усунено залежність відText
  • 251 122 приріст функцій для гольфу
  • 251 128 комбінованих рядків-префіксів та суфіксів
  • 251 188 знято залежність відGast.GenLibTest

Представлено у форматі xxd через недруковані / недійсні UTF-8:

00000000: 6d6f 6475 6c65 2071 3b69 6d70 6f72 7420  module q;import 
00000010: 5374 6445 6e76 3b53 7461 7274 3d28 7325  StdEnv;Start=(s%
00000020: 2830 2c34 3129 2c3f 5b27 0101 0101 0101  (0,41),?['......
00000030: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000040: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000050: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000060: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000070: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000080: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000090: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000a0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000b0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000c0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000d0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000e0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000f0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000100: 0101 0101 0101 0101 0101 0101 275d 2c73  ............'],s
00000110: 2528 3432 2c39 3939 292c 712c 732c 7129  %(42,999),q,s,q)
00000120: 3b71 3d69 6e63 2721 273b 3f5b 683a 745d  ;q=inc'!';?[h:t]
00000130: 2363 3d68 2b69 6628 616e 7928 283d 3d29  #c=h+if(any((==)
00000140: 6829 5b27 ff09 0c26 5b27 5d29 2702 2727  h)['...&['])'.''
00000150: 0127 3d5b 633a 6966 2863 3e68 2969 643f  .'=[c:if(c>h)id?
00000160: 745d 3b3f 653d 653b 733d 226d 6f64 756c  t];?e=e;s="modul
00000170: 6520 713b 696d 706f 7274 2053 7464 456e  e q;import StdEn
00000180: 763b 5374 6172 743d 2873 2528 302c 3431  v;Start=(s%(0,41
00000190: 292c 3f5b 2727 5d2c 7325 2834 322c 3939  ),?[''],s%(42,99
000001a0: 3929 2c71 2c73 2c71 293b 713d 696e 6327  9),q,s,q);q=inc'
000001b0: 2127 3b3f 5b68 3a74 5d23 633d 682b 6966  !';?[h:t]#c=h+if
000001c0: 2861 6e79 2828 3d3d 2968 295b 27ff 090c  (any((==)h)['...
000001d0: 265b 275d 2927 0227 2701 273d 5b63 3a69  &['])'.''.'=[c:i
000001e0: 6628 633e 6829 6964 3f74 5d3b 3f65 3d65  f(c>h)id?t];?e=e
000001f0: 3b73 3d22                                ;s="

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

Прирощує 226-байтове рядок через все значення байт за винятком \0, \n, \r, 'і \.

Причиною, чому ми уникаємо цих символів, є:

  • \0 змушує компілятора гніватися
  • \nі \rне може відображатись у списках
  • ' закінчився б список
  • \ може спричинити проблеми, якщо мова йде про характер, який може швидко переходити

Після того, як рядок буде все \377, вона завертається до всіх\001 s, даючи оригінальну програму.


Вихід (принаймні на TIO) - символ із порядковим значенням 128, але складається з двох байтів C2 80. Це те саме, що поведінка на вашій локальній машині?
Джо Кінг,

1
@JoKing О, ні, я отримую один байт на своїй машині. TIO манглями виводиться, коли він недійсний UTF-8 (і файли введення теж).
Οurous

1
@JoKing Я змінив відповідь на новий формат, який дозволяє побачити правильну поведінку в TIO.
Οurous

0

Gol> <> , 70 байт, 39039000 ітерацій

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

Нічого собі, це набагато нижче, ніж я думав, що це буде ... Наступний крок! Це зробить більше ітерацій !!!

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


не здається нічого видалити, як тільки він досягне 500, просто додає байт NUL
Джо Кінг,

Це взагалі працює? Я не можу примусити "збільшити останній чар" для роботи
лише ASCII,

@ ASCII-тільки Тепер це працює, вибачте про це, я переплутав розділ, працюючи над виправленням усієї справи. Працює зараз, вибачте за незручності !!!
KrystosTheOverlord

@JoKing Байт NUL - це процес видалення, тепер програма повинна видалити, поки вона майже не зникне, потім видаліть NUL і збільшить останній знак, якщо він є ~, то він буде перетворений на '#', повернувшись назад до нормального !!!
KrystosTheOverlord
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.