Dize çoğaltıcı


15

Vim'de, bir komuttan önce gelen bir sayı 3ddile eşdeğer bir komutu tekrarlayabilirsiniz dd dd dd. Bu yinelenen model Vim komutlarıyla sınırlı değil. Dize de bu şekilde çoğaltılabilir.

Şartname:

Yalnızca basamaklar, alfabetik karakterler (hem büyük hem de küçük harf) ve boşluklardan oluşan ve isteğe bağlı bir son satır olan girdi olarak, aşağıdaki işi yapan bir program yazın:

  • Her "kelime" rakam ve harflerden oluşur. Harfden önce bir sayı gelirse (bir sayıda birden fazla basamak olabilir veya sayı sıfırsa), verilen harf için bu harfi tekrarlayın. Örneğin:

    a2bc -> abbc
    3xx1yz -> xxxxyz
    10ab0c0d0e -> aaaaaaaaaab # No 'cde' because there's a zero
    2A2a2A2a -> AAaaAAaa
    
  • Kelimeler boşluklarla ayrılır. Bitişik her iki kelime arasında en fazla bir boşluk vardır.

Kolay değil mi? İşte ek şeyler:

  • Boşluktan önce bir sayı varsa, verilen süreler için sonraki kelimeyi tekrarlayın. Sayı her zaman önceki sözcüğün sonuna veya dizenin başlangıcına eklenir. Misal:

    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
    
  • Boş bir kelimenin tekrarlanması gerekiyorsa, arka arkaya birden fazla boşluk bırakmayın. Ezin onları:

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

    Başka bir deyişle, programınız asla iki boşluğun birlikte çıktısını almamalıdır.

  • Giriş asla boş değildir, ancak çıktının boş olmaması gerekli değildir:

    0 3x -> (empty)
    
  • Giriş ve çıkış tercih edilen herhangi bir şekilde alınabilir. Bağımsız değişkenlerden girdi alan ve dönüş değerleri üzerinden çıktı veren bir işlev de kabul edilebilir.

    Bir program ise, hata ile çıkmamalıdır (yani, dönüş değeri sıfırdır).

  • Sayılar her zaman ondalıktır ve sayının kendisi sıfır olmadığı sürece asla sıfırla başlamaz, bu durumda yalnızca bir sıfır vardır. Yani girdi olarak düşünmenize 077aveya vermenize gerek yok 000a.

  • Tüm sayılar 2 ^ 31'in altındadır (2.147.483.648). Maksimum çıkış uzunluğu 2 ^ 32 (4,294,967,296) baytın altında.

  • Program isteğe bağlı olarak bir sondaki boşluk ve / veya bir sondaki yeni hat çıktısı verebilir. Bu alan ve satırsonu, çıktının geçerliliğini etkilemez. Doğru çıktı boş olsa bile, bir boşluğun çıktısı ve ardından bir yeni satır verilir.

Kısacası, geçerli bir girdi şu normal ifadeyle eşleşir:

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

Ve geçerli bir çıktı için:

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

Örnek test senaryoları:

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

Bu bir , bu yüzden her dilde bayt en kısa program kazanır!


3
.... "program hatayla çıkılmamalı" "girdi karakter listesi olarak verilmemeli ..." herhangi bir sebep var mı? (zaten bildiğiniz gibi) genellikle esnek G / Ç biçimine izin veririz.
user202729

@ user202729 Ben ikincisini kaldırmayı düşünüyorum. Program çıkış sonucu için bunu saklamak istiyorum. Düzenleme : Tamamlandı.
iBug



Ben yukarıdaki gibi tüm test vakaları için çalıştı, ama bunun için düzgün çalışmadı kod vardı gibi a3 0xc b-> gibi bir test a c c c beklenmesi gerektiğini düşünüyorum.
Brad Gilbert b2gills

Yanıtlar:



2

Perl 6, 88 bayt

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

Dene

Expanded:

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

~(…).wordsKombinasyon, bir “sözcüğü” kaldırılırsa kullanışlıdır gereksiz boşluklar kaldırır.


1

Python 2, 286 275 260 257 238 bayt

-19 sayesinde bayt 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 dizeyi bağımsız değişken olarak alır ve biçimlendirilmiş dizeyi yazdırır.

İşte test örnekleri ile bir repl.it.

Kod çözülmemiş 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())

Hâlâ iyileştirmeler üzerinde çalışıyor.



@ovs Teşekkürler. execFonksiyondaki tek satır olduğu için yeni satırdan ve girintiden kurtulmayı düşünmediğime inanamıyorum .
nog642


0

Temiz , 443 ... 306 bayt

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

Çevrimiçi deneyin!


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.