Тюрінг-повний перекладач мови


42

Проблема, яку я вважав, що це було б дуже класно, - це зробити перекладача для мови, яку ви вибрали цілком Тюрінг .

Правила прості:

  1. Ви можете використовувати будь-яку мову для створення цього перекладача, навіть якщо він є новішим, ніж цей виклик.
  2. Ви можете використовувати будь-яку мову, повну Тьюрінга, до тих пір, поки вона не є тією, якою ви пишете на ній.
  3. Ви можете не просто оцінити код, наприклад, використовувати функції eval.
  4. Пояснення того, як ви підійшли до цього, буде приємним, але не обов'язковим.
  5. Це буде оцінено в байтах.
  6. Кожне подання повинно бути повноцінним, що означає, що кожна функція, яку має обрана вами мова, повинна бути присутнім.

Простіше кажучи:

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

Удачі!


3
Я також рекомендую правило, згідно з яким реалізована мова повинна відрізнятися від мови, якою ви користуєтесь для її реалізації, щоб запобігти тривіальним evalрішенням.
ETHproductions

1
Насправді, ви можете просто заборонити evalкоманди / функції, оскільки деякі мови мають вбудовані модулі для оцінки коду на іншій мові.
ETHproductions

2
@arodebaugh Для майбутніх викликів ви можете опублікувати свою ідею в пісочниці, де ви зможете отримати зворотній зв'язок та вияснити подібні деталі, перш ніж виклики перейдуть до життя та отримаєте відповідь.
Мартін Ендер

1
Гаразд, ви, напевно, повинні бути трохи більш конкретними і сказати щось на кшталт "Ви не можете просто виконувати код будь-яким методом", щоб уникнути інших тривіальних відповідей, таких як Bash + perl.
ETHproductions

Відповіді:


16

Брахілог (2) → Поставити проблему листування , 9 байт

~h=∋ᵐ\cᵐ=

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

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

Програма у посиланні TIO вище - це [["a","baa"],["ab","aa"],["bba","bb"]], яку я скопіював із Вікіпедії. Рішення (яке програма знаходить досить швидко) є ["bbaabbbaa","bbaabbbaa"].

Пояснення

Це в значній мірі просто прямий переклад проблеми кореспонденції Пост на Брахілог.

~h=∋ᵐ\cᵐ=
~h         Find {the shortest possible} list which starts with {the input}
  =        and for which all elements are equal
   ∋ᵐ      such that taking an element of each element,
     \cᵐ   and concatenating elements in corresponding positions,
        =  produces a list all of whose elements are equal.

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


1
І звичайне "пропуск значень, які мають сенс і врятують байти, але інтерпретатор Брахілог не може з цим впоратися": перші п'ять байтів можуть бути виражені як ~dp(що не означає зовсім одне і те ж, але досить близько, щоб все-таки бути Тюрінг-завершений, за винятком того, що перекладач Брахілог ще не знає, як повернути назад d.

12

Желе → "Додати мінімум для переміщення", 5 4 байти

+"Ṃẞ

Спробуйте в Інтернеті! (виконує лише одну ітерацію, щоб уникнути таймаутів)

Дуже проста конструкція, завершена Тюрінгом: ми беремо квадратну матрицю як програму і циклічно вічно, ідентифікуючи лексикографічно найменший рядок, потім збільшуємо кожен елемент першого ряду на перший елемент лексикографічно найменшого, кожен елемент другого ряду за другим елементом лексикографічно найменшого тощо. (Програма Jelly - це " +"додати відповідні елементи {вхідних даних і} мінімум {оригіналу}, циклу"; це байт коротший, ніж моя попередня програма Z+ṂZß, яка зробила абсолютно те саме. Ясна річ, я повинен був зосередитися на гольфінгу Желе, а не просто гольф реалізованої мови.)

Отримана мова є Тюрінг-повною з тієї ж причини, що і кенгуру. Перший елемент кожного рядка діє як кількість пропусків (хоча замість кількості пропусків кожної команди зменшується, коли вона пропускається, ми замість цього збільшуємо кількість пропусків кожної команди під час її запуску, і шукаємо команду з найнижчою кількістю пропусків ніж команди з нульовою кількістю пропусків; це те саме). Ми гарантуємо, що цей перший елемент вище, ніж інші елементи (які представляють кількість разів, коли кожна команда з’являється в мультисеті кожної команди), таким чином гарантуючи, що перший рядок ніколи не буде мінімальним; залишок першого ряду може бути сміттям. Єдина проблема, що залишилася - це моделювання способу, коли команди з рівним числом пропусків запускаються циклічно послідовно, але ми можемо це зробити, помноживши всі пропущені підрахунки на велику константу, а потім додавши на малі "початкові" пропуск рахунків до першого стовпця, який буде виконувати перемичку. Це дає нам розрив "перших запущених команд без запуску", а не "нескорочених команд циклічно виконується послідовно", але конструкція Цюрінга-повноти для кенгуру не переймається цією різницею.


10

Математика, що тлумачить Гра життя Конвея, 64 байти

CellularAutomaton@{224,{2,{t={2,2,2},{2,1,2},t}},{1,1}}~Nest~##&

Гра Життя Конвея, як відомо, Тюрінг завершена; і стільникові автомати - найщиріша одержимість Стівена Вольфрама. CellularAutomaton@{224,{2,{t={2,2,2},{2,1,2},t}},{1,1}}- це правило, яке перетворює двовимірний масив 0s та 1s відповідно до одного кроку гри Життя Конвея. (Я думаю, що поведінка за замовчуванням полягає в тому, що цей масив обертається навколо його країв, тому це насправді дискретний торус.) ~Nest~##&Перетворює це правило у функцію, яка при заданому початковому стані плати (будь-яких вимірів) і nцілому цілі як аргументи виводить результат nітерацій правила «Гра в життя».

Для власної насолоди ви можете використовувати загорнуту версію

b = RandomInteger[1,{50,50}];
Manipulate[ArrayPlot[
  CellularAutomaton@{224,{2,{t={2,2,2},{2,1,2},t}},{1,1}}~Nest~##&
    [b, n] ]
, {{n,0}, 0, 100, 1}]

і прокручуйте свій шлях через 100 поколінь на дошці розміром 50x50.


Якщо я правильно розумію, це фіксований розмір дошки? У такому випадку я думаю, що це не може бути повним Тьюрінгом, чи не так?
DLosc

Будь-який конкретний виклик функції має фіксований розмір плати, але розмір плати може бути довільно великим. (Зверніть увагу, що друга половина публікації описує приклад дотримання коду в дії, а не власне самого коду.)
Грег Мартін

Що я говорю, це те, що для того, щоб GoL був Turing-Complete, він повинен бути здатним до картини, яка зростає нескінченно. .
DLosc

Безумовно, це розумна перспектива. Але реалізація мов програмування на фізичних комп'ютерах навіть не задовольняє цей тест! Можна було б задовольнитись (гіпотетичною) послідовністю фізичних комп'ютерів, що мають більше і більше пам'яті, кожен з яких може обчислити ще одне значення цієї обчислюваної функції; в цей момент, однак, слід бути однаково задоволеним (гіпотетичною) послідовністю входів до такої програми GoL.
Грег Мартін

9

Туртлед, що інтерпретує КТ , 49 байт

Я, можливо, зможу це пограти в гольф

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

це те, що я зробив деякий час тому насправді (тоді гольф дещо зараз)

!-l[*+.r_]' !l[ l]r[ u.(;d' u)d(1[ r].[ l])( r)+]

Як це працює:

Turtlèd використовує комірки сітки. Коли я кажу "написати щось на сітці", я маю на увазі, що суцільна група символів розміщена на сітці. приклад

[ ][ ][ ][ ][ ][ ][ ]
[ ][H][E][L][L][O][ ]
[ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ]

на програму

дані вводяться першими:

!-l[*+.r_]' 

це по суті програма для котів. він записує вхід на сітку.

тоді вводяться команди:

!

що це робиться з цими командами:

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

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

[ u.(;d' u)d(1[ r].[ l])( r)+]

що він робить у цьому циклі, чи рухається він вгору від лівого лівого рядка даних та записує поточний символ команди (u.). якщо він є; в кінці виробництва він переміщується вниз і видаляє крайній лівий біт даних під ним і переміщується назад ( (;d' u)). то в будь-якому випадку вона рухається вниз по одному ( d). якщо біт там не був видалений, це означає, що він повинен перевірити, чи копіювати біт з команд наприкінці. Таким чином, якщо цей символ, який є або був лівим лівим бітом даних, є 1, він переміститься до кінця правого кінця рядка даних, скопіює біт із командного рядка та повернеться назад до простору зліва від крайніх лівих даних біт ( (1[ r].[ l])). тепер він знаходиться або на лівій лівій біті даних, яка дорівнювала нулю, або ліворуч від лівої лівої бази даних. Таким чином, ми рухаємось праворуч, якщо на пробілі (( r)). потім, покажчик команди збільшується, тому ми запишемо наступну команду в наступну ітерацію циклу. Якщо більше немає рядків даних, це означає, що ми знаходимося в просторі і цикл закінчиться. інакше ми повторюємо цикл.


Спробуйте пограти більше!
arodebaugh

9

PerlТризірковий варіант програміста , 26 + 1 = 27 байт

++$a[$a[$a[$_]]]for@F;redo

Спробуйте в Інтернеті! (Це посилання містить заголовок, який виходить із програми після встановленої кількості ітерацій (щоб TIO не вийшов з часу), а також друкувати внутрішній стан кожної ітерації (щоб вона зробила щось спостережуване).)

Запустіть з -a(1 байт штрафу, як ви можете вписати його -M5.010до створення -aM5.010).

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

Програмі насправді не потрібно багато пояснень; Тризірковий програміст має дуже просту специфікацію, і це прямий його переклад. Єдині найтонші моменти: @Fце введення програми у формі масиву (це наслідок -a); і redoповторить всю програму, оскільки вона знаходиться в неявному циклі (також наслідок -a).


1
Я думаю, що для стрілки більше сенсу означати, що "зводиться до", ніж "інтерпретує".
Кінтопія

9

x86 збірка (синтаксис Intel / MASM) -Brainfuck 2127 байт.

Ще гольф у змозі

.386
.model flat,stdcall
.stack 4096
include \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib
ExitProcess proto,dwExitCode:dword
.data
bfsrc BYTE 200 dup(0) 
bfcells BYTE 100 dup(0) 
loopStack DD 5 dup(0) 
charBuf BYTE 5 dup(0) 
newline BYTE 10,0 
prompt BYTE "$",0 
hr BYTE 50 dup('-'),0 
space BYTE ' ',0
.code
EvalBf proc
    start:
    invoke StdOut, addr prompt
    invoke StdIn, addr bfsrc,200
    cmp bfsrc,0
    je exit
    mov eax,0 
    mov ebx,0 
    mov ecx,0 
    processInstruction:
    cmp BYTE PTR bfsrc[ebx], '+'
    je plus
    cmp BYTE PTR bfsrc[ebx], '-'
    je minus
    cmp BYTE PTR bfsrc[ebx], '>'
    je fwd
    cmp BYTE PTR bfsrc[ebx], '<'
    je back
    cmp BYTE PTR bfsrc[ebx], '['
    je open
    cmp BYTE PTR bfsrc[ebx], ']'
    je close
    cmp BYTE PTR bfsrc[ebx], '.'
    je dot
    jmp processNextInstruction
    plus:
    inc BYTE PTR bfcells[eax]
    jmp processNextInstruction
    minus:
    dec BYTE PTR bfcells[eax]
    jmp processNextInstruction
    fwd:
    inc eax
    jmp processNextInstruction
    back:
    dec eax
    jmp processNextInstruction
    open:
    mov loopStack[ecx*4],ebx
    inc ecx
    jmp processNextInstruction
    close:
    dec ecx
    cmp BYTE PTR bfcells[eax], 0
    je processNextInstruction
    mov ebx,loopStack[ecx*4]
    inc ecx
    jmp processNextInstruction
    dot:
    mov dl, BYTE PTR bfcells[eax]
    mov BYTE PTR charBuf[0], dl
    mov BYTE PTR charBuf[1],0anything
    push eax
    push ecx
    invoke StdOut, addr charBuf
    pop ecx
    pop eax
    jmp processNextInstruction
    processNextInstruction:
    inc ebx
    cmp BYTE PTR bfsrc[ebx], 0
    je done
    jmp processInstruction
    done:
    invoke StdOut, addr newline
    mov eax, 0
    printNext:
    cmp eax, 100
    jge reset
    push eax
    invoke dwtoa, BYTE PTR bfcells[eax], addr charBuf
    invoke StdOut, addr charBuf
    invoke StdOut, addr space
    pop eax
    inc eax
    jmp printNext
    reset:
    invoke StdOut, addr newline
    invoke StdOut, addr hr
    invoke StdOut, addr newline
    jmp start

    exit:
    invoke ExitProcess,0
EvalBf endp
end EvalBf

3
Зазвичай відповіді на збірку враховуються в розмірі машинного коду, що виходить, тому вам не потрібно взагалі гольфувати збірку, просто мінімізуйте кількість / розмір інструкцій.
Роберт Фрейзер

@RobertFraser uhh Я не знаю, як це порахувати: P
Крістофер

3
Власне, спочатку я якось прочитав заголовок як "x86 asm, реалізований у Brainfuck", і
мене

@Quetzalcoatl Це було б вражаюче
Крістофер

1
pls Імена змінної гольфу / етикетки ty
лише ASCII

8

Система циклічних тегів інтерпретації піп , 16 байт

YqWyyPBg@++vXPOy

Приймає постановки системи тегів як аргументи командного рядка та початковий рядок даних із stdin.

Вищевказаний код якось важко перевірити, оскільки він не дає жодного результату (тому єдине спостережуване поведінка - "припиняється" проти "не закінчується"). Отже, ось версія, яка не перебуває у віці, яка виводить рядок даних після кожного кроку, а також припиняється після 20 кроків, тому TIO не повинен мати справу з тоннами виведення з нескінченних циклів: Спробуйте це в Інтернеті!

Циклічні системи міток

Циклічні тегові системи - надзвичайно проста, але Тюрінг-повна обчислювальна модель. Вони складаються з переліку виробництв, які визначають операції над рядком даних . Рядок виробництва та даних складається з 1 та 0.

На кожному кроці видаляється крайній лівий символ рядка даних.

  • Якщо символ дорівнює 1, поточне виробництво додається до правої частини рядка даних.
  • Якщо символ 0, нічого не додається.

У будь-якому випадку, поточне виробництво переходить до наступного виробництва у списку, циклічно: якщо ми були на останньому виробництві, ми переходимо до першого. Виконання триває, поки рядок даних не буде порожнім.

Пояснення

                  g is list of cmdline args; v is -1 (implicit)
 q                Read a line of stdin for the data string
Y                 and yank it into the y variable
  Wy              While data string is nonempty:
       g@++v       Retrieve the next production from g (using cyclic indexing)
             POy   Pop the first character of y
            X      String-multiply: result is the production if the first character of y
                   was 1, or empty string if it was 0
    yPB            Push that string to the back end of y

Гей, я просто згадав, що вам не потрібно вводити рядок даних; це може бути просто 1джерело: посилання esolangs на цей arxiv.org/abs/1312.6700 . Я скоро відредагую свою відповідь, і якщо це допоможе вашій відповіді, вам слід (т. Ч. Ваш внесок здається досить гострим насправді)
лимон

8

Ітералізовані узагальнені функції Collatz -> Python 2, 46 байт

a,b,x,m=input()
while-~x%m:x=x/m*a[x%m]+b[x%m]

Назвіть цю функцію зі списками m-1 a і b's, початковим значенням x та дільником m, які в сукупності становлять "програму" для IGCF. Замість того, щоб скористатися третім масивом, щоб вказати, на яких модулях зупинятися, це просто зупиняється, коли модуль m-1. Це спрощення означає, що може знадобитися додаткові зусилля для перетворення заданої програми Fractran в цей варіант, але це заощадить пару байт в інтерпретаторі.

Спробуйте в Інтернеті! Цей TIO демонструє, як додати 5 + 5 за допомогою цієї мови. Програма a = [3], b = [0], m = 2 робить додавання, і, починаючи з 7776 = 2 ^ 5 * 3 ^ 5, врешті-решт виходить 59049 = 3 ^ 10.


Гарна робота. Я сподівався виграти щедроту, але хорошу роботу
Крістофер

7

Варіант реплікації -> Python 2, 47 байт

l=input()
while l:l=l[2+l[0]:]+l[2:2+l[0]]*l[1]

Ця функція інтерпретує варіант ResPlicate

  • для якої програма - це список пітонів рівної довжини з парними елементами з парними індексами.
  • без вводу / виводу.
  • для яких спроба скопіювати більше значень, ніж існує в іншій черзі, просто копіює залишок черги (тобто скопійований біт не забитий нулями до необхідної довжини).

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

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


2
Чому ні l=input()? Буде байт коротше.
feersum

7

Perl -aI / D машина , 24 байти

$p=$a[$p]+=$_ for@F;redo

Спробуйте в Інтернеті! (містить заголовок, який друкує внутрішній стан і зупиняється після 10 ітерацій, щоб поведінка була помітна)

Про мову

Я провів останні кілька днів, працюючи над I / D-машиною , однією з моїх останніх ідей щодо дуже простих мов програмування. Він працює так: зберігання даних складається з необмеженої оперативної пам’яті, спочатку всіх нулів. Кожен елемент може зберігати необмежене ціле число (хоча на практиці більшість машинних програм вводу / виводу в більшості з них зберігатимуть лише малі цілі числа та використовуватиме безмежні цілі числа лише як спосіб адресації комірок з великими адресами). Існує також покажчик даних, який вказує на комірку (тобто містить адресу як клітинку); вона спочатку також дорівнює нулю.

Є лише дві команди:

  • I: Збільшення комірки, на яку вказує вказівник даних. (Сам покажчик даних залишається незмінним.)
  • D: Дереференція покажчика даних, тобто зчитування значення комірки, на яке вказує вказівник даних. Потім збережіть отримане значення, яке ви прочитали назад, у покажчик даних.

Виконання просто запускає програму в циклі повторно, назавжди.

Досить дивно, що ця проста мова є Тюрінг-повною, тому я працював над доведенням цього. Ось доказ . Він досить схожий на (але простіший, ніж) доказ для тризіркового програміста, дуже схожою мовою (і насправді в цьому поданні використовується однакова базова оболонка OISC навколо програми, що відрізняється лише фактичною реалізованою інструкцією).

Про програму

Використання

Вхід повинен бути наданий на стандартному вході і являє собою машинну програму вводу / виводу без коментарів та з використанням синтаксису RLE / OISC. (Машина вводу / виводу має два різних, еквівалентних синтаксису, але для гольфності ця програма підтримує лише один з них.) У цьому синтаксисі програма - це послідовність чисел у десятковій частині, що представляє тривалість виконання Iкоманд між Dкомандами. (Ви можете вказати дві чи більше послідовних Dкоманд, розмістивши Iміж ними "запуск 0 команд", так що синтаксис є повністю загальним.)

Пояснення

Як видно з програми, це не реалізує команди Iта Dкоманди окремо. Насправді це (дуже незначно) оптимізуючий перекладач (чисто тому, що писати так коротше). Ключ полягає в тому, щоб побачити, що виконання n команд приросту збільшує цільовий показник вказівника n разів, тобто додає до нього n ; і запуск команд з збільшенням 0 може також бути реалізований таким чином, оскільки додавання 0 в пам'ять не має ефекту. Отже, операція, яку ми реально реалізуємо, полягає в чергуванні між реалізацією запуску Iта a D. Або іншими словами, "додати ндо значення, на яке вказує покажчик даних (зберігання його назад у значенні, на яке вказує покажчик даних), потім зчитують значення, на яке вказує вказівник даних, і зберігають його в покажчику даних ". Це явно більш багатослівний, ніж потрібно бути, і ми можемо додатково спростити це, щоб "додати n до значення, на яке вказує вказівник даних, а потім зберегти це значення як у цілі вказівника даних, так і в самому покажчику даних".

Отже, це є основою нашої програми. Ми використовуємо масив $aдля зберігання оперативної пам’яті та $pв якості вказівника даних (індексація в масив):

$p=$a[$p]+=$_
         + $_  add {the run length}
   $a[$p]      to the element of $a pointed to by $p
   $a[$p] =    storing the result back into that element
$p=            and also in the pointer itself

Зручно, Perl інтерпретує неініціалізовані елементи масиву як 0, коли вони обробляються як числа, тому масив буде ліниво ініціалізований до нулів для нас без явного коду для цього. (Однією з потенційних проблем є числова точність, коли цифри набувають великих розмірів; проте це станеться лише в тому випадку, якщо кількість використовуваного масиву перевищує адресний простір машини (цілі числа Perl досить великі, щоб утримувати покажчики), що не може трапитися на ідеалізованій машині.)

Нарешті, все, що нам потрібно зробити, - це розмістити цю програму в пару циклів. for@FПетля, в поєднанні з -aпараметром командного рядка, буде цикл над полями стандартним вводом (визначення за замовчуванням «поля» тут буде розділено на пробільних). redoЦикл буде помістити всю програму в неявному циклі (крім, зручно, читання стандартного вводу), що призведе до того , програма для запуску в циклі багаторазово, відповідно з вимогами семантики машини I / D.


З поверненням! Нам більше не потрібно забивати прапори для перекладачів, лише зауважте, що це "Perl with -a". codegolf.meta.stackexchange.com/a/14339/9365
Дом Гастінгс

6

Желе2-тег система , 8 байт

µḢị⁴⁸;Ḋß

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

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

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

Наприклад, Вікіпедія дає приклад системи тегів { a, b, c}, { abc, ba, caaa} з початковою рядком aaa; в цьому форматі введення, це [1,1,1], [[2,3],[1],[1,1,1]]. (Системи тегів не мають фіксованого синтаксису, і це здається розумним способом.)

Посилання TIO має доданий ("написати внутрішній стан та новий рядок для stdout"), щоб показати, що програма насправді працює.

Пояснення

µḢị⁴⁸;Ḋß
           {implicit: initialise internal state from first argument}
µ          Disregard the second command-line argument by default
 Ḣ         Take the first element, removing it from the internal state
  ị⁴       Use the value to index into the second argument
    ⁸;     Prepend (the rest of) the internal state
      Ḋ    Discard the first element of the internal state
       ß   Loop forever

6

BF / P ", реалізований у машині Тьюрінга, 842 байти

Таблиця переходу (пов'язана через довжину)

Перехідний стіл, менш гольф-версія

Симулятор машини Turing я використовував

Це звичайно не виграє жодної нагороди за довжину, але це те, що я завжди хотів зробити, оскільки BF настільки схожий на машину Тюрінга. Кожна комірка зберігає значення від 0x0- 0xF. Однак ширина далеко не на веб-сайті Тюрінг-машин, а також без збоїв браузера. Функції ,і .(вхід і вихід) не визначені, тому це трохи більше схоже на P ", ніж на справжній BF.

Щоб запустити його, вставте таблицю переходу в тренажер машини Turing, встановіть вхід до деякого коду BF і натисніть запустити.

Стрічка ТМ зберігає як BF-код, так і BF-дані, з єдиним проміжком посередині. Він відслідковує свою позицію в коді, змінюючи символ, який він працює в даний час ( [-> (і т. Д.) Та своє положення в даних, розташованим ^перед коміркою. Після того, як він прочитає командний символ, він рухається, поки не потрапить на карету, перемістить одну клітинку праворуч і виконує відповідну функцію. Потім він повертається назад, шукаючи одного з "модифікованих" символів команди в BF-коді, і переходить до наступного, повторюючи весь процес. Після закінчення коду він зупиняється.

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

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


1
Обмеження довжини публікації більш ніж достатньо для розміщення таблиці переходу
лише для ASCII

6

C реалізуючи (2,3) машину Тьюрінга , 236 205 байт (на 46 31 менше, якщо вам не байдуже про незручні введення)

Завдяки Appleshell для -11 байт, VisualMelon для -12 байт і Йохан дю Тойт для -7 байт.

CeilingCat зробив версію, яка використовує всього 144 байти, дивіться тут .

(Додав сюди кілька розривів рядків, тому вам не доведеться прокручувати, але зазвичай більшість з них буде видалено)

#define c char
j;i;k;c s,d[256];c main(){c*p=d+128;gets(d);
for(;k<256&&d[k];)d[k++]-=48;for(;++j<256;)
{c t=*p;*p=-t*t+(2-s)*t+1+s;p+=(s^t==0)*2-1;s=s?t%2:!t%3;
for(i=0;++i<256;)printf("%d",d[i]);puts("");}}

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

Для використання: Введіть рядок до 256 одиниць, нулів та двох, щоб ініціалізувати стрічку. Будь-які неініціалізовані значення будуть нульовими. (Значення, відмінні від 0, 1 і 2, можуть спричинити невизначене поведінку.) Програма повторює понад 256 кроків. Кількість кроків, які вона повторює, можна збільшити, змінивши код, але очевидно, що потрібно більше символів.

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

Багато байт - це робота з входом і виходом, і я втратив цілих 42 байти, змусивши її прийняти 0, 1 і 2 замість NUL, SOH, STX. (Щоб змінити це, видаліть k;з переднього та for(;k<256&&d[k];)d[k++]-=48;другого рядків.)

Таблиця транзиту, особливо лінія *p=-t*t+(2-s)*t+1+s;(яка встановлює значення на стрічку), ймовірно, може бути також стиснута ще більше.


1
Ого, і це ваш перший гольф-код тут! Чудово!
Zacharý

Ви можете скоротити декларації глобальної змінної так: k,j;c s,d[256];( intмається на увазі C, тоді ви також можете перейти iдо глобальної декларації, щоб зберегти ще 3 байти)
Appleshell

@Appleshell Спасибі, я це зроблю.
а52

Ви можете перемістити перевірку рядка null-terminal всередині циклу. Вкладка k++та виймання {}економить ще пару байтів. for(;k<256&d[k];)d[k++]-=-48;Оскільки jце лише хронометр часу (значення ніколи не використовується), ви можете замінити його (і i) kна підрахунок зворотнього k==256шляху : ви знаєте, що після першого циклу, тому підрахуйте до нуля в другому for(;k>0;), який залишає k==-1, тому останньою петлею може стати for(;++k<256;). (Відмова: Я зазвичай гольф C#, але це здавалося скластися).
VisualMelon

1
@VisualMelon Я визначив проблему. Мені потрібно було користуватися k<256&&d[k], а не &, тому d[k]що оцінювали в k==256. Крім того, оскільки після цього циклу kвже не було гарантовано 256, мені довелося після цього скинути його, щоб гарантувати 256 кроків. (Якщо у вас (тобто у VisualMelon) є якісь інші пропозиції, ми, ймовірно, повинні розмістити їх у чаті, щоб ми не отримували занадто багато коментарів)
a52

5

Röda реалізації Fractran , 114 112 106 байт

1 байт збережено завдяки @fergusq шляхом перестановки параметрів

f&n,a{x=1{x=0;(a/" ")()|[_/`/`]|[parseInteger(_[0],_1[1])]|{|q,w|{n*=q/w;x=1}if[n%w<1,x<1]}_,_}while[x>0]}

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

Виклик функції наступним чином: f reference_to_input program. Вихід буде зберігатися у розташуванні input.


Точка з комою після e[1]зайвої. Також ви можете зберегти один байт, змінивши порядок параметрів: f&n,a.
fergusq

@fergusq Дякую за f&n,aхитрість, і я ось-ось збирався видалити цю напівколонку, коли ви коментували :)
Kritixi Lithos

5

Clojure, 82 81 байт (машина Тюрінга)

Оновлення: видалено пробіл із t{} s.

#(loop[p 0 t{}s 1](if-let[[S M N](%[(or(t p)0)s])](recur(+ p M)(assoc t p S)N)t))

Реалізує машину Тьюрінга як цикл, повертає стрічку, коли буде досягнуто стан зупинки. У правилах переходу держави це вказується, опускаючи стан переходу. Це settins Nдо nilі подальше if-letперерве як відповідний перехід стану не найден з вхідного хеш-карті %. Насправді будь-яке значення для цього стану матиме, наприклад :abort, 0 або -1.

Бездоріжжя з прикладом 3-штатного 2-символьного зайнятого бобра з Вікіпедії .

(def f #(loop[pos 0 tape {} state 1]
          (if-let [[sym move next-state](%[(get tape pos 0)state])]
            (do (println [pos tape state])
                (recur(+ pos move)(assoc tape pos sym)next-state))
            tape)))

(f {[0 1] [1  1 2]
    [0 2] [1 -1 1]
    [0 3] [1 -1 2] 
    [1 1] [1 -1 3]
    [1 2] [1  1 2]
    [1 3] [1  1]})

{0 1, 1 1, -1 1, -2 1, -3 1, 2 1}

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

На одному ядрі 6700K цей запуск 5-державного 2-символьного зайнятого бобра (47,1 мільйона кроків) приблизно за 29 секунд, або 1,6 мільйона кроків / секунду.


5

MПорада , 4 байти

Ṅ×ịß

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

Посилання TIO додає колонтитул для виклику функції за прикладом програми підказки, показаної на сторінці Esolang (M "автоматична обгортка" для виклику функцій так, ніби вони були програмами, не можуть обробляти раціональні чи фіксовані числа, або, принаймні, у мене немає Я не придумав, як це сказати, тому мені потрібно перетворити функцію в повну програму вручну, щоб мати можливість її запускати.)

Це фактично друкує корисний вихід налагодження; Програма не може бути записана в 3 байти в M, тому що програма, що складається з рівно трьох діад, запускає спеціальний випадок в аналізаторі, тому мені довелося додати додаткову команду, щоб уникнути особливого випадку. Створення його (друк з новим рядком) принаймні дає корисну мету.

ıi=1

Не здійснює введення / виведення (крім halt / no-halt). Введення / виведення - це розширення на підказку (не є частиною самої мови), і не потрібно для цілісного завершення.

Пояснення / передумови

Ṅ×ịß
Ṅ     Print {the left argument} and a newline; also resolves a parser ambiguity
  ị   {The left argument}th element of {the right argument}, wrapping on OoB
 ×    Multiply {the left argument} by {the chosen element}
   ß  Recursive call; arguments: {the product} and {the same right argument}

[1,2,3][1,2,3,1,2,3,1,2,3,…]rx+s, що є поліномом, і "базове перетворення", побудоване в багатьох мовах для гольфу, насправді є маскою оцінювача поліномів загального призначення. Отже, все, що нам потрібно зробити - це індексувати список списків цифр, конвертувати їх у базу, і ми закінчили, правда?

xx

x(xy)xy. Звичайно, ми могли б перемогти ланцюгову поведінку майже на все, що завгодно, але це коштувало б цілого байту, а записи мови для гольфу в цьому питанні стають настільки короткими, що байт - це багато.

Тож я озирнувся і трохи переоцінився. Чи є якісь операції, які ми могли б використовувати замість поліномальної оцінки? В ідеалі - комутаційні, тому нам не потрібно турбуватися про порядок аргументів? Незабаром після цього я зрозумів, що функції Колатца складніші, ніж повинні бути.

s

І звичайно, на відміну від базового перетворення ( ), множення ( ×) є комутативним, і, таким чином, не має значення, в якому порядку розміщуються аргументи. Отже, все, що нам потрібно написати ×ị, а потім розмістити програму в нескінченну рекурсію ß, і ми маємо повну мову Тюрінга. Правильно?

(xy)(xy)¹×ịß¹¹ є хорошим вибором, оскільки він дає корисний вихід налагодження.

Чи можливі три байти? Якщо я чогось не пропускаю, не з цим конкретним вибором мови втілення та реалізації, але на даний момент, напевно, здається, що це можливо було б якось можливо, оскільки існує так багато способів зробити це за чотири і так багато Тюрінга мови, які ви могли реалізувати.


Подумавши про це ще трохи, ми могли б отримати це до трьох байтів , використовуючи і замість ×і ; отримана мова не зовсім та сама мова, як Tip, але вона досить схожа і майже напевно Тюрінг-повна з тієї ж причини. На жаль, це не реалізовано в M, і я не можу знайти жодного способу зробити Jelly робити довільну точність обчислень, коли будь-який із входів є не цілим реальним числом. Якщо хтось знає будь-які інші мови для гри в гольф, де ця конструкція може працювати, проте сміливо відправте це.
ais523

4

C інтерпретація Brainfuck, 187 байт

t[999],*p=t,c,i,l;f(char*t){for(i=0;c=t[i];i++){c^62?c^60?c^43?c^45?c^46?c^44?c^91:(*p=getchar()):putchar(*p):--*p:++*p:--p:++p;if(c==93&&*p)for(l=1;l>0;)c=t[--i],c==91?l--:c==93?l++:0;}}

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


3
Welp, відповідь обов'язково повинна була використовувати BF.
Zacharý

4

Lua інтерпретуючи Brainf ***, 467 байт

b,r,a,i,n,s=0,io.read,{0},1,1,"><+-.,[]"c,f=r(),{function()n=n+1;a[n]=a[n]or 0;end,function()n=n-1;a[n]=a[n]or 0;end,function()a[n]=a[n]+1;end,function()a[n]=a[n]-1;end,function()io.write(string.char(a[n]))end,function()a[n]=io.read():byte()end,function()i=a[n]~=0 and i or c:find("]",i)end,function()if a[n]~=0 then b,x=1,""repeat i=i-1 x=c:sub(i,i)b=x=="["and b-1 or x=="]"and b+1 or b until b==0 and x=="["end end}repeat f[s:find(c:sub(i,i),1,1)]()i=i+1 until i>#c

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


2
+1 для brainsгравців, це завжди цікаво, коли гольфістів призначають до списку змінних.
Zacharý

4

CJam → ResPlicate Variant, 15 14 13 байт

-1 байт завдяки @ ais523

l~{(/((*+e_}h

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

l~{ ... }hЧастина просто приймає масив в якості вхідних даних і повторюється до тих пір , що масив не пустили.

Пояснення для основного циклу:

    e# Stack:             | [3 2 1 1 2 2 2 1]
(   e# Pop first element: | [2 1 1 2 2 2 1] 3
/   e# Split chunks:      | [[2 1 1] [2 2 2] [1]]
(   e# Pop first:         | [[2 2 2] [1]] [2 1 1]
(   e# Pop first:         | [[2 2 2] [1]] [1 1] 2
*   e# Repeat array:      | [[2 2 2] [1]] [1 1 1 1]
+   e# Concatenate:       | [[2 2 2] [1] 1 1 1 1]
e_  e# Flatten:           | [2 2 2 1 1 1 1 1]

Тут вам не дуже потрібен приріст. Просто вкажіть, що довжини блоків слід збільшувати на 1 у початковій програмі; що не шкодить цілісності повноти ResPlicate (є ТС-конструкції, в яких довжина блоків і кількість повторів ніколи не змішуються).

3

Чіп , 20 + 3 = 23 байти (Правило 110)

AZZ
>}/a
`)\'E~Zte*f

+3 для прапора -z

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

Це подання не є ідеальним, оскільки чіп (ще) не має певної здатності до циклу, тому вихід повинен бути переданий як вхід для імітації декількох поколінь, таким чином (звичайно, ви можете запустити цю петлю на невизначений час, і Chip може обробляти довільно довгий вхід, тому ця комбінація є Turing Complete).

Ця реалізація приймає введення та заданий вихід у вигляді ASCII 0s та 1s. Логіка тут така:

p := value of left neighbor cell    AZZ
q := value of current cell          AZ
r := value of right neighbor cell   A

q' := ((r xor q) and p) or          >}/a
      ((r or q) and ~p)             `)\'

Залишок елементів призначений для ведення домашнього господарства: e*fвикликає цифровий вихід ASCII і E~Ztзавершує виконання двох байтів після вичерпання вхідних даних (оскільки ширина зростає на 2 у кожному поколінні).


3

Clojure, 75 байт (Циклічна система тегів)

Оновлення 1: замінено some?на nil?.

Оновлення 2: Виправлено відсутність Sу іншій гілці if s.

#(loop[[p & P](cycle %)[s & S]%2](if(nil? s)S(recur P(if s(concat S p)S))))

Реалізує циклічну тегову систему , повертає, nilякщо програма зупиняється, циклічно назавжди. Clojure справді світить тут нескінченними ледачими послідовностями (такими як цикл ) і руйнування . Одні та нулі позначаються як істинні та хибні значення. Коли рядок даних закінчується, sстає nil.

Безголівки:

(def f #(loop[[p & P] (cycle %) [s & S] %2 i 5]
          (do
            (pprint [p (concat [s] S)])
            (if (and (some? s) (pos? i))
              (recur P (if s (concat S p) S) (dec i))))))

Приклад результатів:

(f [[false]] [true true])
[[false] (true true)]
[[false] (true false)]
[[false] (false false)]
[[false] (false)]
[[false] (nil)]

(f [[false true true] [true false] [true false true]] [true])
[[false true true] (true)]
[[true false]      (false true true)]
[[true false true] (true true)]
[[false true true] (true true false true)]
[[true false]      (true false true false true true)]
[[true false true] (false true false true true true false)]

2

Інтерпретація JavaScript Правилом 110 , 131 байт (99 байт? 28 байт?)

a=(p,q,r)=>q+r+q*r+p*q*r
b=l=>{r="";for(i=0;i<l.length-2;i++)r+=a(l[i],+l[i+1],+l[i+2])%2;return r}
c=(l,n)=>!n?l:c(b(0+l+0),n-1)

Як бачите, код визначає 3 функції a, bі c. Можливо, можна зберегти байти, об’єднавши їх в 1 функцію (я не бачу, як), але добре, що є окремі, оскільки кожен з них у певному сенсі вже виконує цю проблему.

Функція aбере 3 числа як вхідні дані і обчислює якийсь дивний їх многочлен. Коли ці 3 числа є 0або 1їх можна вважати клітинами правила 110. Паритет виходу з aцього виду може розглядатися як значення середньої комірки в наступному поколінні. Тож у певному сенсі ця проста функція вже є "інтерпретатором" правила 110 (28 байт):

a=(p,q,r)=>(q+r+q*r+p*q*r)%2

Потім ми можемо створити нову функцію, bяка оцінює aкожен символ рядка одиниць і нулів. Це bтоді, кращим чином, ніж aперекладач правила 110. Беручи mod 2 після оцінки збережених дужок (99 байт):

a=(p,q,r)=>q+r+q*r+p*q*r
b=l=>{r="";for(i=0;i<l.length-2;i++)r+=a(l[i],+l[i+1],+l[i+2])%2;return r}

Щоб фактично обчислити функцію з Правилом 110, користувач повинен вказати початковий стан та кількість поколінь, після яких вихід 'з'явиться'. Ми можемо зробити третю функцію, cяка займає рядок одиниць і нулів, і додатне ціле число n, яке потім оцінює bна рядок, nрази. Таким чином, ми дійсно можемо розглядати правило 110 як мову програмування, де програма - це початковий стан і число n, а вихід - стан після nпоколінь. Тепер ця функція cє фактичним перекладачем для цієї мови програмування, тому остаточний код для цього завдання є тим, що я представив вище.


Чи обчислює це 110 з належним фоном? Ранішу мою відповідь було видалено, оскільки вона не мала фону.
Пшеничний майстер

@WheatWizard фон є частиною вхідних даних, ваша відповідь не повинна була бути видалена для цього
Jens Renders

Фон повинен бути нескінченним, чи можна брати нескінченний внесок?
Пшеничний майстер

@WheatWizard це не повинно бути нескінченним, його потрібно зробити довільно великим, а це може
Jens Renders

1
Правило 110 не є Тюрінг завершеним, якщо ви вирішите покоління заздалегідь, і вам потрібен нескінченний внесок у конструкцію, про яку я знаю. Навіть якщо хтось знайшов конструкцію з кінцевим початковим станом, ви не можете знати пам'яті або часу, необхідного до запуску програми, оскільки тоді ви могли б вирішити проблему зупинки.
Ørjan Johansen

2

JS -> Новий рядок 854 байти

(function(d){var b=0;var n=!0;var c=[];var h=[];var e=0;var l=[];var m=0;var f=2;var a=0;var g=!1;var k=function(a){if(a===1)return!1;if(a%2===0&&a!==2)return!1;if(a%3===0&&a!==3)return!1;if(a%5===0&&a!==5)return!1;if(a%7===0&&a!==7)return!1;for(var b=7;b<d.round(d.sqrt(a))+1;b++)if(a%b===0)return!1;return f=a,!0;};var j=0;var i=0;var o=function(q){var o=d.__split(q,'\n');d.println(o);for(var n=0;n<o.length;n++)if(n>=f^2&&n<=f+1^2&&k(n)){f=n;for(var p=0;p<o[n].length;p++){if(o[n]==='+'&&(a+=c[b],b++),o[n]==='-')if(g===!0&&a<=0)break;else a-=c[b],b++;if(o[n]==='*'&&(a*=c[b],b++),o[n]==='/'&&(a/=c[b],b++),o[n]==='s'&&(a=d.sqrt(a)),o[n]==='%'&&(a%=c[b],b++),o[n]==='a'&&l.push(a),o[n]==='g'&&(a=c[b],b++),o[n]==='q'&&c.push(a),o[n]==='i'&&a++,o[n]==='d')if(g===!0&&a<=0)break;else a--;o[n]==='r'&&(g=!0),o[n]==='w'&&(g=!1),o[n]==='['&&(j=n),o[n]===']'&&a>0&&(n=j,h[e]--),o[n]==='{'&&(i=n),o[n]==='}'&&h[e]>0&&(n=i,h[e]--),m=a,o[n]==='k'&&e++;}}};});

Супер гольф завдяки Google.


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

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

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

1
Ви можете поєднати всі varтвердження:var b=0,n=!0,c=[],h=[],e=0,l=[],m=0,f=2,a=0,g=!1;
Esolanging Fruit

1
Видаліть усі varти
лише ASCII

1

Clojure, 87 байт (правило 110)

Кредит за паритетним кодом належить Йенсу Рендеру! Я дуже боровся з тим, як це висловити, і збирався перейти з [p q r]бінарного в ціле число і використовувати таблицю пошуку.

#(iterate(fn[S](for[[p q r](partition 3 1(concat[0]S[0]))](mod(+ q(* q(+ 1 p)r)r)2)))%)

Тут partitionі руйнування Clojure робить логічне застосування досить простим. Ця функція повертає нескінченну послідовність станів, тому абонент відповідає за takeстільки, скільки їм потрібно, або просто nthперейти до певного стану. Якби прокладки з нулем були двома елементами, а не один, то стрічка постійно зростала, уникаючи межових проблем. Тепер він залишається початковою шириною.

Приклад:

(def f #(iterate(fn[S](for[[p q r](partition 3 1(concat[0]S[0]))](mod(+ q(* q(+ 1 p)r)r)2)))%))

(pprint (take 5 (f '(0 0 0 0 0 1 1 1 0 0 1 0 0))))
((0 0 0 0 0 1 1 1 0 0 1 0 0)
 (0 0 0 0 1 1 0 1 0 1 1 0 0)
 (0 0 0 1 1 1 1 1 1 1 1 0 0)
 (0 0 1 1 0 0 0 0 0 0 1 0 0)
 (0 1 1 1 0 0 0 0 0 1 1 0 0))

1
Якщо ви коли-небудь працюєте з оригінальною шириною, це, можливо, не може бути повним Тьюрінгом, оскільки воно має лише обмежене зберігання пам'яті. (Насправді, всі відомі конструкції Тюрінг-повноти з Правила 110 вимагають "накладки", яка використовується для розширення ширини, оскільки програма продовжує мати шаблон, вказаний із введення користувача, і різний ліворуч і праворуч, а не просто з використанням нулів.)

Я бачу, це ускладнює його моделювання тоді. Clojure's cycleзмогли б побудувати нескінченну схему
накладки

Подумайте про це, було б не надто складно сприймати цей шаблон накладки як додаткові аргументи та розширити змодельовану стрічку на 1 блок ліворуч та праворуч. Швидкість інформації тут становить 1 блок / ітерація, тому нам просто потрібно моделювати "світловий конус" навколо центрального блоку, який має асиметричну структуру. (CMIIW)
NikoNyrh

1

APL (Dyalog)Fractran варіант, 15 байт

(⊃0~⍨××0=1|×)⍣≡

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

Функція приймає раціоналі як список чисел, а не два списки, що містять чисельник і знаменник, і виводить результат, якщо програма закінчиться. Це реалізує варіант Fractran, який має раціональну 1/1 (= 1) в кінці програми. 1 не впливає на повноту Тьюрінга (наскільки я розумію), оскільки вхід до програми припадає лише на 1, коли ніхто з інших раціоналів не працює, а коли це відбувається, вхід не змінюється. Це використовується лише для того, щоб функція знала, коли закінчитися.

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

(⊃0~⍨××0=1|×)⍣≡ переглядає раціональний аргумент як лівий аргумент, який позначається як ⊣, а вхідний як правий аргумент - to

(⊃0~⍨××0=1|×) функціональний потяг

  • 1|×отримайте частину після десяткової крапки (модуль 1) добутку ×⊣ і ⊢

  • 0= це дорівнює 0?

  • ×× помножте цей результат на ⊣ × ⊢, де раціональне × ⊢ не є цілим числом, воно замінюється на 0

  • 0~⍨ видалити всі 0

  • отримати перший елемент

цикл, поки вхід не зміниться, зауважте, що результат (⊃0~⍨××0=1|×)повторного використання як вхід, тому, якщо він перестає змінюватися (в результаті 1 в кінці), програма зупиняється


1

JavaScript: обчислення лямбда ( 123 114)

Представлено з використанням індексів Дебруйна в дуплеях.

V=function b(c,d){if(!isNaN(c)){for(;--c;)d=d[1];return d[0]}return 0==c[0]?e=>b(c[1],[e,d]):b(c[0],d)(b(c[1],d))}

S комбінатор є [0, [0, [0, [[3, 1], [2, 1]]]]]

К є [0, [0, 2]]

Я є [0, 1]

Редагувати: Поголений 9 байтів, замінивши "number"==typeof cна!isNaN(c)


0

APL (Dyalog Unicode) , 15 байт SBCS

Повна програма, яка реалізує узагальнений одновимірний виконавець стільникового автомата. Сюди входить правило 110, яке є Тюрінгом повним. Запрошує stdin для початкового стану, кількості ітерацій (або для продовження до стабільного або {⍵≡⎕←⍺}для відображення всіх проміжних значень до стабільності) та встановлення правил.

⎕∊⍨∘(⊢∘⊂⌺3)⍣⎕⊢⎕

Спробуйте в Інтернеті! (4 повторення правила 110)

 запит на початковий стан та

 вихід, який (відокремлює стан від кількості ітерацій)

⍣⎕ підкажіть про кількість повторень і багато разів застосуйте таку функцію:

() Застосувати таку негласну функцію:

  ⌺3 отримайте всі мікрорайони довжиною-3 (з інформацією про те, чи є вони на краю) та застосуйте таку негласну функцію до кожної пари:

    оточити околиці

    і

    принести це (відкинувши інформацію про те, що знаходиться на краю)

 тоді

∊⍨ перевірити, чи є вони членами

 запит на перелік мікрорайонів, що ведуть до наступної ітерації

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