ストリングレプリケーター


15

Vimのでは、あなたが番号を前置することにより、コマンドを繰り返すことができ、同様3ddに相当しますdd dd dd。さて、この繰り返しパターンはVimコマンドに限定されません。文字列もこの方法で複製できます。

仕様:

入力として、数字、アルファベット文字(大文字と小文字の両方)、およびスペースのみで構成される文字列を指定し、オプションで末尾の改行を使用して、次のジョブを実行するプログラムを作成します。

  • 各「単語」は数字とアルファベットで構成されます。文字の前に数字が付いている場合(数字に複数の数字があるか、数字がゼロの場合)、その文字を指定された回数だけ繰り返します。例えば:

    a2bc -> abbc
    3xx1yz -> xxxxyz
    10ab0c0d0e -> aaaaaaaaaab # No 'cde' because there's a zero
    2A2a2A2a -> AAaaAAaa
    
  • 単語はスペースで区切られます。隣接する2つの単語ごとに最大1つのスペースがあります。

簡単ですね。追加のものは次のとおりです。

  • スペースの前に数字がある場合は、指定された時間だけ次の単語を繰り返します。番号は常に前の単語の末尾、または文字列の先頭に添付されます。例:

    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
    
  • 空の単語を繰り返す必要がある場合、複数のスペースを連続して出力しないでください。それらをつぶします:

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

    つまり、プログラムで2つのスペースを一緒に出力しないでください。

  • 入力が空になることはありませんが、出力が空でない必要はありません。

    0 3x -> (empty)
    
  • 入力および出力は、任意の方法で取得できます。引数から入力を受け取り、戻り値を介して出力を与える関数も受け入れられます。

    プログラムの場合、エラーで終了してはなりません(つまり、戻り値はゼロです)。

  • 数値は常に10進数であり、数値自体がゼロでない限りゼロで始まることはありません。その場合、ゼロは1つだけです。すなわち、あなたは考慮する必要はありません077aつまり000a、入力として、入力。

  • すべての数値は2 ^ 31(2,147,483,648)未満です。最大出力長は2 ^ 32(4,294,967,296)バイト未満です。

  • プログラムは、オプションで1つの末尾スペースおよび/または1つの末尾改行を出力できます。これらのスペースと改行は、出力の有効性に影響しません。正しい出力が空であっても、スペースに続いて改行が出力されると、修飾されます。

つまり、有効な入力は次の正規表現に一致します。

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

有効な出力の場合:

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

サンプルテストケース:

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

これはので、各言語のバイト単位の最短プログラムが勝ちです!


3
....「プログラムはエラーで終了してはなりません」「入力は文字のリストとして指定してはいけません...」特定の理由 (既にご存知のように)通常、柔軟なI / O形式を使用できます。
user202729

@ user202729後者の削除を検討しています。プログラムの終了結果のために、それを保持したいです。編集:完了。
iBug

1
同様
コール


a3 0xc b->のようなテストをa c c c b追加する必要があると思います。元々、上記のすべてのテストケースで機能するコードがありましたが、それでは正しく機能しませんでした。
ブラッドギルバートb2gills

回答:



2

Perl 6、88バイト

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

試して

拡張:

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

この~(…).words組み合わせは、余分なスペースを削除します。これは、「単語」が削除される場合に便利です。


1

パイソン2、286の 275 260 257 238バイト

ovsのおかげで-19バイト

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 引数として文字列を取り、フォーマットされた文字列を出力します。

テストケースのrepl.itを次に示します。

未ゴルフコード:

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

改善に取り組んでいます。



@ovsありがとう。exec関数の唯一の行であるため、改行を削除してインデントすることを考えていなかったとは信じられません。
nog642


0

Clean443 ... 306バイト

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

オンラインでお試しください!


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.