Розгорніть закодований рядок


18

Існує класичне кодування і декодування довжини пробігу.

input   output
a3b2c5  aaabbccccc

І це досить прямо вперед і робилося раніше.

Завдання полягає також у врахуванні нестандартної поведінки, коли декілька символів передують довжині пробігу ( одна цифра від 0-9). Кожен символ перед цифрою довжини виконання (остання цифра перед нецифровою чи кінцевою ланцюжком) має це значення, яке застосовується до нього окремо і друкується в порядку.

Деякі тестові вхідні та вихідні дані, включаючи деякі крайні регістри

input   output
ab3c5   aaabbbccccc
a0b3    bbb  
13b1    111b
a13b1   aaa111b
a123b1  aaa111222b
aa2a1b1 aaaaab
  • Послідовність символів ( [a-zA-Z0-9]+) повинна дотримуватися її довжини виконання ( [0-9])
  • Необхідно враховувати лише дійсні дані ( ([a-zA-Z0-9]+[0-9])*)
    • так, порожній рядок є коректним введенням.
  • Введення здійснюється через стандартний вхід, вихід - через стандартний вихід

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


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

4
@MichaelT Оцінка символів сильно заохочує стиснення вихідного коду до UTF32, що дозволяє кодувати до 4 байтів на символ, але є абсолютно нечитабельним.
isaacg

ярмарок @isaacg 'nuff. Я відредагую, щоб змінити байти. Я роздумую над тим, щоб висловити стиль ескізів, щоб бути прийнятним для майбутніх викликів.

Чи слід подати наше повідомлення без помилок, якщо вхід є порожнім рядком? Консенсус по мете , що вихід на STDERR може бути проігнорований, але так як ви явно говорили про це, я повинен запитати.
Денніс

@Денніс порожній рядок, як слід вводити, повинен зупинитися. Він не повинен переходити в нескінченний цикл або друкувати інший текст на стандартний вихід.

Відповіді:


3

Піп, 22 + 1 = 23 байти

Використовує -rпрапор. Зауважте, що для цього потрібно: 1) ввести EOF після входу (Ctrl-D в Linux, Ctrl-Z в Windows) або 2) передати вхід десь з іншого місця.

(^_@<v)X_@vMa@`\D*\d+`

Пояснення:

                        a is first line of stdin (from -r flag) and v is -1 (implicit)
              `\D*\d+`  Pattern (regex) object that matches zero or more non-digits
                        followed by at least one digit
            a@          Find all non-overlapping matches in a, returning a list of strings
           M            To that list, map a lambda function:
  _@<v                    Argument sans last character (equivalent to Python a[:-1])
(^    )                   Split into a list of characters
        _@v               Last character of argument
       X                  Repeat each character of the list that many times
                          (String multiplication X, like most operators, works item-wise
                          on lists)
                        Auto-print (implicit)

Результатом операції з картою є фактично список списків, але за замовчуванням списки просто об'єднуються разом при друкуванні, тому не потрібно вручну перетворювати на рядок.

Приклад, із введенням a13b1:

Var a gets        "a13b1"
After regex match  ["a13" "b1"]
After map          [["aaa" "111"] ["b"]]
Final output       aaa111b

Pip має базову підтримку регулярного виразів станом на ... 2 дні тому . Чудові терміни!


Той, хто працює (і так робить майстер) з -rпрапором. (Питання вказує, що дані повинні надходити від STDIN.)
Денніс,

@Dennis На жаль, це пропустив. Додано прапор до кількості байтів. Я повинен був би мати можливість використовувати спеціальну змінну qзамість aбез зайвих прапорів, але, здається, є помилка, і вона просить ввести двічі.
DLosc

Нарешті мова про гольф із підтримкою регулярного вибору!
Денніс

@ Денніс, я бачу, як ти перейшов на піп зараз!
Оптимізатор

8

Перл / Баш 54 40 + 1 = 41 байт

perl -pe's:(\D*\d*)(\d):"\$1=~s/./\$&x$2/egr":ege'

Це в основному регулярний вираз в рамках регулярного вираження. І трохи магії.

Пояснення

Зовнішній вираз /(\D*\d*)(\d)/gвитягує кожну групу кодованих довжиною прогону. Ми фіксуємо матеріал для повторення $1та кількість повторень у $2. Тепер ми замінюємо кожну таку групу розширенням цієї групи. Для цього ми оцінюємо код "\$1=~s/./\$&x$2/egr" два рази (як за /eeпрапором на зовнішній підстановці).

Перша оцінка лише інтерполюватиме кількість повторень у рядок - інші змінні захищені косою рисою. Отже, припускаючи вхідa14 , у нас зараз буде код $1=~s/./$&x4/egr, який буде оцінено знову.

Це застосує заміну до вмісту $1(матеріал для повторення a1). Заміна відповідає кожному символу .. $&Мінлива містить весь матч, який ми повторювати x4раз. Ми робимо це на /gмісцевому рівні для кожного матчу та/r замінюємо заміщену рядок, а не змінюємо $1змінну (яка є лише для читання). Тож результат внутрішньої підстановки є aaaa1111.

-pПрапора застосовує заміну кожної вхідної лінії , і виводить результат.


3
Це прийнято оцінювати це як рішення Perl, де ви просто додаєте 1 байт для -pмодифікатора. Я рахую 45 байт. Крім того, ви повинні мати можливість використовувати \Dзамість [a-z], що також усувало необхідність i.
Денніс

7

CJam, 33 31 27 байт

Так, відсутність регулярних виразів робить це досить довгим ...

qN+{:XA,s&L\:L>{])~e*[}&X}%

Як це працює

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

(Трохи застаріле розширення коду)

q{                       }%        e# Read the input (q) and loop through each character
  L                                e# Put variable L (initially empty character) on stack
   A,                              e# Put variable A (equals 10) and create an array 0..9
     s                             e# Convert the array to string "0123456789"
      &                            e# Do a set intersect b/w previous char and 0-9 string
                                   e# If numeric, it gives 1 char string, otherwise 0
       \:LA,s&                     e# Swap to bring current character on top. Store it in L
                                   e# and do the same set intersect with it
              >                    e# Means we are checking that current char is non-numeric
                                   e# and previous numeric
               {      }&           e# Run this block if above is true
                ])~                e# Wrap everything not already repeated in an array and
                                   e# take out the last character and convert it to integer.
                                   e# This is the run length of the preceding string
                   e*              e# Repeat each character in the string, run length times
                     [             e# Start a new array to help when next run length is found
                        L          e# Restore the current character back on stack to be used
                                   e# in next iteration
                           )~e*    e# The last string-run-length pair is not decoded..
                                   e# So we do that now

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


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

6

rs , 43 71 chars

Ну, це швидко вийшло. Дурні номери ...

(\d)(\D)/\1 \2
+(\w)(\w+?)(\d)(?= |$)/\1\3 \2\3
(\w)(\d)/(\1)^^(\2)
 /

Спробуйте тут!

Оригінальна версія (не працювала з таким входом 123):

+(\D)(\D+)(\d)/\1\3\2\3
(\D)(\d)/(\1)^^(\2)

Пояснення

Перший рядок розміщує пробіли між прогонами, що містять числа, наприклад, перетворення a313вa3 13 .

Другий рядок безперервно розширює стиснені кодування, як aa5і ранішеa5a5 .

Третій рядок перетворює кожен екземпляр a5у aaaaaвикористання оператора повторення .

Останній рядок видаляє пробіли.


Як це впорається a123b1?
Оптимізатор

@Optimizer Не дуже. Мені потрібно трохи підправити ...
kirbyfan64з

Виправлено @Optimizer.
kirbyfan64sos

5

Javascript ( ES6 ), 86 83 байт

alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>b.replace(/./g,y=>y.repeat(c))))

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

alert( // output final result
    prompt(). // take input
    replace(/(.+?)(\d)(?!\d)/g, // replace ungreedy capture group of any characters 
                                // followed by a digit (captured)
                                // and not followed by a digit (negative lookahead)
        (a, b, c)=> // replace with a function
            b.replace(/./g, // replace all characters in b
                y=>y.repeat(c) // with that character repeated c times
            )
    )
)

Не alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>Array(c+1).join(b)))зробиш те ж саме? Це всього 71 байт.
Ісмаїл Мігель

@IsmaelMiguel, який би працював, лише якщо перед цифрою був один символ. Поняття масиву обробляє повторення кожного символу окремо.
nderscore

Спробуйте, Array(6).join('12')і воно повернеться '1212121212'.
Ісмаїл Мігель

Цей працює: alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>Array(-~c).join(b)))(той самий 71 байт, протестований на es6fiddle.net/ia7gocwg )
Ісмаель Мігель

1
Я знайшов інший (очевидний) спосіб сказати 3 байти: D
nderscore

4

CJam, 27 25 байт

r_'A+1>.{64&1$>{])~f*o}&}

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

Як це працює

r_                        e# Read a token from STDIN and push a copy.
  'A+                     e# Append the character A to the copy.
     1>                   e# Discard the first character of the copy.
       .{               } e# For each character C of the input string and the
                          e# corresponding character D of the copy:
         64&              e#   Take the bitwise and of D and 64. This pushes @
                          e#   if D is a letter and NUL if it is a digit.
            1$>           e#   Compare the result to a copy of C. This pushes 1
                          e#   if and only if D is a letter and C is a digit.
               {      }&  e#   If the result was 1, do the following:
                ]         e#     Wrap the stack in an array.
                 )~       e#     Pop and evaluate the last character.
                   f*     e#     Repeat each char in the array that many times.
                     o    e#     Print all characters.

3

Pyth, 33 32 28 байт

ssmm*vedkPdPcz-hMJf<@zT\=UzJ

Спробуйте в Інтернеті: Демонстрація або Тест-джгут

Пояснення

Я поясню код на прикладі введення aa1a23b2. Сподіваємось, це трохи простіше прослідкувати, ніж без.

                               implicit: z = input string = 'aa1a23b2'
                         Uz    the indices of z: [0, 1, 2, 4, 5, 6, 7]
                  f            filter for indices T, which satisfy:
                   <@zT\=        z[T] < "="
                               this gives us the list of indices [2, 4, 5, 7], 
                               which correspond to digits in z. 
                 J             assignment, J = [2, 4, 5, 7]
               hMJ             increment all element in J: [3, 5, 6, 8]
              -            J   and remove the elements of J:
                                 [3, 5, 6, 8] - [2, 4, 5, 7] = [3, 6, 8]
            cz                 split z at these indices: ['aa1', 'a23', 'b2', '']
           P                   remove last element: ['aa1', 'a23', 'b2']
  m                            map each string d to:
   m     Pd                      map each string k of d-without-last-char to:
     ved                           int(last element of d)
    *   k                          * k
                               this creates [['a', 'a'], ['aaa', '222'], ['bb']]
 s                             sum the lists: ['a', 'a', 'aaa', '222', 'bb']
s                              sum the strings: 'aaaaa222bb'



2

Python 2.7, 98 байт

import re
print"".join(c*int(m[-1])for m in 
re.findall(r".+?\d(?!\d)",raw_input())for c in m[:-1])

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


Ви можете зберегти 2 байти, перейшовши з Python 2 на 3. raw_inputстає, inputале printпотрібні дужки.
Олексій А.

Щоправда, але я віддаю перевагу гольфу в пітон 2.7.
рекурсивна

1

Джулія, 105 99 95 87 байт

s->join([join([string(b)^(int(p[end])-48)for b=chop(p)])for p=matchall(r"\D*\d*\d",s)])

Це створює неназвану функцію, яка приймає рядок як вхід a повертає рядок. Щоб зателефонувати, дайте ім’я, наприклад f=s->....

Тут використовуються два розуміння масиву, одне вкладене в інше. Зовнішнє розуміння діє на кожну відповідність вхідного рядка проти регулярного виразу \D*\d*\d. Внутрішнє розуміння повторює кожен символ відповідності відповідно до кінцевої цифри. Елементи внутрішнього масиву об’єднані в рядок, тому зовнішній масив - це масив рядків. Вони приєднуються та повертаються.

У Джулії рядки можна обробляти як масиви символів. Однак зауважте, що Charі Stringв Julia типи не визначені однакові методи; зокрема, не існує методу повторення використання ^символів. Для цього використовується спільне вирішення:

  • Проведіть петлю над рядком, опускаючи останній символ, який видаляється за допомогою chop().
  • Перетворити поточний символ у рядок за допомогою string() .
  • Перетворіть кінцеву цифру, яка також є символом, у ціле число. Однак зауважте, що, наприклад, int('4')не повертається 4. Скоріше, він повертає кодову точку, яка в даному випадку дорівнює 52. Таким чином, ми можемо відняти 48, щоб повернути фактичне ціле число.
  • Повторіть string(b)відповідно до int(p[end]) - 48.

Приклади:

julia> f("ab3c5")
"aaabbbccccc"

julia> f("a0b3")
"bbb"

julia> f("13b1")
"111b"

1

Пітон 3, 148 144 136 135 Байт

w,o,r,d=''.join,'',[],[]
for c in input()+' ':
 if'/'<c<':':d+=[c]
 elif d:o+=w(x*int(w(d))for x in r);r=[c];d=[]
 else:r+=[c]
print(o)

Дякуємо Pietu1998 та mbomb007 за пропозиції.

Пітон 2, 161 151 147 139 138 байт

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

w,o,r,d=''.join,'',[],[]
for c in raw_input()+' ':
 if'/'<c<':':d+=[c]
 elif d:o+=w(x*int(w(d))for x in r);r=[c];d=[]
 else:r+=[c]
print o

3
Змінення на Python 3 економить пару байтів ( raw_з дужок, дужок print). len(d)>0можна замінити, dоскільки порожній список є хибним, а не порожній список - правдою. list(...)може перейти прямо до for. Квадратні дужки w([...])не потрібні, оскільки це єдиний аргумент. Ви можете видалити місце в ) for. Ось і все другорядне, що я придумав поки що.
PurkkaKoodari

@ Pietu1998 Дякуємо за допомогу!
Каде

Не надто сильно змінюючи підхід, ви можете позбутися, list()оскільки рядки є ітерабельними. Можна використовувати w=r=''. Якщо ви готові багато чого змінити, дивіться моє рішення. :)
рекурсивна

if c.isdigit()може стати if'/'<c<':', якщо я не помиляюся.
DLosc

@DLosc дякую, що, здається, працює.
Каде

0

Java 7, 175 байт

String c(String s){String r="",a[];for(String x:s.split("(?<=(\\d)(?!\\d))")){a=x.split("");for(int i=0,j,l=a.length-1;i<l;i++)for(j=0;j++<new Short(a[l]);r+=a[i]);}return r;}

Завдання складніше, ніж здається, ..

Невикористаний і тестовий код:

Спробуйте тут.

class M{
  static String c(String s){
    String r = "",
           a[];
    for(String x : s.split("(?<=(\\d)(?!\\d))")){
      a = x.split("");
      for(int i = 0, j, l = a.length-1; i < l; i++){
        for(j = 0; j++ < new Short(a[l]); r += a[i]);
      }
    }
    return r;
  }

  public static void main(String[] a){
    System.out.println(c("ab3c5"));
    System.out.println(c("a0b3"));
    System.out.println(c("13b1"));
    System.out.println(c("a13b1"));
    System.out.println(c("a123b1"));
    System.out.println(c("aa2a1b1"));
    System.out.println(c("123"));
  }
}

Вихід:

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