Уніміфікуйте стрункоподібну струну


13

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

Код Pyth часто важко читати. Навіть вихід з режиму налагодження (транспільований Python) часто складається з довгого рядка, іноді з дужками, вкладеними на десять глибин. Однак правильно відформатований Pyth дуже читабельний.

Ось фрагмент коду Pyth, написаний @isaacg у Play The Word Word .

.MlZfqhMtTeMPT+Lzs.pMyQ

Це набагато читабельніше, як це.

.M                     Filter by gives-maximal-value of
   l Z                   lambda Z:length(Z) over
   f                     filter by (lambda T:
     q                     equal
       hM t T                head-map tail T
       eM P T                end-map Pop T)
     +L                    Append z to each element in
        z                        
        s .pM y Q            flattened permutations of each subset of Q

Для цього виклику ми усуваємо аспект колмогорова при категоризації символів Pyth та зосереджуємось на форматуванні. Замість того, щоб бути Pyth-кодом, вхід буде складатися з символів у 0123456789M. Цифра nявляє собою функцію арійності nі Mявляє собою оператор. Наприклад, наведений вище код представлений як 210221M101M102M011M10. Ось такі кроки для зменшення змін:

Відокремте рядок на лексеми.

Маркер відповідає [0-9]M*. 0Mне відбудеться при введенні.

Додайте останні 0.

Коли аргументів недостатньо, Pyth додає Qдо коду стільки неявних змінних (лямбда-змінних чи s), скільки необхідно для заповнення аргументів програми; вони повинні бути представлені 0s.

Групуйте жетони в рядки.

Аритність токена - це значення його цифри.

  • Маркер arity-0 (тобто 0) закінчує рядок.

  • Для токена arity-1 наступний жетон повинен переходити на ту саму лінію, розділену пробілом.

  • Для лексеми arity> = 2 його аргументи йдуть в окремі рядки, в порядку, в якому вони відображаються в коді, за кожним з них слідують власні субаргументи тощо. Аргументи на маркер відступають до кінця цього маркера плюс один пробіл.

Вхідні дані

Непорожній рядок (або масив char, масив рядків довжиною-1 тощо), дозволених стандартними методами вводу-виводу), що складається з 0123456789M, який не буде містити підрядку 0M.

Вихідні дані

Рядок відформатований відповідно до вищезазначених правил.

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

210221M101M102M011M10

2
  1 0
  2
    2
      1M 1 0
      1M 1 0
    2M
       0
       1 1M 1 0


123M4M

1 2
    3M
       4M
          0
          0
          0
          0
       0
       0
    0


2MM

2MM
    0
    0


11011100

1 1 0
1 1 1 0
0


9000000

9
  0
  0
  0
  0
  0
  0
  0
  0
  0

Питання, пов’язані з цим: codegolf.stackexchange.com/questions/47798/…
lirtosiast

Чи можу я взяти вхід як масив цифр / рядків? Прикладом 210221M101M102M011M10може бути[2,1,0,2,2,1,'M',1,0,1,'M',1,0,2,'M',0,1,1,'M',1,0]
Luis felipe De jesus Munoz

@LuisfelipeDejesusMunoz Ні, якщо тільки стандартні правила вводу-виводу не вимагають, щоб ви дозволили (що я не думаю, що вони роблять.) IMO, це трохи змінить виклик, якщо Ms може бути іншим типом даних від цілих чисел.
lirtosiast

@lirtosiast Отже, масив символів / односимвольних рядків добре, лише не використовуючи різні типи даних між цифрами та M?
Каміль Дракарі

1
@LeakyNun Порожній рядок зараз не визначений.
lirtosiast

Відповіді:


1

JavaScript (ES8), 160 159 байт

f=(s,a=[d=0,p=[1]])=>s.replace(/(.)M*/g,(s,c)=>(g=_=>a[d]?s+(P=p[d]-=c--&&~s.length,c?`
`.padEnd(P):' '):g(d--))(a[d]--,a[++d]=+c,p[d]=p[d-1]))+(d?f('0',a):'')

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

Прокоментував

f = (                          // f = recursive function taking:
  s,                           //   s   = input string
  a = [                        //   a[] = array holding the number of expected arguments
    d = 0,                     //   d   = current depth, initialized to 0
    p = [1]                    //   p[] = array holding the padding values
  ]                            //
) =>                           //
  s.replace(                   // search in s all substrings
    RegExp('(.)M*', 'g'),      // consisting of a digit followed by 0 to N 'M' characters
    (s, c) =>                  // for each substring s beginning with the digit c:
      ( g = _ =>               //   g = recursive function
          a[d] ?               //     if we're still expecting at least one argument at
                               //     this depth:
            s + (              //       append s
              P = p[d] -=      //       update the padding value P = p[d] for this depth:
                c-- &&         //         decrement c; unless c was equal to 0,
                ~s.length,     //         add the length of s + 1 to p[d]
              c ?              //       if c is not equal to 0 (i.e. was not equal to 1):
                `\n`.padEnd(P) //         append a linefeed followed by P - 1 spaces
              :                //       else:
                ' '            //         append a single space
            )                  //
          :                    //     else (all arguments have been processed):
            g(d--)             //       decrement the depth and call g again
      )(                       //   before the initial call to g:
        a[d]--,                //     decrement the number of arguments at depth d
        a[++d] = +c,           //     set the number of arguments for the next depth
        p[d] = p[d - 1]        //     set the padding value for the next depth,
      )                        //     using a copy of the previous depth
  ) + (                        // end of replace()
    d ?                        // if we're not back at depth 0:
      f('0', a)                //   do a recursive call to f with an extra '0'
    :                          // else:
      ''                       //   stop recursion
  )                            //

1

Haskell , 192 190 187 байт

unlines.snd.f
f(n:r)|(m,t)<-span(>'9')r,(s,l)<-n#t=(s,n?((n:m):map((' '<$(n:n:m))++)l))
f e=(e,["0"])
'1'?(a:b:r)=(a++drop(length a)b):r
_?s=s
'0'#s=(s,[])
n#s|(r,l)<-f s=(l++)<$>pred n#r

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

Повинно бути кращим способом обробки справи arity-1, він наразі займає 45 байт.

Зміни:

  • -2 байти шляхом переходу на інший метод обробки 1, хоча попередній метод, мабуть, має більший потенціал оптимізації.
  • -3 байти, не перетворюючи цифри символів у числа та не використовуючи predзамість них n-1.
unlines.snd.f
f(n:r)|(m,t)<-span(>'9')r,(s,l)<-read[n]#t,w<-map((' '<$(n:n:m))++)=(s,last$((n:m):w l):[(n:m++' ':h):w t|n<'2',h:t<-[l]])
f e=(e,["0"])
0#s=(s,[])
n#s|(r,l)<-f s=(l++)<$>(n-1)#r

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


1

Вугілля деревне , 75 байт

FS⊞υ⎇⁼ιM⁺⊟υιι≔⮌υυ≔⟦⟧θ≔⟦⟧ηW∨υη«≔⎇υ⊟υ0ιι¿⊖Σι↘→⊞θι⊞ηΣιW∧η¬§η±¹«⊟ηM⊕L⊟θ←¿η⊞η⊖⊟η

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Пояснення:

FS⊞υ⎇⁼ιM⁺⊟υιι

Переведіть курсор на символи введення та перетворіть їх у список цифр із необов'язковими Mсуфіксами.

≔⮌υυ

Переверніть цей список, щоб ми могли використовувати його Popдля споживання.

≔⟦⟧θ

Ця змінна являє собою стек жетонів, чия складність ще не виконана.

≔⟦⟧η

Ця змінна є стеком залишків масиву невиконаних лексем.

W∨υη«

Повторюйте, поки ми не спожили всі жетони та не випорожнили стопку.

     ≔⎇υ⊟υ0ι

Отримайте наступний жетон або його 0немає.

     ι¿⊖Σι↘→

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

     ⊞θι⊞ηΣι

Додайте маркер та його арність до відповідних змінних.

     W∧η¬§η±¹«

Повторіть, поки стек масиву не є порожнім, але верхня аритація дорівнює нулю.

              ⊟η

Відмовтеся від нульової арності.

              M⊕L⊟θ←

Видаліть його маркер і перемістіть стільки символів.

              ¿η⊞η⊖⊟η

Якщо залишилися артії, то декрементуйте верхню артью.

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