Python 2 / Retina, 550 + 645 = 1373 1254 1221 1195 байт
Я не зовсім впевнений , що якщо unichr
і replace
деталі можуть бути golfed більше. Я спробував використовувати Python 3, але багато чого втрачається, якщо потрібно додати круглі дужки та обробити їх. Я спробував налаштувати R=unicode.replace
та використати це, але вихід зіпсується.
Зауважте, що у Retina за замовчуванням є зворотний новий рядок, і це не включено до програм. Якщо хтось скаже, що мені потрібно його зняти, це можна зробити тривіально. Також код Python працює у repl.it, але не гарантується, що він працює на Ideone.com.
Також зауважте, що провідні та зворотні нові рядки є важливими у наведеному нижче коді.
Програма A (Python 2): 638 587 566 550 байт (UTF-8)
Пітон 2 , Сітківка
U=unichr;s=U(39)*3;_=u'''\n#U=unichr;s=U(39)*3;_=u%s.replace(U(9),U(96));print _%%(s+_+s).replace(U(10),U(92)+'n').replace(U(96),U(9)).replace(U(178),U(179)).replace(U(183),U(184)).replace(U(182),U(183))#|¶#·print"Wrong language!"·#?.*t|"·¶#{2}|^.¶\n#1 #\n\n#T ²-¹ _o [^¹]\nn=chr(10);print n+n.join(['print"Wrong language!"','#?.*t|"'])+n\n'''.replace(U(9),U(96));print _%(s+_+s).replace(U(10),U(92)+'n').replace(U(96),U(9)).replace(U(178),U(179)).replace(U(183),U(184)).replace(U(182),U(183))#|
#¶print"Wrong language!"¶#?.*t|"¶
#{2}|^.
Програма B (Retina): 735 667 655 645 байт (ISO 8859-1)
Сітківка , Python 2
#U=unichr;s=U(39)*3;_=u'''\n#U=unichr;s=U(39)*3;_=u%s.replace(U(9),U(96));print _%%(s+_+s).replace(U(10),U(92)+'n').replace(U(96),U(9)).replace(U(178),U(179)).replace(U(183),U(184)).replace(U(182),U(183))#|·#¸print"Wrong language!"¸#?.*t|"¸·#{2}|^.·\n#1 #\n\n#T ³-¹ _o [^¹]\nn=chr(10);print n+n.join(['print"Wrong language!"','#?.*t|"'])+n\n'''.replace(U(9),U(96));print _%(s+_+s).replace(U(10),U(92)+'n').replace(U(96),U(9)).replace(U(178),U(179)).replace(U(183),U(184)).replace(U(182),U(183))#|¶#·print"Wrong language!"·#?.*t|"·¶#{2}|^.¶
#1`#
#T`²-¹`_o`[^¹]
n=chr(10);print n+n.join(['print"Wrong language!"','#?.*t|"'])+n
Програма C:
Пітон 2 , Сітківка
Це насправді можна скоротити, використовуючи #!`W.*!
замість двох останніх рядків, але це робить A і B довше, тому що, якщо `
в рядку, де не було жодного, значить, мені потрібно по-іншому поводитись (тому що перший зворотний ряд у рядку в Retina є роздільником конфігурації).
print"Wrong language!"
#?.*t|"
Пояснення:
Програма C:
# Retina: replace nothing with the Python code string
print"Wrong language!" # >> code is executed if run in Python
#?.*t|" # Comment w/ '?' for Retina to skip, then replace up to the 't',
# as well as any quotation marks, with nothing
Я написав Програму С під час своєї першої спроби і зберіг її здебільшого. У Python він друкує рядок і ігнорує коментар. У Retina вона нічого не замінює, print"Wrong language!"
а потім видаляє частини навколо Wrong language!
.
Щоб краще зрозуміти складні програми, давайте розглянемо спрощені версії:
Програма A (спрощена):
print"\n#PYTHON\n#1`#\n\n#T`²-¹`_o`[^¹]\nn=chr(10);print n+n.join(['print"Wrong language!"','#?.*t|"'])+n\n"#|
#¶print"Wrong language!"¶#?.*t|"¶
#{2}|^.
Коли я почав з нуля, я використав PYTHON
біт як заповнювач для коду, який повинен надрукувати Програму А. Ця простіша версія спростила пояснення, як друкуються і Програма B, і Програма C.
print
І все всередині , що друкує програма B, але перший, давайте подивимося , як програма C друкується, тому що це просто. Після того, як print"..."
є #|
. Цей трюк врятував ЗАВАНТАЖЕННЯ труднощів, які я відчув у першій спробі. Це дозволяє Retina нічого не замінювати другим рядком, який буде Програмою C, за винятком того, що є #
спереду. Останні 2 рядки видаляють цей перший #
. Я використовував, #{2}
щоб запобігти видаленню всіх подій #
. Я не можу використовувати так, #1`#
як я використовував у програмі B, оскільки це призводить до проблем із тим, що цей зворотний зв'язок у першому рядку програми А.
Що підводить мене до мого наступного завдання, друкуючи програму B. Можливо, ви помітили ще одну відмінність від фактичного коду. У фактичному коді немає зворотних посилань, оскільки я замінив їх вкладками. Мені довелося замінити символ, тому що будь-який backtick зробить попередній код конфігураційним рядком у Retina, внаслідок чого синтаксис буде недійсним. Я вибрав вкладки, оскільки вони видимі, а точка коду - це одна цифра ( 9
). Код друкує програму B, як показано у спрощеній версії нижче.
Програма B:
#PYTHON
#1`#
#T`²-¹`_o`[^¹]
n=chr(10);print n+n.join(['print"Wrong language!"','#?.*t|"'])+n
Перші два рядки нічого не замінять кодом Python, але з #
передньою частиною та деякими символами трохи відрізняються. Ця частина опущена для наочності. Наступний етап знімає цей перший #
. Потім я використовую етап транслітерації (T) , #T`²-¹`_o`[^¹]
щоб скасувати деякі з replace
операцій бачили в повній програмі А. Використовуючи цей етап є способом виведення буквальний знак абзацу ¶
в сітківці, які в іншому випадку могли б бути impossible.¹ Він замінює ·
з ¶
, і ³
з ²
. Виникнення ¹
волевиявлення залишиться незмінним через їх ігнорування [^¹]
.
Програма A:
Нові рядки та вкладки додано для читабельності.
U=unichr;s=U(39)*3;
_=u'''
\n#U=unichr;s=U(39)*3;
_=u%s.replace(U(9),U(96));
print _%%(s+_+s)
.replace(U(10),U(92)+'n').replace(U(96),U(9)).replace(U(178),U(179))
.replace(U(183),U(184)).replace(U(182),U(183))#|
¶#·print"Wrong language!"·#?.*t|"·
¶#{2}|^.
¶
\n#1 #\n\n#T ²-¹ _o [^¹]\nn=chr(10);print n+n.join(['print"Wrong language!"','#?.*t|"'])+n\n'''
.replace(U(9),U(96));
print _%(s+_+s)
.replace(U(10),U(92)+'n').replace(U(96),U(9)).replace(U(178),U(179))
.replace(U(183),U(184)).replace(U(182),U(183))#|
#¶print"Wrong language!"¶#?.*t|"¶
#{2}|^.
Звідси випливає загальна структура наступної Python quine:
_='_=%r;print _%%_';print _%_
Коли ви додаєте речі до або після, ви також повинні вводити їх у рядок.
U=unichr;_='U=unichr;_=%r;print(_%%_).replace('','')';print(_%_).replace('','')
Я хотів використати потрійний котирування рядка, щоб полегшити включення лапок (уникаючи використання зворотних нахилів). s=U(39)*3;
- це рядок '''
. Я також використовував %s
замість цього %r
, щоб уникнути проблем з новими рядками чи іншими символами, які не виникають із зворотним нахилом.
U=unichr;s=U(39)*3;_='''U=unichr;s=U(39)*3;_=%s;print(s+_%%_+s).replace('','')''';print(s+_%_+s).replace('','')
Отже, тепер заміни. Перша заміна .replace(U(9),U(96));
полягає в заміні вкладок із задніми позначками, які ми бачимо в програмі B. Ця заміна проводиться перед форматуванням рядків, оскільки вкладки повинні залишатися вкладками в програмі А. Інші заміни - це просто уникнути використання певних символів у 2-й. рядок Програми B:
.replace(U(10),U(92)+'n') # Replace newlines with a backslash and 'n', for B to print A.
.replace(U(96),U(9)) # Replace backticks with tabs for the first part of B.
.replace(U(178),U(179)) # Replace '²' with '³', which will be undone with B's T stage
.replace(U(183),U(184)) # Replace '·' with '¸', which will be undone with B's T stage
.replace(U(182),U(183)) # Replace '¶' with '·', which will be undone with B's T stage
Ці три останні заміни передбачають етап транслітерації в програмі B, щоб запобігти видаленню або транслітерації цих символів, коли їх не повинно бути.
Єдиною іншою частиною коду є код програми B, який по суті є скопійованим символом для символу, за винятком змін, пов'язаних із замінами.
¹ Дякую Мартіну за пораду про те, як вивести літерал ¶
на Retina. Це все значно спростило.