Réplicateur de chaînes

15

Dans Vim, vous pouvez répéter une commande en la précédant d'un nombre, comme 3ddest équivalent à dd dd dd. Eh bien, ce motif répétitif n'est pas limité aux commandes Vim. La chaîne peut également être répliquée de cette manière.

Spécification:

Étant donné une chaîne, composée uniquement de chiffres, de caractères alphabétiques (majuscules et minuscules) et d'espaces, avec un retour à la ligne facultatif en entrée, écrivez un programme qui effectue le travail suivant:

  • Chaque «mot» est composé de chiffres et d'alphabets. Si une lettre est précédée d'un nombre (il peut y avoir plus d'un chiffre dans un nombre ou le nombre est zéro), répétez cette lettre pour les heures données. Par exemple:

    a2bc -> abbc
    3xx1yz -> xxxxyz
    10ab0c0d0e -> aaaaaaaaaab # No 'cde' because there's a zero
    2A2a2A2a -> AAaaAAaa
    
  • Les mots sont séparés par des espaces. Il y a un maximum d'un espace entre deux mots adjacents.

Facile, non? Voici les trucs supplémentaires:

  • S'il y a un nombre devant l'espace, répétez le mot suivant pour les heures données. Le numéro sera toujours attaché à la fin du mot précédent ou au début de la chaîne. Exemple:

    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
    
  • Si un mot vide doit être répété, ne sortez pas plusieurs espaces d'affilée. Écrasez-les:

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

    En d'autres termes, votre programme ne doit jamais produire deux espaces ensemble.

  • L'entrée n'est jamais vide, mais il n'est pas nécessaire que la sortie ne soit pas vide:

    0 3x -> (empty)
    
  • L'entrée et la sortie peuvent être prises de n'importe quelle manière préférée. Une fonction prenant l'entrée des arguments et donnant la sortie via les valeurs de retour est également acceptable.

    S'il s'agit d'un programme, il ne doit pas sortir avec erreur (c'est-à-dire que la valeur de retour est zéro).

  • Les nombres sont toujours décimaux et ne commencent jamais par un zéro, sauf si le nombre lui-même est zéro, auquel cas il n'y a qu'un seul zéro. C'est-à-dire que vous n'avez pas besoin de considérer 077aou de 000adonner en entrée.

  • Tous les chiffres sont inférieurs à 2 ^ 31 (2 147 483 648). La longueur de sortie maximale est inférieure à 2 ^ 32 (4 294 967 296) octets.

  • Le programme peut éventuellement générer un espace de fin et / ou une nouvelle ligne de fin. Cet espace et cette nouvelle ligne n'affectent pas la validité de la sortie. Même si la sortie correcte doit être vide, une sortie d'un espace suivie d'une nouvelle ligne sera qualifiée.

En bref, une entrée valide correspond à cette expression régulière:

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

Et pour une sortie valide:

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

Exemples de cas de 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

Il s'agit d'un , donc le programme le plus court en octets dans chaque langue gagne!

iBug
la source
3
.... "le programme ne doit pas sortir avec erreur" "l'entrée ne doit pas être donnée comme une liste de caractères ..." pour une raison particulière? (comme vous le saviez déjà), nous autorisons généralement un format d'E / S flexible.
user202729
@ user202729 J'envisage de supprimer ce dernier. Pour le résultat de sortie du programme, je veux le garder. Modifier : terminé.
iBug
1
Similaire .
cole
1
Aussi similaire
danieltakeshi
Je pense qu'un test comme a3 0xc b-> a c c c bdevrait être ajouté, car j'avais à l'origine du code qui fonctionnait pour tous les cas de test ci-dessus, mais ne fonctionnait pas correctement pour cela.
Brad Gilbert b2gills

Réponses:

2

Perl 6, 88 octets

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

Essaye-le

Étendu:

{ # 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 ~(…).wordscombinaison supprime les espaces superflus, ce qui est utile si un «mot» est supprimé.

Brad Gilbert b2gills
la source
1

Python 2, 286 275 260 257 238 octets

-19 octets grâce aux 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 prend une chaîne comme argument et imprime la chaîne formatée.

Voici un repl.it avec les cas de test.

Code non golfé:

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

Je travaille toujours sur des améliorations.

nog642
la source
@ovs Merci. Je ne peux pas croire que je n'ai pas pensé à me débarrasser de la nouvelle ligne et du retrait pour le exec, car c'est la seule ligne de la fonction.
nog642
1

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

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

Essayez-le en ligne!

Xcali
la source
0

Nettoyer , 443 ... 306 octets

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

Essayez-le en ligne!

Οurous
la source
0

Lua , 113 octets

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)

Essayez-le en ligne!

Jonathan S.
la source