扩展编码字符串


18

有经典的游程长度编码和解码。

input   output
a3b2c5  aaabbccccc

这是相当直接的,之前已经完成。

面临的挑战是也占了非标准的行为,当多个字符先于游程长度(一个从0-9位)。游程长度位之前的每个字符(字符串的一个非数字或结束之前的最后一位数字)具有施加到其上该值单独地和以打印出来。

一些测试输入和输出,包括一些边缘情况:

input   output
ab3c5   aaabbbccccc
a0b3    bbb  
13b1    111b
a13b1   aaa111b
a123b1  aaa111222b
aa2a1b1 aaaaab
  • 字符序列([a-zA-Z0-9]+)后必须跟游程长度长度([0-9]
  • 只需要考虑有效的输入(([a-zA-Z0-9]+[0-9])*
    • 是的,空字符串是有效输入。
  • 输入通过标准输入,通过标准输出输出

这是代码高尔夫,字节数确定获胜者。


@AlexA。正确。我喜欢不时看到一些esolang,这些字节以字节数为代价。(我当然愿意就为什么这可能是个错误来提出建议)

4
@MichaelT按字符计分强烈鼓励将源代码压缩为UTF32,这允许每个字符最多4个字节的编码,但完全不可读。
isaacg,2015年

@isaacg还不错。我将编辑以更改为字节。我将仔细考虑一种表达sc脚样式的方式,以应对未来的挑战。

如果输入为空字符串,我们的提交是否应该没有错误地完成?关于meta共识是可以忽略对STDERR的输出,但是由于您明确提到了它,因此我不得不问一下。
丹尼斯

@Dennis应该停止输入的空字符串。它不应进入无限循环或将其他文本打印到标准输出。

Answers:


3

点,22 +1 = 23字节

使用-r标志。请注意,这要求您要么1)在输入之后输入EOF(在Linux上为Ctrl-D,在Windows上为Ctrl-Z),要么2)从其他地方输入输入。

(^_@<v)X_@vMa@`\D*\d+`

说明:

                        a is first line of stdin (from -r flag) and v is -1 (implicit)
              `\D*\d+`  Pattern (regex) object that matches zero or more non-digits
                        followed by at least one digit
            a@          Find all non-overlapping matches in a, returning a list of strings
           M            To that list, map a lambda function:
  _@<v                    Argument sans last character (equivalent to Python a[:-1])
(^    )                   Split into a list of characters
        _@v               Last character of argument
       X                  Repeat each character of the list that many times
                          (String multiplication X, like most operators, works item-wise
                          on lists)
                        Auto-print (implicit)

映射操作的结果实际上是一个列表列表,但是默认情况下,列表在打印时只是简单地串联在一起,因此不需要手动转换为字符串。

示例,输入a13b1

Var a gets        "a13b1"
After regex match  ["a13" "b1"]
After map          [["aaa" "111"] ["b"]]
Final output       aaa111b

2天前开始, Pip具有基本的正则表达式支持。很好的时机!


那个与-r标志一起工作(大师也是如此)。(问题指定输入必须来自STDIN。)
丹尼斯

@Dennis Oops,错过了。将标志添加到字节数。我应该能够使用特殊变量q而不是a没有额外的标志,但是似乎有一个错误,它要求输入两次。
DLosc

最后是带有正则表达式支持的高尔夫语言!
丹尼斯

@丹尼斯,我看到你现在转移到点子!
Optimizer

8

Perl / Bash 54 40 + 1 = 41字节

perl -pe's:(\D*\d*)(\d):"\$1=~s/./\$&x$2/egr":ege'

它基本上是一个正则表达式中的正则表达式。还有一点魔术。

说明

外部正则表达式/(\D*\d*)(\d)/g提取每个游程长度编码的组。我们捕获要重复的内容$1以及中的重复次数$2。现在,我们将每个此类组替换为该组的扩展。为此,我们对代码进行"\$1=~s/./\$&x$2/egr" 两次评估(例如通过/ee外部替换上的标志)。

第一次求值只会将重复次数内插到字符串中,而其他变量则由反斜杠保护。因此,假设输入a14,我们现在将拥有代码$1=~s/./$&x4/egr,它将再次被评估。

这会将替换内容应用于$1(要重复的内容a1)的内容。替换匹配每个字符.。该$&变量保存了整场比赛,这是我们重复x4多次。我们/g对每个匹配项进行大体上的操作,然后/r返回替换的字符串,而不是修改$1变量(只读)。因此,内部替换的结果为aaaa1111

-p标志将替换应用于每个输入行并打印出结果。


3
通常将此作为Perl解决方案进行评分,您只需在其中添加1个字节的-p修饰符即可。我数了45个字节。此外,您应该可以使用\D代替[a-z],这也消除了对的需要i
丹尼斯

7

CJam,33 31 27字节

lack,缺少正则表达式使它变得很长。

qN+{:XA,s&L\:L>{])~e*[}&X}%

怎么运行的

我们循环遍历输入字符串的所有字符,并在每次迭代中跟踪最后遇到的字符(第一次从空字符开始)。然后我们检查当前字符为非数字最后一个字符是数字。如果是这样,我们将每个先前字符(尚未重复)重复该次数。

(有些过时的代码扩展)

q{                       }%        e# Read the input (q) and loop through each character
  L                                e# Put variable L (initially empty character) on stack
   A,                              e# Put variable A (equals 10) and create an array 0..9
     s                             e# Convert the array to string "0123456789"
      &                            e# Do a set intersect b/w previous char and 0-9 string
                                   e# If numeric, it gives 1 char string, otherwise 0
       \:LA,s&                     e# Swap to bring current character on top. Store it in L
                                   e# and do the same set intersect with it
              >                    e# Means we are checking that current char is non-numeric
                                   e# and previous numeric
               {      }&           e# Run this block if above is true
                ])~                e# Wrap everything not already repeated in an array and
                                   e# take out the last character and convert it to integer.
                                   e# This is the run length of the preceding string
                   e*              e# Repeat each character in the string, run length times
                     [             e# Start a new array to help when next run length is found
                        L          e# Restore the current character back on stack to be used
                                   e# in next iteration
                           )~e*    e# The last string-run-length pair is not decoded..
                                   e# So we do that now

在这里在线尝试


我确实感谢字节限定符引起的问题的演示。谢谢。我在考虑如何表达限定条件,以使单个指令为多字节字符的语言不会因使用这种漏洞而受到惩罚,而不会允许您显示的UTF编码通过漏洞进入。PS我真的很喜欢看到您提供的算法细分。

6

rs43 71个字符

好吧,这很快就变长了。愚蠢的数字...

(\d)(\D)/\1 \2
+(\w)(\w+?)(\d)(?= |$)/\1\3 \2\3
(\w)(\d)/(\1)^^(\2)
 /

在这里尝试!

原始版本(不适用于像这样的输入123):

+(\D)(\D+)(\d)/\1\3\2\3
(\D)(\d)/(\1)^^(\2)

说明

第一行在包含数字的行之间放置空格,例如a313变成a3 13

第二行连续地展开压缩编码等aa5a5a5

第三行使用重复运算符将的每个实例转换a5为。aaaaa

最后一行删除空格。


它如何处理a123b1
Optimizer

@Optimizer不好。我需要稍微调整一下...
kirbyfan64sos

@Optimizer已修复。
kirbyfan64sos

5

Javascript(ES6),86 83字节

alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>b.replace(/./g,y=>y.repeat(c))))

评论:

alert( // output final result
    prompt(). // take input
    replace(/(.+?)(\d)(?!\d)/g, // replace ungreedy capture group of any characters 
                                // followed by a digit (captured)
                                // and not followed by a digit (negative lookahead)
        (a, b, c)=> // replace with a function
            b.replace(/./g, // replace all characters in b
                y=>y.repeat(c) // with that character repeated c times
            )
    )
)

不会alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>Array(c+1).join(b)))一样吗?它只有71个字节长。
Ismael Miguel

@IsmaelMiguel仅在数字前有单个字符时才有效。数组理解处理单独重复每个字符。
nderscore 2015年

尝试Array(6).join('12'),它将返回'1212121212'
伊斯梅尔·米格尔

此作品有效:(alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>Array(-~c).join(b)))相同的71个字节长,在es6fiddle.net/ia7gocwg上进行了测试)
Ismael Miguel

1
我发现了一种不同的(明显的)方式来说3个字节:D
nderscore

4

CJam,27 25字节

r_'A+1>.{64&1$>{])~f*o}&}

CJam解释器中在线尝试。

怎么运行的

r_                        e# Read a token from STDIN and push a copy.
  'A+                     e# Append the character A to the copy.
     1>                   e# Discard the first character of the copy.
       .{               } e# For each character C of the input string and the
                          e# corresponding character D of the copy:
         64&              e#   Take the bitwise and of D and 64. This pushes @
                          e#   if D is a letter and NUL if it is a digit.
            1$>           e#   Compare the result to a copy of C. This pushes 1
                          e#   if and only if D is a letter and C is a digit.
               {      }&  e#   If the result was 1, do the following:
                ]         e#     Wrap the stack in an array.
                 )~       e#     Pop and evaluate the last character.
                   f*     e#     Repeat each char in the array that many times.
                     o    e#     Print all characters.

3

Pyth,33 32 28字节

ssmm*vedkPdPcz-hMJf<@zT\=UzJ

在线尝试:演示测试工具

说明

我将使用示例输入解释代码aa1a23b2。希望这比没有它容易一些。

                               implicit: z = input string = 'aa1a23b2'
                         Uz    the indices of z: [0, 1, 2, 4, 5, 6, 7]
                  f            filter for indices T, which satisfy:
                   <@zT\=        z[T] < "="
                               this gives us the list of indices [2, 4, 5, 7], 
                               which correspond to digits in z. 
                 J             assignment, J = [2, 4, 5, 7]
               hMJ             increment all element in J: [3, 5, 6, 8]
              -            J   and remove the elements of J:
                                 [3, 5, 6, 8] - [2, 4, 5, 7] = [3, 6, 8]
            cz                 split z at these indices: ['aa1', 'a23', 'b2', '']
           P                   remove last element: ['aa1', 'a23', 'b2']
  m                            map each string d to:
   m     Pd                      map each string k of d-without-last-char to:
     ved                           int(last element of d)
    *   k                          * k
                               this creates [['a', 'a'], ['aaa', '222'], ['bb']]
 s                             sum the lists: ['a', 'a', 'aaa', '222', 'bb']
s                              sum the strings: 'aaaaa222bb'


2

JavaScript的112

alert(prompt().replace(/.*?\d+/g,function(m){for(i=n=m.length-1,o="";i--;){j=m[n];while(j--)o=m[i]+o}return o}))


2

Python 2.7,98个字节

import re
print"".join(c*int(m[-1])for m in 
re.findall(r".+?\d(?!\d)",raw_input())for c in m[:-1])

这只是执行一个简单的正则表达式搜索不带数字的数字,然后对每个组进行字符串算术并将它们重新组合在一起。


您可以通过切换从Python的2至3节省2个字节raw_input变为inputprint需要括号。
Alex A.

是的,但是我更喜欢python 2.7。
递归

1

朱莉娅,105 99 95 87字节

s->join([join([string(b)^(int(p[end])-48)for b=chop(p)])for p=matchall(r"\D*\d*\d",s)])

这将创建一个未命名函数,该函数将字符串作为输入,并返回一个字符串。要给它起个名字,例如f=s->...

这里使用两个数组推导,一个嵌套在另一个内。外部理解对输入字符串的每个匹配正则表达式起作用\D*\d*\d。内部理解会根据尾随数字重复匹配的每个字符。内部数组的元素连接成一个字符串,因此外部数组是一个字符串数组。这些被加入并返回。

在Julia中,字符串可以像字符数组一样对待。但是,请注意,Julia 中的CharString类型没有定义相同的方法。特别是,没有^用于字符的重复方法。这使用了复杂的解决方法:

  • 循环跳过省略最后一个字符的字符串,可使用将其删除chop()
  • 使用将当前字符转换为字符串string()
  • 将结尾的数字(也是一个字符)转换为整数。但是,请注意,例如,int('4')它不返回4。而是返回代码点,在这种情况下为52。因此,我们可以减去48以返回实际整数。
  • string(b)根据重复int(p[end]) - 48

例子:

julia> f("ab3c5")
"aaabbbccccc"

julia> f("a0b3")
"bbb"

julia> f("13b1")
"111b"

1

Python 3中,148 144 136 135字节

w,o,r,d=''.join,'',[],[]
for c in input()+' ':
 if'/'<c<':':d+=[c]
 elif d:o+=w(x*int(w(d))for x in r);r=[c];d=[]
 else:r+=[c]
print(o)

感谢Pietu1998和mbomb007的建议。

Python 2中,161 151 147 139 138字节

也许今天才是漫长的一天,但我一生都无法弄清楚如何打高尔夫球。

w,o,r,d=''.join,'',[],[]
for c in raw_input()+' ':
 if'/'<c<':':d+=[c]
 elif d:o+=w(x*int(w(d))for x in r);r=[c];d=[]
 else:r+=[c]
print o

3
更改为Python 3会节省几个字节(raw_out为,括号为print)。len(d)>0可以替换d为空列表是虚假的,而非空列表是真虚假的。list(...)可以直接到for。方括号中的w([...])是不必要的,因为这是唯一的论点。您可以删除中的空格) for。到目前为止,所有这些都是我想出的小事情。
PurkkaKoodari

@ Pietu1998感谢您的帮助!
卡德,2015年

无需过多更改方法,就可以消除list()字符串的可迭代性。您可以使用w=r=''。如果您愿意对其进行很多更改,请参阅我的解决方案。:)
递归

if c.isdigit()if'/'<c<':'如果我没记错的话,可以成为。
DLosc

@DLosc谢谢,这似乎有效。
卡德2015年

0

Java 7,175字节

String c(String s){String r="",a[];for(String x:s.split("(?<=(\\d)(?!\\d))")){a=x.split("");for(int i=0,j,l=a.length-1;i<l;i++)for(j=0;j++<new Short(a[l]);r+=a[i]);}return r;}

imo面临的挑战比看起来要难。

取消测试的代码:

在这里尝试。

class M{
  static String c(String s){
    String r = "",
           a[];
    for(String x : s.split("(?<=(\\d)(?!\\d))")){
      a = x.split("");
      for(int i = 0, j, l = a.length-1; i < l; i++){
        for(j = 0; j++ < new Short(a[l]); r += a[i]);
      }
    }
    return r;
  }

  public static void main(String[] a){
    System.out.println(c("ab3c5"));
    System.out.println(c("a0b3"));
    System.out.println(c("13b1"));
    System.out.println(c("a13b1"));
    System.out.println(c("a123b1"));
    System.out.println(c("aa2a1b1"));
    System.out.println(c("123"));
  }
}

输出:

aaabbbccccc
bbb
111b
aaa111b
aaa111222b
aaaaab
111222
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.