Чітке укрупнення в потягах APL


19

В APL можна записати мовчазні функції, які називаються поїздами . Те, як вони працюють, не має значення для цього завдання. Ось різні способи їх групування, використовуючи як функцію:

⍴      -> ⍴
⍴⍴     -> ⍴⍴
⍴⍴⍴    -> ⍴⍴⍴
⍴⍴⍴⍴   -> ⍴(⍴⍴⍴)
⍴⍴⍴⍴⍴  -> ⍴⍴(⍴⍴⍴)
⍴⍴⍴⍴⍴⍴ -> ⍴(⍴⍴(⍴⍴⍴))
...

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

Step 0: ⍴⍴⍴⍴⍴⍴
There are strictly more than 3 functions, repeat.
Step 1: ⍴⍴⍴(⍴⍴⍴)
There are strictly more than 3 functions, repeat.
Step 2: ⍴(⍴⍴(⍴⍴⍴))
There are 3 or less functions, we're done.

Ось та сама процедура, що застосовується до ⍴⍴⍴(⍴⍴)⍴(⍴⍴⍴⍴(⍴⍴⍴))⍴⍴:

Step 0: ⍴⍴⍴(⍴⍴)⍴(⍴⍴⍴⍴(⍴⍴⍴))⍴⍴
There are strictly more than 3 functions, repeat.
We have met a nested train, applying procedure to that first:
  Step 0: ⍴⍴⍴⍴(⍴⍴⍴)
  There are strictly more than 3 functions, repeat.
  We have met a nested train, applying procedure to that first:
    Step 0: ⍴⍴⍴
    There are 3 or less functions, we're done.
  Step 1: ⍴⍴(⍴⍴(⍴⍴⍴))
  There are 3 or less functions, we're done.
Step 1: ⍴⍴⍴(⍴⍴)⍴((⍴⍴(⍴⍴(⍴⍴⍴)))⍴⍴)
There are strictly more than 3 functions, repeat.
We have met a nested train, applying procedure to that first:
  Step 0: ⍴⍴
  There are 3 or less functions, we're done.
Step 2: ⍴⍴⍴((⍴⍴)⍴((⍴⍴(⍴⍴(⍴⍴⍴)))⍴⍴))
There are strictly more than 3 functions, repeat.
Step 3: ⍴(⍴⍴((⍴⍴)⍴((⍴⍴(⍴⍴(⍴⍴⍴)))⍴⍴)))
There are 3 functions or less, we're done.

Вхідні дані

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

Вихідні дані

Знову ж таки, ви можете вибрати 3 різних символів, 2 для дужок та 1 для функцій. Зауважте, що вони не повинні відповідати обраним для введення даних, але вони повинні бути послідовними.

Правила

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

Тестові справи

Тут використовуються символи ()⍴, ви повинні замінити їх вибраними символами.

⍴                          -> ⍴
⍴                          -> ⍴
⍴⍴                         -> ⍴⍴
⍴⍴⍴                        -> ⍴⍴⍴
⍴⍴⍴⍴                       -> ⍴(⍴⍴⍴)
⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴            -> ⍴⍴(⍴⍴(⍴⍴(⍴⍴(⍴⍴(⍴⍴(⍴⍴⍴))))))
⍴⍴⍴⍴⍴(⍴⍴⍴)⍴⍴(⍴(⍴⍴⍴)⍴⍴⍴)⍴⍴⍴ -> ⍴(⍴⍴(⍴⍴((⍴⍴⍴)⍴(⍴(⍴(⍴⍴⍴)(⍴⍴⍴))(⍴⍴⍴)))))
(⍴⍴⍴)(⍴⍴⍴)(⍴⍴⍴)            -> (⍴⍴⍴)(⍴⍴⍴)(⍴⍴⍴)
(⍴⍴⍴)(⍴⍴⍴)⍴⍴⍴              -> (⍴⍴⍴)(⍴⍴⍴)(⍴⍴⍴)
⍴⍴(⍴)⍴⍴                    -> ⍴⍴(⍴⍴⍴)
((⍴⍴))                     -> ⍴⍴
⍴⍴((⍴⍴))⍴⍴                 -> ⍴⍴((⍴⍴)⍴⍴)

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


2
Я думаю, що повністю - це кращий заголовок, ніж явно .
Adám


@ Adám, я очікував, що ця відповідь відповідатиме, але вона не отримає багато відгуків;)
Erik the Outgolfer

@ Adám Очевидно, що частина в заголовку стосується того, що ви повинні видалити непотрібні дужки. Повністю - це те, що ви повинні робити, коли ви відповідаєте на виклик; p
Ерік Переможник

Чи правда, що ця функція завжди буде безсилою?
Esolanging Fruit

Відповіді:


7

APL (Dyalog Classic) , 71 68 65 63 байт

0{⍵≡⍕⍵:⍵⋄⍬≡⍵:'⍬'1=≢⍵:⍺∇⊃⍵⋄3≥≢⍵:⍺⌽')(',⍣⍺∊1∇¨⍵⋄⍺∇¯3(↓,∘⊂1∇↑)⍵}⍎

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

Символи , які я вибрав для введення / виведення '(', ')'і '⍬'.

Це рішення є самим поїздом APL.

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

Dfn (тобто лямбда - { }) перетинає дерево рекурсивно і перетворює його в правильно скобковий рядок. Лівий аргумент контролює, чи слід дужки додавати до поточного рівня, якщо це необхідно.

Dfn обробляє такі випадки на основі правильного аргументу:

  • якщо це вже рядок ( ⍵≡⍕⍵), поверніть його

  • якщо це так , поверніть таблицю'⍬'

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

  • якщо його довжина ≤3, повторіть повтор для кожного з елементів і оточіть, ()якщо це необхідно

  • в іншому випадку повторіть для 3-х хвоста, додайте всі, крім 3-х хвоста, та повторіть повтор


Виглядає як 63 символи, більшість з яких Unicode. Яке кодування символів виробляє 63 байти для цього? Я роблю це 141 байт в UTF8.
Корі



@ Adám Дякую за це. Я подивився, але не знав, що шукати, щоб отримати відповідь.
Корі

3

Python 2 , 224 208 204 байт

-16 байт завдяки містеру Xcoder -4 байти завдяки ов

r=str.replace
p='p'
def c(l):
 while len(l)>3:l=l[:-3]+(l[-3:],)
 return l and map(c,l)or l
print r(r(r(r(r(`c(eval(r(r(r(input(),'(p)',p),p,'[],'),')','),')))`,'[]',p),*'[('),*'])'),' ',''),',','')[1:-1]

Спробуйте в Інтернеті! або Спробуйте всі тестові приклади

Код можна розділити на 3 основні етапи:
Перетворення вводу в вкладений список та заміна (p)->p. Єдина функція pбуде замінена порожнім списком.

eval(r(r(r(input(),'(p)',p),p,'[],'),')','),'))

Рекурсивна функція застосувати правило "3 або менше" у поточному списку та викликати себе у всіх під-списках.

def c(l):
 while len(l)>3:l=l[:-3]+(l[-3:],)
 return l and map(c,l)or l

Багато замінює для форматування до потрібного вихідного формату

r(r(r(r(r(`c(...)`,'[]',p),*'[('),*'])'),' ',''),',','')[1:-1]


1
Це не спрощує ((pp))(або p((pp))p).
Мартін Ендер

2

CJam , 56 байт

Б'є APL!

lW%~]]]{{_,{K_,({~}|}&}%{_,3>}{3/(aa\+:~}w}:K~~`1>W<W%S/

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

Це працює (я думаю), і я поняття не маю, чому ...

Символи введення призначені ][Tдля ()⍴, а вихідні символи - ][0для ()⍴(так, це означає, що вони повернуті до того, що ви очікували; наприклад, ви можете перейти TTT]TT[T]TTTT]TTT[[TT).

Огляд на високому рівні

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

Потім визначаємо процедуру K. Kробить більшу частину роботи для нашого подання, і вона працює наступним чином:

  • Вхідний масив буде поєднанням нулів і непорожніх підмасивів. Визначте підмасиви та рекурсивно застосуйте Kїх. Результатом повинен бути інший масив, і якщо цей масив складається лише з одного елемента, розпакуйте його (це позбавиться від зайвих дужок).
  • Поки в результаті є більше трьох елементів, згрупуйте перші три (не останні три; пригадайте, що вхід обробляється назад) в єдиний список.
  • Поверніть результат.

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

Деякі пояснення для гольф-битів

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

  • Якщо вершина стека є цілим числом n , ,генерує діапазон [0..n) . Оскільки єдине ціле число, з яким ми стикаємось 0, це завжди дає нам порожній список [], який є фальсиєю.
  • Якщо вершиною стека є масив, ,приймає його довжину. Оскільки всі масиви, з якими ми стикаємося, будуть не порожніми, це завжди дає нам додатне ціле число, яке є truthy.

Ще один гольф, який може зацікавити - це метод, який я використовую для групування перших трьох елементів масиву; це дещо схоже на моє подання "Код повного тлумачення мови для гольфу" . У CJam немає короткого способу розбити масив на дві частини (ви можете спробувати відрізати першу частину, а потім другу частину, зберігаючи початковий масив та індекс у стеку, але це не дуже добре працює) , тому я замість цього використовую використання 3/, яке об'єднує масив у блоки по 3. Потім я можу спливати перший елемент (, обернутись у масив двічі aa, а потім додати до початку списку \+. Причина, яку ми обертаємо в масив двічі, полягає в тому, що нам потрібно зняти шар :~, оскільки ми просто згрупували решту масиву також у розділи.


Нітпік: це переможець APL без вбудованих файлів .
Ерік Аутгольфер

@EriktheOutgolfer Ярмарок досить.
Esolanging Fruit

0

JavaScript (ES6), 149 146 байт

i='a';f=s=>s==(s=s[R='replace'](/\((\w+)\)/,(q,t)=>(f[q=i+=0]=f(t),q)))&&s==(s=s[R](/(?!^)((a0+|p){3})$/,"($1)"))?s[R](/a0+/g,t=>`(${f[t]})`):f(s)
<textarea cols=80 id=I>ppp(pp)p(pppp(ppp))pp</textarea><br>
<button onclick=O.innerText=f(I.value)>Run</button><br>
<pre id=O></pre>

Використовує ()p, хоча ви використовуєте іншу букву, ви можете просто змінити pцілі до кінця.

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