Развернуть закодированную строку


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. Верный. Есть некоторые esolangs, которые я люблю время от времени видеть, которые иначе штрафуются подсчетом байтов. (Я, конечно, открыт для предложений относительно того, почему это может быть ошибкой, если считать таким образом)

4
@MichaelT Скоринг по символам настоятельно рекомендует сжимать исходный код в UTF32, который позволяет кодировать до 4 байтов на символ, но полностью нечитаем.
Исаак

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

Предполагается, что наше представление завершится без ошибок, если на входе будет пустая строка? Консенсус по мете , что выход на 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)

Результатом операции map на самом деле является список списков, но по умолчанию списки просто объединяются вместе при печати, поэтому ручное преобразование в строку не требуется.

Пример с вводом a13b1:

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

Пип имеет базовую поддержку регулярных выражений с ... 2 дня назад . Отличное время!


Это работает (и так же мастер) с -rфлагом. (Вопрос указывает, что входные данные должны поступить от STDIN.)
Деннис

@ Денис Упс, пропустил это. Добавлен флаг для подсчета байтов. Мне следовало бы использовать специальную переменную qвместо aлишних флагов, но, похоже, есть ошибка, и она запрашивает ввод дважды.
DLosc

Наконец, язык игры в гольф с поддержкой регулярных выражений!
Деннис

@ Денис, я вижу, ты переходишь на пипс сейчас!
Оптимизатор

8

Perl / Bash 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 символов

Ну, это быстро обернулось. Глупые цифры ...

(\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 Исправлено.
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)])

Это создает безымянную функцию, которая принимает строку в качестве входных данных и возвращает строку. Чтобы назвать его, дайте ему имя, например f=s->....

Здесь используются два понимания массива, одно вложено в другое. Внешнее понимание действует на каждое совпадение входной строки с регулярным выражением \D*\d*\d. Внутреннее понимание повторяет каждый символ в соответствии с последней цифрой. Элементы внутреннего массива объединяются в строку, поэтому внешний массив представляет собой массив строк. К ним присоединяются и возвращаются.

В Julia строки могут рассматриваться как массивы символов. Тем не менее, обратите внимание , что Charи Stringтипы в Джулию не имеют одни и те же методы определены; в частности, нет способа повторения, использующего ^для символов. Это использует запутанный обходной путь:

  • Зациклите строку, пропустив последний символ, который удаляется с помощью 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

Python 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 за предложения.

Python 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;}

Задача сложнее, чем кажется

Ungolfed & тестовый код:

Попробуй это здесь.

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.