Множення на самомодифікацію


33

... принаймні для певного визначення поняття "самомодифікація".

Завдання

У цих проблемах, ваше завдання полягає в тому, щоб написати три рядки A, Bі Cякі задовольняють такі властивості.

  • Рядок Bмає довжину не менше 1.

  • Для кожного n ≥ 0рядка є дійсною програмою (що означає повну програму чи визначення функції) на обраній вами мові програмування. Індекс вказує повторення, тому це означає , що рядки , , , і т.д. Кожна програма займає один рядок в якості вхідних даних, і повертає один рядок в якості висновку.ABnCACABCABBCABBBC

  • Для будь-якого m, n ≥ 0, якщо програма запускається з введенням , вона повертається . Для входів, які не мають такої форми, програма може робити що завгодно, включаючи аварію.ABmCABnCABm*n+1C

Деякі приклади у форматі program(input) -> output:

AC(AC) -> ABC
ABC(AC) -> ABC
ABBBBBC(AC) -> ABC
AC(ABC) -> ABC
AC(ABBBBC) -> ABC
ABC(ABC) -> ABBC
ABBC(ABC) -> ABBBC
ABBBBC(ABBBC) -> ABBBBBBBBBBBBBC
ABBBC(ABBBBBBC) -> ABBBBBBBBBBBBBBBBBBBC

Правила та підрахунок балів

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

Стандартні лазівки заборонені. Програми не мають права прямого чи опосередкованого доступу до власного вихідного коду (за винятком випадків, коли вони надаються як вхідні дані). Ви повинні визначити рядки A, Bі Cв своїй відповіді в деякому роді, і закликав , щоб пояснити своє рішення.

Відповіді:


16

CJam, 9 8 байт

A: 1
B: 0
C:  r,(#0q

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

Як це працює

(ABcode) e# Push the integer 10 ** len(Bcode).
<SP>     e# Noop. Separates (AB) and C for input reading.
r        e# Read the first whitespace-separated token from STDIN (ABinput).
,(       e# Push the string length minus 1: len(Binput)
#        e# Power operator: 10 ** len(Bcode) len(Binput) # ->
         e#   (10 ** len(Bcode)) ** len(Binput) = 10 ** (len(Bcode) * len(Binput))
0        e# Push an additional 0 to complete len(Bcode) * len(Binput) + 1 zeroes.
q        e# Read the remaining input (C).

12

CJam, 15 13 11 байт

A: rl"
B: <SP>
C: <LF>",(*SNq

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

Як це працює

e# A

r     e# Read a whitespace-separated token from STDIN.
      e# This reads the input up to the first space, but does not consume it.
l     e# Read the rest of the first line from STDIN.
      e# This reads up to the first linefeed and consumes it.

"     e# Initiate a string.

e# B

<SP>  e# Fill the string with as many spaces as there are copies of B.

e# C

<LF>" e# Terminate the string with a linefeed.
      e# This serves as a delimiter for the `l' command.
,(    e# Compute the length of the string minus 1 (to account for the LF).
*     e# Repeat the string read by `l' that many times.
SN    e# Push a space and a linefeed.
q     e# Read the remaining input (i.e., the second line) from STDIN.

Зрештою, стек містить маркер, зчитуваний r, простір, що створюється *, пробіл та передачу SNліній, що висуваються, і рядки, прочитані q. CJam друкує все це автоматично.


Га, приємне використання цитат там: D
Оптимізатор

9

Піта, 10

A: w*\0hl*w[<newline>
B: 0
C: <empty>

Джерело розділимо на два рядки. Перший рядок - A, другий - Bs. Оскільки A знаходиться на першому рядку, перший wпросто друкує A - легко, зроблено.

У Pyth провідні нулі є окремими лексемами, так [00)насправді є [0, 0]. Зауважте, що перший рядок закінчується l[, а другий рядок складається з 0000.... Таким чином, l[насправді підраховується кількість B в цій програмі. Другий wчитається у другому рядку вводу - це кількість Bs вводу. Звідси це просте множення, збільшення та виведення, що має багато нулів.


9

Сітківка , 25 19 байт

A: ]\]<LF>
B: ]]
C: <LF>m`^]*$<LF>]$0]

<LF> stands for newline

Приклад ABCкоду:

]\]
]]
m`^]*$
]$0]

Код має два етапи заміщення:

  • змінити вхід AB^mCв AB^(m*n)Cзмінивши кожен Bна B^n:

    • ]\]відповідає кожному Bвхідних даних і нічого іншого завдяки втечі в рядках візерунка
    • ]]...]] є B^n
  • зміна B^(m*n)до B^(m*n+1)по

    • m`^]*$взявши лінію лише з ]'s
    • ]$0]додавши до нього додаткову пару ]]таким чином, щоб цей рядок не відповідав першому регулярному вираженню

Я додав до балу 3 байти для -sбагаторядкового прапора, який потрібен, щоб весь код Retina міг бути в одному файлі.

2 байти збережено завдяки @ MartinBüttner.


8

Python 3, 51 байт

A: lambda s:s[:28]+"x"*(1+len("
B: x
C: ")*(len(s)-51))+s[-23:]

Приклад використання:

>>> f=lambda s:s[:28]+"x"*(1+len("xx")*(len(s)-51))+s[-23:]
>>> f('lambda s:s[:28]+"x"*(1+len("xxx")*(len(s)-51))+s[-23:]')
'lambda s:s[:28]+"x"*(1+len("xxxxxxx")*(len(s)-51))+s[-23:]'

Функція обчислює n*m+1з , (1+len("xxx")*(len(s)-51))де є m x«и в рядку ( xxxчастина є B^m). Помноження рядка "x"на це число дає, B^(n*m+1)і функція приймає Aі Cвиводить із вхідних даних і об'єднує все це для отримання AB^(n*m+1)C.

Той самий підхід у J:

J, 35 байт

A: (19{.]),('x'#~1+(#'
B: x
C: ')*35-~#),_16{.]

5

CJam, 22

A:<empty>
B:{])`\,q,K/(*))*"_~"}
C:{])`\,q,K/(*))*"_~"}_~

Приклад виконання:

ABBC(ABC) -> ABBBC

що перекладається на

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

з введенням як

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

який дає такий вихід:

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

Як це працює :

Давайте подивимось, які програми ACі ABCяк виглядають:

AC :{])`\,q,K/(*))*"_~"}_~
ABC:{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

Ми помічаємо, що C=B_~

Давайте подивимось, що Bробить:

{])`\,q,K/(*))*"_~"}

{                  }    e# This is a code block. Alone, this does nothing except
                        e# pushing this block to stack as is
 ]                      e# Wrap everything on stack in an array
  )`                    e# Take out the last part and convert it to its string representation
    \,                  e# Take length of remaining array
      q,K/              e# Read the input, take its length and int divide by K (i.e. 20)
          (*            e# Decrement and multiply by the array length on stack
            ))          e# Add two to the product
              *         e# Repeat the string representation on stack that many times
               "_~"     e# Put this string on stack

Тепер давайте подивимось, що буде працювати ACбез будь-якого вводу:

{])`\,q,K/(*))*"_~"}_~                      e# Copy the block and run it
{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}~   e# Block is copied, run it
{      ...         } ])                     e# Wrapped array has the block in it.
                       `\,                  e# Stringify it and take length of remaining = 0
                          q,K/              e# No input so 0
                              (*))          e# 0 * -1 = 0. 0 + 2 = 2
                                  *         e# Repeat the stringified block 2 times:
                                            e# "{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}"
                                   "_~"     e# Put this string. Program ends, so print stack:
                                            e# {])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

Нічого собі, вихід є ABC.

Ми в основному підраховуємо, скільки Bіснує в коді. Тоді скільки вхідних даних (використовуючи довжину). Помножте їх, збільшуючи вдвічі (оскільки Cтакож є B) і додайте _~до отриманняC

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


3

Haskell , 50 байт

fце прийняття та повернення функції String.

Рядок B - це просто один пробіл, а C починається з одного.

A:_:b="
B: 
C: ";f s|a:c<-words s=unwords$a:(drop 50s>>b):c

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

  • _:b=" "присвоює всі, окрім першого, пробілів у рядковій літералі b, роблячи це рівним копіям m B програми.
  • s- це рядок введення. a:c<-words sрозбиває його на слова, розділені пробілом, так що aстає A і cстає списком слів, що містять C. Копії B ігноруються, оскільки wordsвидавлюється декілька пробілів (чого уникає решта програми).
  • drop 50s- рядок, довжина якої дорівнює кількості n копій B на вході. drop 50s>>bоб'єднує багато копій b, даючи mn пробіли.
  • unwords$a:(drop 50s>>b):cз'єднує всі рядки назад разом з пробілами. Оскільки (drop 50s>>b)в списку вставлено додаткове "слово" , також є додаткове місце приєднання, яке автоматично додає +1 до множення.

2

Матлаб, 85

Перший раз я зробив такий абстрактний виклик, тому для мене це був скоріше виклик кодування, ніж виклик коду-гольфу!

Три рядки без лапок:

A:    "X=strsplit(input('','s'));m=0 "
B:    "+1 "
C:    ";[X{1},32,repmat(['+1',32],1,m*(length(X)-2)+1),X{end}]"

Як це працює: Я розділив вхідний аргумент на пробіл, такn його можна визначити за кількістю частин рядків. B працює як свого роду лічильник, щоб отримати m. Для реконструкції відповіді я використовую A і C з розбиття, повторюю B m * n + 1 раз, і я вставляю пробіли, використовуючи їх значення ASCII, щоб у C. не виникало небажаних розщеплень.

EDIT: ну, випадково порахував A + B


1

C (gcc) , 81 байт

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

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

A: m;f(char*s){m=strrchr(s+66,32)-s-65;printf("%.66s%*s",s,m*strlen("
B: <SPACE>
C: ")+16,s+m+66);}

За ідентифікації я просто мав в виду , що це повинно бути ясно з вашої відповіді , який фрагменти коду A , B і C . Це не вимога до програми.
Згарб

1

TI-Basic (83 серія), 65 байт

Сегмент А (33 байти):

Input Str1:sub(Str1,1,27:For(I,0,(length(Str1)-55)(length("

Сегмент B:

X

Сегмент C (32 байти):

Y")-1:Ans+"X":End:Ans+sub(Str1,length(Str1)-27,28

Мені дуже подобається знайти це завдання, подібне до квіточка! Більшість лайків не працюють у TI-Basic без принаймні невеликого обману, оскільки немає можливості уникнути "символу. (В обох сенсах слова "втеча".) Але тут ми отримуємо вхідний рядок за допомогою Inputкоманди, і вводити "там ідеально добре.

Тут ще існує деяка кількість дуріння TI-Basic, щоб не обійтися: порожня рядок недійсна, тому наївне рішення вставити рядок "XXX...XX"у цикл не буде працювати, коли n = 0. Натомість ми вручну обчислюємо значення mn + 1 і вставляємо рядок, "X"що багато разів.

Постійні магічні 27і 28в програмі, трохи не від підрахунку байт 33 і 32, бо Str1, sub(іlength( два байта маркери , які тільки сприяють 1 до довжини струни.

Якщо ми використовуємо нові рядки замість :, виглядає, коли можна зберегти кілька байт, залишивши кінцеві лапки, але це насправді не працює. Перш за все, вам потрібен шістнадцятковий редактор, перш ніж ви зможете додати символ рядка до рядка: ви не можете просто ввести його, тому що якщо натиснути ENTER під час Inputкоманди, він подає введення. Коли я спробував підходити шестигранний редактор, у мене з’явилася дивна помилка переповнення буфера, яка змінила вміст моєї програми, тому не спробуйте цього вдома зі своїм дорогим калькулятором.


0

Java 11, 135 65 + 26 = 91 байт

А

s->{var p=s.split("\\(\"|\"\\.");return p[0]+"(\"B"+p[1].repeat("

Б

B

С

".length())+'"'+'.'+p[2];}

Спробуйте його онлайн тут (у TIO ще немає Java 11, тому це покладається на допоміжний метод замість String::repeat()).

Безголівки:

s -> { // lambda taking and returning a String
    var p = s.split("\\(\"|\"\\."); // split input into parts A, B^n, C (where n may be 0) at the "(\"" and "\"."
    return p[0] + "(\"B" + // put it back together: A plus the part the split shaved off, plus an extra B ...
    p[1].repeat("BBB".length()) + // ... plus B^(n*m)
    '"' + '.' + p[2]; // plus C, with the part the split shaved off reattached
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.