Replicatore di stringhe


15

In Vim, puoi ripetere un comando precedendolo con un numero, come 3ddè equivalente a dd dd dd. Bene, questo schema ripetuto non è limitato ai comandi di Vim. Anche la stringa può essere replicata in questo modo.

Specifica:

Data una stringa, composta solo da cifre, caratteri alfabetici (sia maiuscoli che minuscoli) e spazi, con una nuova riga finale facoltativa, come input, scrivere un programma che svolge il seguente lavoro:

  • Ogni "parola" è composta da cifre e alfabeti. Se una lettera è preceduta da un numero (potrebbe esserci più di una cifra in un numero o il numero è zero), ripeti quella lettera per i tempi indicati. Per esempio:

    a2bc -> abbc
    3xx1yz -> xxxxyz
    10ab0c0d0e -> aaaaaaaaaab # No 'cde' because there's a zero
    2A2a2A2a -> AAaaAAaa
    
  • Le parole sono separate da spazi. C'è un massimo di uno spazio tra ogni due parole adiacenti.

Facile vero? Ecco le cose aggiuntive:

  • Se c'è un numero prima dello spazio, ripeti la parola successiva per i tempi indicati. Il numero verrà sempre associato alla fine della parola precedente o all'inizio della stringa. Esempio:

    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 una parola vuota deve essere ripetuta, non generare più spazi di fila. Schiacciarli:

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

    In altre parole, il tuo programma non dovrebbe mai generare due spazi insieme.

  • L'input non è mai vuoto, ma non è necessario che l'output sia non vuoto:

    0 3x -> (empty)
    
  • Ingresso e uscita possono essere presi in qualsiasi modo preferito. È accettabile anche una funzione che accetta input da argomenti e fornisce output tramite valori di ritorno.

    Se è un programma, non deve uscire con errori (ovvero il valore di ritorno è zero).

  • I numeri sono sempre decimali e non iniziano mai con uno zero, a meno che il numero stesso non sia zero, nel qual caso esiste solo uno zero. Cioè non è necessario considerare 077ao 000adati come input.

  • Tutti i numeri sono inferiori a 2 ^ 31 (2.147.483.648). La lunghezza massima dell'output è inferiore a 2 ^ 32 (4.294.967.296) byte.

  • Il programma può facoltativamente generare uno spazio finale e / o una nuova riga finale. Lo spazio e la nuova riga non influiscono sulla validità dell'output. Anche se l'output corretto deve essere vuoto, si qualificherà un output di uno spazio seguito da una nuova riga.

In breve, un input valido corrisponde a questa espressione regolare:

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

E per un output valido:

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

Esempi di casi di test:

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

Questo è un , quindi vince il programma più breve in byte in ogni lingua!


3
.... "il programma non deve uscire con errore" "l'immissione non deve essere indicata come un elenco di caratteri ..." qualche motivo particolare? (come già sapevi) generalmente consentiamo un formato I / O flessibile.
user202729

@ user202729 Sto prendendo in considerazione la rimozione di quest'ultimo. Per il risultato dell'uscita dal programma voglio mantenerlo. Modifica : Fatto.
iBug



Penso che dovrebbe essere aggiunto un test come a3 0xc b-> a c c c b, poiché inizialmente avevo un codice che funzionava per tutti i casi di test sopra, ma non funzionava correttamente per quello.
Brad Gilbert b2gills

Risposte:



2

Perl 6, 88 byte

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

Provalo

Allargato:

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

La ~(…).wordscombinazione rimuove gli spazi estranei, utile se viene rimossa una "parola".


1

Python 2, 286 275 260 257 238 byte

-19 byte grazie agli 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 accetta una stringa come argomento e stampa la stringa formattata.

Ecco un repl.it con i casi di test.

Codice non golfato:

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

Continuo a lavorare sui miglioramenti.



@ovs Grazie. Non riesco a credere di non aver pensato di sbarazzarmi della nuova riga e del rientro per exec, poiché è l'unica riga della funzione.
nog642


0

Pulito , 443 ... 306 byte

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

Provalo online!


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.