Реплікатор струни


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

Це , тому найкоротша програма в байтах на кожній мові виграє!


3
.... "програма не повинна виходити з помилкою" "вхід не повинен даватися як список символів ..." з якоїсь конкретної причини? (як ви вже знали) ми зазвичай допускаємо гнучкий формат вводу / виводу.
користувач202729

@ user202729 Я розглядаю питання про видалення останнього. Для результату виходу з програми я хочу її зберегти. Редагувати : Готово.
iBug



Думаю, слід додати тест на зразок 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}

Перевірте це

Розширено:

{ # 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Комбінація видаляє зайві прогалини, що корисно , якщо «слово» отримує видалений.


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 приймає рядок як аргумент і друкує відформатований рядок.

Ось репл.іт із тестовими кейсами.

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

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())

Ще працюю над вдосконаленнями.



@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]]])

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


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