字符串复制器


15

在Vim中,您可以在命令前加上一个数字来重复该命令,例如3dd等效于dd dd dd。嗯,这种重复模式不限于Vim命令。字符串也可以用这种方式复制。

规格:

给定一个仅包含数字,字母字符(大写和小写)和空格的字符串,并带有可选的尾随换行符作为输入,编写一个程序来完成以下任务:

  • 每个“单词”由数字和字母组成。如果字母前面带有数字(数字中可能有多个数字,或者数字为零),请在给定的时间重复该字母。例如:

    a2bc -> abbc
    3xx1yz -> xxxxyz
    10ab0c0d0e -> aaaaaaaaaab # No 'cde' because there's a zero
    2A2a2A2a -> AAaaAAaa
    
  • 单词之间用空格隔开。每两个相邻的词之间最多有一个空格。

容易吧?这是其他东西:

  • 如果空格前有数字,请在给定的时间重复下一个单词。该数字将始终附加在前一个单词的末尾或字符串的开头。例:

    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'
    

    换句话说,您的程序永远不要同时输出两个空格。

  • 输入从不为空,但输出非为非空是不必要的:

    0 3x -> (empty)
    
  • 输入和输出可以采用任何首选方式。从参数获取输入并通过返回值提供输出的函数也是可以接受的。

    如果它是一个程序,则它不能错误退出(即返回值为零)。

  • 数字始终为十进制,并且永远不会以零开头,除非数字本身为零,在这种情况下,只有一个零。也就是说,您不需要考虑077a000a输入。

  • 所有数字均小于2 ^ 31(2,147,483,648)。最大输出长度小于2 ^ 32(4,294,967,296)字节。

  • 该程序可以可选地输出一个尾随空格和/或一个尾随换行符。这些空格和换行符不会影响输出的有效性。即使正确的输出应该为空,空格输出和换行符也将合格。

简而言之,有效的输入匹配此正则表达式:

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

Answers:



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

Python 2中,286 275 260 257 238个字节

-19字节归功于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 将字符串作为参数并打印格式化的字符串。

这是测试用例的副本

取消程式码:

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

干净443个 ... 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]]])

在线尝试!


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.