Replikator ciągów

15

W Vimie możesz powtórzyć polecenie poprzedzając je liczbą, podobnie jak 3ddodpowiednik dd dd dd. Ten powtarzający się wzorzec nie jest ograniczony do poleceń Vima. Ciąg można również replikować w ten sposób.

Specyfikacja:

Biorąc pod uwagę ciąg znaków, składający się wyłącznie z cyfr, znaków alfabetu (zarówno wielkich, jak i małych) oraz spacji, z opcjonalnym końcowym znakiem nowej linii jako napisem, napisz program, który wykonuje następujące zadanie:

  • Każde „słowo” składa się z cyfr i alfabetów. Jeśli litera poprzedza cyfra (może występować więcej niż jedna cyfra w cyfrze lub liczba wynosi zero), powtórz tę literę dla podanych czasów. Na przykład:

    a2bc -> abbc
    3xx1yz -> xxxxyz
    10ab0c0d0e -> aaaaaaaaaab # No 'cde' because there's a zero
    2A2a2A2a -> AAaaAAaa
    
  • Słowa są oddzielone spacjami. Pomiędzy dwoma sąsiednimi słowami jest maksymalnie jedna spacja.

Łatwe, prawda? Oto dodatkowe rzeczy:

  • Jeśli przed spacją jest liczba, powtórz następne słowo dla podanych czasów. Liczba będzie zawsze dołączana na końcu poprzedniego słowa lub na początku łańcucha. Przykład:

    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
    
  • Jeśli puste słowo powinno zostać powtórzone, nie wypisuj wielu spacji z rzędu. Squash je:

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

    Innymi słowy, twój program nigdy nie powinien wypisywać razem dwóch spacji.

  • Dane wejściowe nigdy nie są puste, ale nie jest konieczne, aby dane wyjściowe były niepuste:

    0 3x -> (empty)
    
  • Dane wejściowe i wyjściowe można przyjmować na dowolne preferowane sposoby. Dopuszczalna jest również funkcja pobierająca dane wejściowe z argumentów i przekazująca dane wyjściowe za pomocą zwracanych wartości.

    Jeśli jest to program, nie może wyjść z błędem (tzn. Zwracana wartość wynosi zero).

  • Liczby są zawsze dziesiętne i nigdy nie zaczynają się od zera, chyba że sama liczba wynosi zero, w którym to przypadku jest tylko jedno zero. Czyli nie musisz brać pod uwagę 077aani 000apodawać danych wejściowych.

  • Wszystkie liczby są poniżej 2 ^ 31 (2 147 483 648). Maksymalna długość wyjściowa jest mniejsza niż 2 ^ 32 (4 294 967 296) bajtów.

  • Program może opcjonalnie wypisać jedną końcową spację i / lub jedną końcową nową linię. Te odstępy i znak nowej linii nie wpływają na ważność danych wyjściowych. Nawet jeśli poprawne wyjście powinno być puste, kwalifikuje się wyjście spacji, po której następuje nowa linia.

Krótko mówiąc, prawidłowe dane wejściowe pasują do tego wyrażenia regularnego:

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

I dla prawidłowego wyniku:

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

Przykładowe przypadki testowe:

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

To jest , więc wygrywa najkrótszy program w bajtach w każdym języku!

iBug
źródło
3
.... „program nie może wyjść z błędem” „Nie można podać danych wejściowych jako listy znaków ...” z jakiegoś konkretnego powodu? (jak już wiesz) ogólnie dopuszczamy elastyczny format We / Wy.
user202729
@ user202729 Rozważam usunięcie tego ostatniego. Dla wyniku wyjścia z programu chcę go zachować. Edycja : Gotowe.
iBug
1
Podobna .
cole
1
Również podobny
danieltakeshi
Myślę, że należy dodać test typu a3 0xc b-> a c c c b, ponieważ pierwotnie miałem kod, który działał dla wszystkich powyższych przypadków testowych, ale nie działał poprawnie dla tego.
Brad Gilbert b2gills

Odpowiedzi:

3

JavaScript (Node.js) , 102 129 110 106 bajtów

s=>s[p="replace"](/(\d+)( \w*[A-Z])/gi,g=(_,a,b)=>b.repeat(a))[p](/(\d+)(.)/g,g)[p](/ +/g,(_,i)=>i?" ":"")

Wypróbuj online!

Dzięki za @Arnauld za -4 bajty.

Shieru Asakoto
źródło
2

Perl 6, 88 bajtów

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

Sprawdź to

Rozszerzony:

{ # 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)
}

Ta ~(…).wordskombinacja usuwa zewnętrzne przestrzenie, co jest przydatne, gdy „słowo” zostanie usunięte.

Brad Gilbert b2gills
źródło
1

Python 2, 286 275 260 257 238 bajtów

-19 bajtów dzięki ovs

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 bierze ciąg jako argument i wypisuje sformatowany ciąg.

Oto repl.it z przypadkami testowymi.

Nieskluczony kod:

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

Nadal pracuję nad ulepszeniami.

nog642
źródło
@ovs Thanks. Nie mogę uwierzyć, że nie myślałem o pozbyciu się nowej linii i wcięcia dla exec, ponieważ jest to jedyna linia w funkcji.
nog642
1

Perl 5 , 77 + 1 ( -p) = 78 bajtów

s/\d+( .*?)(\d*)( |$)/$1x$&.$2.$3/eg&&redo;s/\d+(\D)/$1x$&/eg;s/ +/ /g;s;^ +;

Wypróbuj online!

Xcali
źródło
0

Czysty , 443 ... 306 bajtów

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

Wypróbuj online!

Obrzydliwe
źródło
0

Lua , 113 bajtów

a="(%d+)(%a)"g=a.gsub function r(c,s)return s:rep(c)end g(g(g(g(...,a,r),"(%d+)( %a*)",r)," +"," "),"%a.*",print)

Wypróbuj online!

Jonathan S.
źródło