Replikator string

15

Di Vim, Anda bisa mengulangi perintah dengan mendahului dengan angka, seperti 3ddsetara dengan dd dd dd. Nah, pola berulang ini tidak terbatas pada perintah Vim. String juga dapat direplikasi dengan cara ini.

Spesifikasi:

Diberikan string, yang hanya terdiri dari digit, karakter alfabet (huruf besar dan kecil) dan spasi, dengan baris tambahan opsional, sebagai input, tulis sebuah program yang melakukan pekerjaan berikut:

  • Setiap "kata" terdiri dari angka dan huruf. Jika huruf didahului dengan angka (mungkin ada lebih dari satu digit dalam angka, atau angka itu nol), ulangi huruf itu untuk waktu yang diberikan. Sebagai contoh:

    a2bc -> abbc
    3xx1yz -> xxxxyz
    10ab0c0d0e -> aaaaaaaaaab # No 'cde' because there's a zero
    2A2a2A2a -> AAaaAAaa
    
  • Kata-kata dipisahkan oleh spasi. Ada maksimum satu ruang antara setiap dua kata yang berdekatan.

Mudah kan? Inilah hal-hal tambahan:

  • Jika ada angka sebelum spasi, ulangi kata berikutnya untuk waktu yang diberikan. Nomor akan selalu dilampirkan di akhir kata sebelumnya, atau di awal string. Contoh:

    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
    
  • Jika kata kosong harus diulangi, jangan tampilkan banyak spasi secara berurutan. Remas mereka:

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

    Dengan kata lain, program Anda seharusnya tidak menghasilkan dua spasi secara bersamaan.

  • Input tidak pernah kosong, tetapi output tidak perlu kosong:

    0 3x -> (empty)
    
  • Input dan output dapat diambil dengan cara apa pun yang disukai. Fungsi mengambil input dari argumen dan memberikan output melalui nilai kembali juga dapat diterima.

    Jika itu sebuah program, ia tidak boleh keluar dengan kesalahan (yaitu nilai balik adalah nol).

  • Angka selalu desimal, dan tidak pernah dimulai dengan nol, kecuali jika angka itu sendiri nol, dalam hal ini hanya ada satu nol. Yaitu Anda tidak perlu mempertimbangkan 077aatau 000adiberikan sebagai masukan.

  • Semua angka di bawah 2 ^ 31 (2.147.483.648). Panjang output maksimum adalah di bawah 2 ^ 32 (4.294.967.296) byte.

  • Program opsional dapat menghasilkan satu spasi tambahan dan / atau satu spasi tambahan. Ruang dan baris baru tidak memengaruhi validitas output. Bahkan jika output yang benar harus kosong, output spasi diikuti oleh baris baru akan memenuhi syarat.

Singkatnya, input yang valid cocok dengan ekspresi reguler ini:

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

Dan untuk hasil yang valid:

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

Contoh uji kasus:

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

Ini adalah , jadi program terpendek dalam byte di setiap bahasa menang!

iBug
sumber
3
.... "program tidak boleh keluar dengan kesalahan" "input tidak boleh diberikan sebagai daftar karakter ..." ada alasan khusus? (seperti yang sudah Anda ketahui) kami biasanya mengizinkan format I / O yang fleksibel.
user202729
@ user202729 Saya mempertimbangkan untuk menghapus yang terakhir. Untuk hasil keluar program saya ingin menyimpannya. Edit : Selesai.
iBug
1
Serupa .
cole
1
Juga serupa
danieltakeshi
Saya pikir tes seperti a3 0xc b-> a c c c bharus ditambahkan, karena saya awalnya memiliki kode yang bekerja untuk semua kasus uji di atas, tetapi tidak berfungsi dengan benar untuk itu.
Brad Gilbert b2gills

Jawaban:

3

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

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

Cobalah online!

Terima kasih atas @Arnauld untuk -4 byte.

Shieru Asakoto
sumber
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}

Menguji

Diperluas:

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

The ~(…).wordsKombinasi menghapus spasi asing, yang berguna jika sebuah “kata” akan dihapus.

Brad Gilbert b2gills
sumber
1

Python 2, 286 275 260 257 238 byte

-19 byte berkat 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 mengambil string sebagai argumen dan mencetak string yang diformat.

Ini adalah repl.it dengan kasus uji.

Kode tidak dikunci:

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

Masih bekerja pada perbaikan.

nog642
sumber
238 byte
ovs
@ Terima kasih. Tidak percaya saya tidak berpikir untuk menyingkirkan baris baru dan lekukan untuk exec, karena itu satu-satunya baris dalam fungsi.
nog642
1

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

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

Cobalah online!

Xcali
sumber
0

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

Cobalah online!

Suram
sumber
0

Lua , 113 byte

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)

Cobalah online!

Jonathan S.
sumber