Струнный репликатор

15

В Vim вы можете повторить команду, поставив перед ней число, аналогичное 3ddэквивалентному dd dd dd. Ну, этот повторяющийся шаблон не ограничен командами Vim. Строка также может быть скопирована таким же образом.

Спецификация:

Для заданной строки, состоящей только из цифр, буквенных символов (как в верхнем, так и в нижнем регистре) и пробелов, с необязательным завершающим переводом строки в качестве входных данных, напишите программу, которая выполняет следующую работу:

  • Каждое «слово» состоит из цифр и алфавитов. Если перед буквой стоит число (может быть несколько цифр в номере или число равно нулю), повторите эту букву для заданного времени. Например:

    a2bc -> abbc
    3xx1yz -> xxxxyz
    10ab0c0d0e -> aaaaaaaaaab # No 'cde' because there's a zero
    2A2a2A2a -> AAaaAAaa
    
  • Слова разделены пробелами. Максимум один пробел между каждыми двумя смежными словами.

Легко, правда? Вот дополнительные вещи:

  • Если перед пробелом стоит число, повторите следующее слово для заданного времени. Номер всегда будет прикреплен к концу предыдущего слова или в начале строки. Пример:

    a2bc3 2d -> abbc dd dd dd
    3 3a -> aaa aaa aaa
    33a -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    0 abcd0 efgh3 2x -> xx xx xx
    a3 0xc b -> a c c c b
    
  • Если пустое слово должно быть повторено, не выводите несколько пробелов подряд. Раздавить их:

    a3 0x2 b -> a b b   # NOT 'a    b b'
    

    Другими словами, ваша программа никогда не должна выводить два пробела вместе.

  • Входные данные никогда не бывают пустыми, но необязательно, чтобы выходные данные были непустыми:

    0 3x -> (empty)
    
  • Ввод и вывод могут быть приняты любым предпочтительным способом. Функция, принимающая входные данные из аргументов и выдающая выходные данные через возвращаемые значения, также приемлема.

    Если это программа, она не должна завершаться с ошибкой (т.е. возвращаемое значение равно нулю).

  • Числа всегда десятичные и никогда не начинаются с нуля, если только само число не равно нулю, в этом случае есть только один ноль. Т.е. вам не нужно рассматривать 077aили 000aдавать в качестве входных данных.

  • Все числа меньше 2 ^ 31 (2 147 483 648). Максимальная длина вывода составляет менее 2 32 (4 294 967 296) байтов.

  • Программа может дополнительно вывести один завершающий пробел и / или один завершающий символ новой строки. Эти пробел и новая строка не влияют на достоверность вывода. Даже если правильный вывод должен быть пустым, вывод пробела, за которым следует символ новой строки, будет квалифицирован.

Короче говоря, правильный ввод соответствует этому регулярному выражению:

([0-9]+ )?([0-9A-Za-z]*[A-Za-z])([0-9]* [0-9A-Za-z]*[A-Za-z])*( ?\n?)

И для правильного вывода:

([A-Za-z]+)( [A-Za-z]+)*( ?\n?)

Примеры тестовых случаев:

abcdefg -> abcdefg
a3bcd -> abbbcd
a3bbbc -> abbbbbc
3a0b -> aaa
abc 3d -> abc ddd
abc3 d -> abc d d d
5 1x5 1y0 z -> x x x x x y y y y y
a999 0x b -> a b
999 0s -> (empty)
0 999s -> (empty)
0 999s4 t -> t t t t
a3 0xc b -> a c c c b
ABC3 abc -> ABC abc abc abc

Это , поэтому выигрывает самая короткая программа в байтах на каждом языке!

iBug
источник
3
.... "программа не должна завершиться с ошибкой" "ввод не должен быть представлен в виде списка символов ..." какая-то конкретная причина? (как вы уже знали) мы обычно допускаем гибкий формат ввода / вывода.
user202729
@ user202729 Я рассматриваю удаление последнего. Для результата выхода из программы я хочу сохранить его. Редактировать : Готово.
iBug
1
Похоже .
Коул
1
Также похоже
danieltakeshi
Я думаю, что нужно добавить тест, подобный a3 0xc b-> a c c c b, так как у меня изначально был код, который работал для всех тестовых случаев выше, но не работал правильно для этого.
Брэд Гилберт b2gills

Ответы:

2

Perl 6, 88 байт

{$_=$^a;s:g/(\d+):(\w)/{$1 x$0||'_'}/;s:g/(\d+)\s([\w& \D]+)/ {$1 xx$0}/;~S:g/_//.words}

Проверь это

Expanded:

{ # bare block lambda with placeholder parameter 「$a」

  # store a copy of the argument in 「$_」
  # (shorter than 「-> $_ is copy {…}」)
  $_ = $^a;
  # note that 「$_」 is the default scalar,
  # and many things operate on it by default (like 「s///」)


  # do the character repeats
  s :global
  /

    (\d+)           # repeat count
    :               # don't backtrack (prevents it from matching word repeats)
    (\w)            # character to repeat

  /{

    $1 x $0         # do the repeat

    || '_'          # replace with 「_」 if the repeat was 0 (matched by [\w & \D])
                    # this is so “words” don't get removed yet

  }/;


  # do the word repeats
  s :global
  /

    (\d+)           # repeat count

    \s              # shortest way to match a space

    ([
      \w & \D       # word character and not a digit (doesn't match next repeat)
    ]+)             # match that at least once

  / {               # add a space (as we removed it by matching it)

    $1 xx $0        # list repeat (adds a space between values when stringified)

  }/;


  # the following is the result
  ~                 # stringify (adds spaces between values in a list) # (3)
    S :global /_//  # remove all _ not in-place                        # (1)
    .words          # get a list of words                              # (2)
}

~(…).wordsКомбинация удаляет лишние пробелы, что полезно , если «слово» получает удален.

Брэд Гилберт b2gills
источник
1

Python 2, 286 275 260 257 238 байт

-19 байт благодаря овсу

def f(s,j=' '.join):exec"s=s.split(%s[-1]):s[i]=s[i][:-1];s[i-1]=j([s[i-1]]*int(w[-1]))\ns=list(j(s[::-1])%s):s[i]='';s[i-1]*=int(w)\nprint j(''.join(s[::-1]).strip().split())"%((')[::-1]\nfor i,w in enumerate(s):\n if str.isdigit(w',)*2)

f принимает строку в качестве аргумента и печатает отформатированную строку.

Вот repl.it с тестовыми примерами .

Код Ungolfed:

def f(s, j=' '.join):
    s = s.split()[::-1]
    for i, w in enumerate(s):
        if str.isdigit(w[-1]):
            s[i] = s[i][:-1]
            s[i - 1] = j([s[i - 1]] * int(w[-1]))
    s = list(j(s[::-1]))[::-1]
    for i, w in enumerate(s):
        if str.isdigit(w):
            s[i] = ''
            s[i - 1] *= int(w)
    print j(''.join(s[::-1]).strip().split())

Все еще работаю над улучшениями.

nog642
источник
238 байт
овс
@ovs Спасибо. Не могу поверить, что я не думал избавиться от новой строки и отступа для exec, поскольку это единственная строка в функции.
nog642
0

Чисто , 443 ... 306 байт

import StdEnv,StdLib
^ =last
$n|n>"9"=1=toInt n
?v c| ^v<c=init v=v
q=groupBy
f[a:t]|a<"a"=repeatn($a)(hd t)++f(tl t)|t>[]=[a:f t]=[a," "]
f e=e
@l#[h:t]=[[toString[c:if(c<'1')[]k]\\[c:k]<-q(\a b=max a b<'a')s]\\s<-q(\a b=min a b>' ')l|s>[' ']]
=flatten(map f[?h"a":[?u":"\\u<-t&v<-map^[h:t],_<-[1.. $v]]])

Попробуйте онлайн!

Οurous
источник