Replicador de cadeia

15

No Vim, você pode repetir um comando precedendo-o com um número, como 3ddé equivalente a dd dd dd. Bem, esse padrão de repetição não se restringe aos comandos do Vim. A string também pode ser replicada dessa maneira.

Especificação:

Dada uma sequência, composta apenas por dígitos, caracteres alfabéticos (maiúsculas e minúsculas) e espaços, com uma nova linha à direita opcional, como entrada, escreva um programa que faça o seguinte trabalho:

  • Cada "palavra" consiste em dígitos e alfabetos. Se uma letra for precedida de um número (pode haver mais de um dígito em um número ou o número é zero), repita essa letra pelos tempos determinados. Por exemplo:

    a2bc -> abbc
    3xx1yz -> xxxxyz
    10ab0c0d0e -> aaaaaaaaaab # No 'cde' because there's a zero
    2A2a2A2a -> AAaaAAaa
    
  • As palavras são separadas por espaços. Há no máximo um espaço entre cada duas palavras adjacentes.

Fácil né? Aqui estão as coisas adicionais:

  • Se houver um número antes do espaço, repita a próxima palavra pelos tempos determinados. O número sempre será anexado ao final da palavra anterior ou no início da string. Exemplo:

    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
    
  • Se uma palavra vazia precisar ser repetida, não imprima vários espaços seguidos. Esmagá-los:

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

    Em outras palavras, seu programa nunca deve gerar dois espaços juntos.

  • A entrada nunca está vazia, mas não é necessário que a saída fique vazia:

    0 3x -> (empty)
    
  • Entrada e saída podem ser obtidas de qualquer maneira preferida. Uma função que recebe entrada de argumentos e fornece saída via valores de retorno também é aceitável.

    Se for um programa, ele não deve sair com erro (ou seja, o valor de retorno é zero).

  • Os números são sempre decimais e nunca começam com zero, a menos que o número em si seja zero; nesse caso, existe apenas um zero. 077aOu seja, você não precisa considerar ou 000afornecer como entrada.

  • Todos os números estão abaixo de 2 ^ 31 (2.147.483.648). O comprimento máximo da saída é inferior a 2 ^ 32 (4.294.967.296) bytes.

  • O programa pode opcionalmente gerar um espaço à direita e / ou uma nova linha à direita. O espaço e a nova linha não afetam a validade da saída. Mesmo se a saída correta estiver vazia, a saída de um espaço seguido por uma nova linha será qualificada.

Em resumo, uma entrada válida corresponde a esta expressão regular:

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

E para uma saída válida:

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

Casos de teste de amostra:

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

Este é um , portanto o programa mais curto em bytes em cada idioma vence!

iBug
fonte
3
.... "o programa não pode sair com erro" "a entrada não deve ser fornecida como uma lista de caracteres ..." alguma razão em particular? (como você já sabia), geralmente permitimos um formato de E / S flexível.
precisa saber é o seguinte
@ user202729 Considero remover o último. Para o resultado da saída do programa, quero mantê-lo. Editar : Concluído.
iBug 8/01/19
1
Similar .
cole
1
Também semelhante
danieltakeshi
Acho que um teste como a3 0xc b-> a c c c bdeve ser adicionado, pois originalmente eu tinha um código que funcionava para todos os casos de teste acima, mas não funcionava corretamente para isso.
Brad Gilbert b2gills

Respostas:

3

JavaScript (Node.js) , 102 129 110 106 bytes

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

Experimente online!

Obrigado por @Arnauld por -4 bytes.

Shieru Asakoto
fonte
2

Perl 6, 88 bytes

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

Teste-o

Expandido:

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

A ~(…).wordscombinação remove espaços externos, o que é útil se uma "palavra" for removida.

Brad Gilbert b2gills
fonte
1

Python 2, 286 275 260 257 238 bytes

-19 bytes graças a 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 pega uma string como argumento e imprime a string formatada.

Aqui está um repl.it com os casos de teste.

Código não destruído:

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

Ainda trabalhando em melhorias.

nog642
fonte
238 bytes
ovs
Obrigado @ovs. Não posso acreditar que não pensei em me livrar da nova linha e do recuo da exec, pois é a única linha na função.
nog642
1

Perl 5 , 77 + 1 ( -p) = 78 bytes

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

Experimente online!

Xcali
fonte
0

Limpo , 443 ... 306 bytes

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

Experimente online!

Furioso
fonte
0

Lua , 113 bytes

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)

Experimente online!

Jonathan S.
fonte