Розширення брекета!


36

Ваше завдання полягає в тому, щоб розширити деякі дужки у вході програми, як показано:

  1. Знайдіть рядок s між двома співпадаючими дужками [і ]з однозначною цифрою n після дужки, що закривається.
  2. Зніміть дужки.
  3. Замініть s себе повтореним n разів. (Якщо n дорівнює 0, просто видаліть s .)
  4. Перейдіть до кроку 1, поки у введенні не буде більше відповідних дужок.

Додаткові правила та пояснення:

  • Ви будете брати вклад і давати вихід будь-якими дозволеними засобами.
  • Доступний новий рядок у висновку.
  • Вам потрібно лише обробляти друкований ASCII на вході.
  • Можна вважати , що все дужки збігаються, тобто ви ніколи не будете отримувати вхід []]]]або [[[[].
  • Ви можете припустити, що кожна закриваюча дужка ]має цифру після неї.

Тестові приклади:

Input                -> Output
[Foo[Bar]3]2         -> FooBarBarBarFooBarBarBar
[one]1[two]2[three]3 -> onetwotwothreethreethree
[three[two[one]1]2]3 -> threetwoonetwoonethreetwoonetwoonethreetwoonetwoone
[!@#[$%^[&*(]2]2]2   -> !@#$%^&*(&*($%^&*(&*(!@#$%^&*(&*($%^&*(&*(
[[foo bar baz]1]1    -> foo bar baz
[only once]12        -> only once2
[only twice]23456789 -> only twiceonly twice3456789
[remove me!]0        -> 
before [in ]2after   -> before in in after

Оскільки це , найкоротша відповідь на кожній мові виграє. Удачі!



13
Вам слід поставити черговий виклик, щоб стиснути рядок назад до найкоротшого формату
Jo King

Чи варто чітко заявляти, що ваша струна sніколи не повинна містити інших дужок? Наприклад, спроба вирішити [Foo[Bar]3]2розширення рядка в Foo[Bar3 рази призведе до недійсного стануFoo[BarFoo[BarFoo[Bar]2
BradC

@BradC все залежить від того, як ти вирішиш реалізувати завдання.
MD XF

Чи означає це, що на це є дві вагомі відповіді [a[b]2c[d]2e]2? Ви отримуєте abbcddeabbcddeшляхом розширення bі dспочатку, але ababcdbcdedbabcdbcdedeшляхом розширення a[bі d]2eпершого.
BradC

Відповіді:


13

Гема , 17 символів

[#]?=@repeat{?;#}

Проба зразка:

bash-4.4$ gema '[#]?=@repeat{?;#}' <<< '[three[two[one]1]2]3'
threetwoonetwoonethreetwoonetwoonethreetwoonetwoone

Нічого, поговоримо про пошук потрібної мови для роботи!
MD XF

Або правильна робота для мови. Багато проблем довелося пропустити, оскільки рекурсивний аргумент був недостатньо гнучким.
манатура

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


7

Haskell , 101 96 байт

fst.(""%)
infix 4%
s%']':d:r=(['1'..d]>>s,r)
s%'[':r|(t,q)<-""%r=s++t%q
s%x:r=s++[x]%r
s%e=(s,e)

Спробуйте в Інтернеті! Замість використання регулярного вираження, як більшість інших відповідей, це реалізує рекурсивний аналізатор.

-5 байт завдяки BMO !


4
Декларація про фіксацію (%)економить вам 1 байт і ['1'..d]заощаджує ще 4, див. Це .
ბიმო

3
@BMO Приємно, я не очікував, що декларація про фіксацію коли-небудь стане корисною для гольфу з кодом. Я думаю, ви повинні додати це до питання щодо підказок.
Лайконі

7

Perl 5 , 34 33 29 + 1 ( -p) = 30 байт

s/.([^[]*?)](.)/$1x$2/e&&redo

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

Скоротіть це за допомогою допомоги @Shaggy та @TonHospel.


3
Я не знаю перли, але повтор здається чудовим!
officialaimm

Я думаю, ви повинні бути в змозі зберегти байт, не уникаючи ].
Кудлатий

1
Я не знаю Perl, але це, здається, працює на 30 + 1 байт.
Кудлатий

2
Ці 29 + 1 також працюють: perl -pe 's/.([^[]*?)](.)/$1x$2/e&&redo'іperl -pe 's/.([^][]*)](.)/$1x$2/e&&redo'
Тон Євангелія

5

Japt v2 , 21 20 19 байт

Збережено 2 байти завдяки @Shaggy

e/.([^[]*?)](./@YpZ

Перевірте це в Інтернеті!

eє рекурсивною заміною, яка робить одну заміну за один раз, поки не буде більше збігів. У цьому випадку відповідність регулярного виразу /\[([^[]*?)](\d)/gзамінюється на <внутрішній текст> повторений <digit> разів, поки не буде більше збігів.

Відповідно до того, що я запланував ( тут ), цей регулярний вираз повинен бути в кінцевому рахунку принаймні на 3 2 байти коротше:

‹[“⁽[»₋”]“.›

2
Як ми « можна вважати , що кожна закриває дужка ]має цифру після » ви повинні бути в змозі замінити (\dз (..
Кудлатий

Ви також можете замінити \[на.
Shaggy

@Shaggy Приємно, дякую!
ETHproductions

4

JavaScript, 71 67 66 байт

У мене було 54-байтне рішення, але воно перекрутилося другим тестом! :(

f=s=>s!=(x=s.replace(/.([^[]*?)](.)/,(_,y,z)=>y.repeat(z)))?f(x):x

Випробування

f=s=>s!=(x=s.replace(/.([^[]*?)](.)/,(_,y,z)=>y.repeat(z)))?f(x):x
o.innerText=`[Foo[Bar]3]2
[one]1[two]2[three]3
[three[two[one]1]2]3
[!@#[$%^[&*(]2]2]2
[[foo bar baz]1]1
[only once]12
[only twice]23456789
[remove me!]0
before [in ]2after`.split`\n`.map(x=>x.padEnd(22)+`:  `+f(x)).join`\n`
<pre id=o></pre>


4

Пітон 3 , 110 93 92 байт

import re
f=lambda s:f(re.sub(r'\[([^][]+)\](.)',lambda m:m[1]*int(m[2]),s))if'['in s else s

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

-17 байт завдяки pizzapants184 -1 байт завдяки Kevin Cruijssen


1
-17 байт у Python 3 з використанням індексації re.match та перевірки підрядків in.
pizzapants184

1
-1 байт, змінивши (\d)на (.), тому що ми знаємо, що блок-дужка ]завжди супроводжується цифрою.
Kevin Cruijssen

4

Scala , 173 байт

l.foreach{x=>def r(c:String):String={val t="""\[([^\[\]]*)\](.)""".r.unanchored;c match{case t(g,h)=>r(c.replaceAllLiterally(s"[$g]$h",g*h.toInt));case _=>c}};println(r(x))}

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

Розширено:

l.foreach { x =>
  def remove(current: String): String = {
    val test ="""\[([^\[\]]*)\](.)""".r.unanchored
    current match {
      case test(g, h) => remove(current.replaceAllLiterally(s"[$g]$h", g * h.toInt))
      case _ => current
    }
  }

  println(remove(x))
}

Старе рішення

Scala , 219 215 213 212 199 байт

l.foreach{x=>def r(c:String):String={"""\[([^\[\]]*)\](.)""".r.findFirstMatchIn(c).map{x=>val g=x.group(1);val h=x.group(2).toInt;r(c.replaceAllLiterally(s"[$g]$h",g*h))}.getOrElse(c)};println(r(x))}

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

Розширено:

l.foreach { x =>
  def remove(current: String): String = {
    """\[([^\[\]]*)\](.)""".r.findFirstMatchIn(current).map { x =>
      val g = x.group(1)
      val h = x.group(2).toInt
      remove(current.replaceAllLiterally(s"[$g]$h", g * h))
    }.getOrElse(current)
  }
  println(remove(x))
}

Де l - список рядків, які ми обробимо.

Дякую Кевіну Крейсейну за -1 байт

Пішов з 212 до 199, видаливши невикористаний параметр, не звернув уваги.


4
Ласкаво просимо до PPCG! Спробуйте перекладач Scala tio на сайті tio.run/#scala і подивіться, чи можете ви надіслати посилання для відповіді, щоб інші могли спробувати його в Інтернеті. :)
officialaimm

2
Дякую! Я відредагував відповідь, щоб включити посилання. Сподіваємось, це нормально, як оголошується заголовок, код і колонтитул, щоб бути правильним поданням.
Шикко

1
Привіт, Ласкаво просимо до PPCG! Чудова перша відповідь, +1 від мене. Я думаю, що ви можете зберегти 1 байт, змінивши (\d)на (.), тому що ми знаємо, що блок-дужка ]завжди супроводжується цифрою.
Kevin Cruijssen

3

Складено , 39 38 байт

Збережено 1 байт завдяки Шаггі, погравши в реджекс!

['\[([^[\]]+)](.)'{.y x:x#~y*}recrepl]

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

Просто рекурсивно замінює регулярний вираз '\[([^[\]]+)](.)'правилом повторення.


Я думаю, ви можете зберегти байт, не уникнувши останнього ].
Кудлатий


3

JavaScript - 77 75 72 байти

f=a=>a.replace(/(.*)\[([^[]*?)](.)(.*)/,(a,b,c,d,e)=>f(b+c.repeat(d)+e))

Редагувати: оновлений регулярний вираз із рекомендацією Шаггі

Фрагмент:


2
Ласкаво просимо до PPCG! Ви можете звести це до 70 байт , налаштувавши RegEx.
Кудлатий

Так, 72 байти, очевидно, вибачте; Я забував рахувати f=!
Кудлатий

2

QuadR з аргументом, 30 28 байт

\[[^[]+?].
∊(⍎⊃⌽⍵M)⍴⊂1↓¯2↓⍵M

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

\[[^[]+?]. замінити « [не- [речі ]символ» з

¯2↓⍵M скиньте останні два символи M atch (" ]цифра"), укажіть
1↓ перший символ (" ["),
 додайте, щоб його розглядали як ціле
(... )⍴r Настроїть на довжину:
⌽⍵M переверніть M atch,
 виберіть першу (цифру)
 оцінку
ϵ nlist ( згладити)

 повторюйте, поки більше не відбудеться змін


Еквівалентна функція APL Dyalog - 47 байт:

'\[[^[]+?].'R{∊(⍎⊃⌽⍵.Match)⍴⊂1↓¯2↓⍵.Match}⍣≡

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


2

Java 8, 250 249 241 239 байт

s->{for(;s.contains("[");)for(int i=0,j,k;i<s.length();)if(s.charAt(i++)==93){String t="",r=t;for(j=k=s.charAt(i)-48;j-->0;)t+=s.replaceAll(r="(.*)\\[([^\\]]+)\\]"+k+"(.*)","$2");s=k<1?t:s.replaceFirst(r,"$1$3").replace("",t);}return s;}

-2 байти завдяки @JonathanFrech (код містить два недрукованих символи ASCII, які можна побачити у TIO-посилання нижче).

Зітхніть ... Java з регулярним виразом настільки проклято обмежена. Я просто цитую себе з іншої відповіді тут:

Заміна WWWWз 222Wлегко в Java, але 4Wнемає .. Якщо тільки Java був спосіб використовувати регулярний вираз захоплення-група що - то .. Отримання довжини з "$1".length(), замінивши сам матч з "$1".replace(...), що перетворює матч до цілого числа з new Integer("$1"), або з допомогою щось подібне, як Retina (тобто s.replaceAll("(?=(.)\\1)(\\1)+","$#2$1"))або JavaScript (тобто s.replaceAll("(.)\\1+",m->m.length()+m.charAt(0))) - це моя річ номер 1, яку я хотів би бачити в Java в майбутньому, щоб скористатися codegolfing ..>.> Я думаю, що це 10-й + час, який я ненавиджу Java не можу зробити з матчем групи захоплення ..
Цитата звідси.

Пояснення:

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

s->{                           // Method with String as both parameter and return-type
  for(;s.contains("[");)       //  Loop as long as the String contains a block-bracket
    for(int i=0,j,k;i<s.length();)
                               //   Inner loop over the characters of the String
      if(s.charAt(i++)==93){   //    If the current character is a closing block-bracket:
        String t="",r=t;       //     Create two temp-Strings, starting empty
        for(j=k=s.charAt(i)-48;//     Take the digit after the closing bracket
            j-->0;)            //     Loop that many times:
          t+=s.replaceAll(r="(.*)\\[([^\\]]+)\\]"+k+"(.*)","$2");
                               //      Append `t` with the word inside the block brackets
        s=k<1?                 //     If the digit was 0:
           t                   //      Replace the input with an empty String as well
          :                    //     Else:
           s.replaceFirst(r,"$1$3").replace("",t);}
                               //      Replace the word between brackets by `t`,
                               //      and remove the digit
  return s;}                   //  Return the modified input-String as result

1
Я думаю, ви можете використовувати справді ASCII, хоча і недрукований символ, щоб зберегти два байти . (Ваше рішення дійсно займає 241 байт, 239 символів.)
Джонатан Фрех

@JonathanFrech Дякую! Шукав 1-байтний символ за межами діапазону ASCII для друку. Не думав про те, щоб скористатися недрукованим
файлом


2

С, 407 368 байт

Дякую Джонатану Фреху за збереження байтів.

гольф (файл bracket.c):

i,j,k,l,n;char*f(a,m)char*a;{for(i=0;a[i];++i){a[i]==91&&(j=i+1);if(a[i]==93){k=a[i+1]-48;if(!k){for(l=i+2;l<m;)a[++l-i+j-4]=a[l];a=realloc(a,m-3);return f(a,m-3);}for(l=j;l<i;)a[~-l++]=a[l];for(l=i+2;l<m;)a[++l-4]=a[l];m-=3;n=m+~-k*(i---j--);a=realloc(a,n);for(l=i;l<m;)a[l+++~-k*(i-j)]=a[l];for(m=0;m<k;++m)for(l=j;l<i;)a[l+++m*(i-j)]=a[l];return f(a,n);}}return a;}

невольф з програмою:

#include <stdlib.h>
#include <stdio.h>

// '[' = 133
// ']' = 135
// '0' = 48

i, j, k, l, n;

char* f(a,m) char*a;
{
  for (i=0; a[i]; ++i) {
    a[i]==91&&(j=i+1);

    if (a[i]==93) {
      k=a[i+1]-48;

      if (!k) {
        for (l=i+2; l<m; )
          a[++l-i+j-4] = a[l];

        a = realloc(a,m-3);
        return f(a,m-3);
      }
      for (l=j;l<i;)
        a[~-l++] = a[l];
      for (l=i+2; l<m; )
        a[++l-4] = a[l];
      m -= 3;
      n = m+~-k*(i---j--);
      a = realloc(a,n);

      for (l=i; l<m; )
        a[l+++~-k*(i-j)] = a[l];
      for (m=0; m<k; ++m)
        for (l=j; l<i;)
          a[l+++m*(i-j)] = a[l];

      return f(a,n);
    }
  }
  return a;
}

int main()
{
  char c[]="[Foo[Bar]3]2";
  char *b;

  char cc[]="[remove me!]0";
  char *bb;

  char ccc[]="[only once]12";
  char *bbb;

  b=malloc(13);
  bb=malloc(14);
  bbb=malloc(14);

  for (i=0; i<13; ++i)
    b[i] = c[i];

  for (i=0; i<14; ++i)
    bb[i] = cc[i];

  for (i=0; i<14; ++i)
    bbb[i]=ccc[i];

  printf("%s\n", f(b, 13));
  printf("%s\n", f(bb, 14));
  printf("%s\n", f(bbb, 14));

  return 0;
}

Складено з gcc 5.4.1, gcc bracket.c



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

Якщо ви використовуєте GCC, я думаю, що компілятор спробує відгадати визначення обох mallocі realloc, в тому числі stdlib.h, власних.
Джонатан Фрех

Я цього не знав. Хороша особливість для коду в гольф. Спасибі.
Цатогуа

2

Червоний , 147 байт

f: func[t][a: charset[not"[]"]while[parse t[any a some[remove["["copy h any a"]"copy d a](insert/dup v: copy""h to-integer d)insert v | skip]]][]t]

Безголівки:

f: func [t][
    a: charset [not "[]"]                          ; all chars except [ and ]
    while [ parse t [                              ; repeat while parse is returning true
        any a                                      ; 0 or more chars other than [ and ]
        some [                                     ; one or more block:
            remove ["[" copy h any a "]" copy d a] ; remove the entire block, store the
                                                   ; substring between the [] in h,
                                                   ; the digit into d
            (insert/dup v: copy "" h to-integer d) ; makes d copies of h 
            insert v                               ; and inserts them in place 
            | skip ]                               ; skip if no match
        ]                                       
    ][]                                            ; empty block for 'while'
    t                                              ; return the modified string
]

Я почав вивчати діалект Red's Parse лише вчора, тому впевнений, що мій код можна вдосконалити. Синтаксичний розбір незрівнянно більш багатослівний, ніж регулярний вираз, але він дуже чіткий, гнучкий і читабельний і може вільно змішуватися з рештою червоної мови.

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


1

Желе , 30 байт

œṡ”]µḢUœṡ”[ẋ€1¦Ṫ©Ḣ$FṚ;®
Çċ”]$¡

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


Пояснення.


œṡ”]µḢUœṡ”[ẋ€1¦Ṫ©Ḣ$FṚ;®    Helper link 1, expand once.
                           Assume input = "ab[cd]2ef".

œṡ      Split at first occurence of
  ”]      character "]".
    µ   Start new monadic chain. Value = "ab[cd","2ef".

Ḣ       ead. "ab[cd"
 U      Upend. "dc[ba"
  œṡ”[  Split at first occurence of "[". | "dc","ba".

ẋ€        Repeat ...
  1¦        the element at index 1...
          by ...
    Ṫ Ḣ$    the ead of the ail of ...
          the input list ("ab[cd","2ef") (that is, 2)

          The command  also pop the head '2'. The remaining
            part of the tail is "ef".
     ©    Meanwhile, store the tail ("ef") to the register.

          Current value: "dcdc","ba"
FṚ        Flatten and everse. | "abcdcd"
  ;®      Concatenate with the value of the register. "abcdcdef"

Çċ”]$¡    Main link.

 ċ”]$     Count number of "]" in the input.
     ¡    Repeatedly apply...
Ç           the last link...
            that many times.

1

C, 381 байт

Компактна версія:

while(1){int t=strlen(i);int a,c=-1;char*w;char*s;char*f;while(c++<t){if(i[c]==']'){int k=c-a;w=calloc((k--),1);memcpy(w,&i[a+1],k);s=calloc((t-c-1),1);memcpy(s,&i[c+2],t-c-2);i[a]=0;int r=i[c+1]-48;if(r==0){f=calloc(t,1);sprintf(f,"%s%s",i,s);}else{f=calloc((t+k),1);sprintf(f,"%s%s[%s]%d%s",i,w,w,r-1,s);}free(i);i=f;break;}else if(i[c]=='[')a=c;}free(w);free(s);if(c>=t)break;}

Повна версія:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

void proceed(char* input)
{
  while(1)
  {
    int t=strlen(input);
    int start,cursor=-1;
    char* word;
    char* suffix;
    char* final;
    while(cursor++<t)
    {
      if(input[cursor]==']')
      {
        int wordlength = cursor-start;
        word=calloc((wordlength--),sizeof(char));
        memcpy(word, &input[start+1], wordlength );
        suffix=calloc((t-cursor-1),sizeof(char));
        memcpy( suffix, &input[cursor+2], t-cursor-2 );
        input[start]='\0';
        int rep=input[cursor+1]-'0';
        if(rep==0)
        {
          final=calloc(t,sizeof(char));
          sprintf(final,"%s%s",input,suffix);
        }
        else
        {
          final=calloc((t+wordlength+5),sizeof(char));
          sprintf(final,"%s%s[%s]%d%s",input,word,word,rep-1,suffix);
        }
        free(input);
        input=final;
        break;
      }
      else if(input[cursor]=='[')
        start=cursor;
    }
    free(word);
    free(suffix);

    if(cursor>=t)break;
  }
}

int main()
{
  char* input=calloc(256,sizeof(char));
  sprintf(input,"a[[toto]2b]2[ana]3");
  printf("in : %s\n",input);
  proceed(input);
  printf("out: %s\n",input);
  return 0;
}

3
Ласкаво просимо до PPCG!
Кудлатий

1
Ласкаво просимо на сайт! Зауважте, що матеріали C повинні бути повноцінними програмами або функціями, а не лише фрагментами.
MD XF

1

Пітон, 80 байт

import re
b=re.sub
s=lambda x:eval(b(r"\](.)",r"')*\1+'",b(r"\[","'+('","%r"%x)))

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

s("[Foo[Bar]3]2")Перетворює [Foo[Bar]3]2на''+('Foo'+('Bar')*3+'')*2+'' та оцінює.

Помилка введення з лапками в дужках (наприклад [']3)


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