对字符串进行长度编码


18

假设我们使用以下规则从另一个字符串中拉出一个字符串,该字符串仅包含ASCII可打印字符,并称为*-string。如果在进程停止之前字符串用完,则表示错误,并且在这种情况下,进程的结果是不确定的:

  1. 从...开始 d=1, s=""
  2. 每当遇到a时*,乘以d2。每当遇到另一个字符时,将其连接到的末尾s并从中减去1 d。如果现在d=0停止并返回s

定义的例子

d->d
769->7
abcd56->a
*abcd56->ab
**abcd56->abcd
*7*690->769
***abcdefghij->abcdefgh

未定义的示例:(请注意,空字符串也将是其中之一)

*7
**769
*7*
*a*b
*

您的工作是获取一个字符串并返回*产生该字符串的最短-string。

程式范例

7->7
a->a
ab->*ab
abcd->**abcd
769->*7*69

您的程序应处理任何至少包含一个字符且仅包含非*ASCII可打印字符的字符串。您永远不能返回未定义过程的字符串,因为根据定义,它们不能产生任何字符串。

适用标准漏洞和I / O规则。


我们可以假设输入不包含*吗?
Luis Mendo

3
@DonMuesli “仅非* ASCII可打印字符”
FryAmTheEggman

Answers:


3

Pyth(36 27字节)

感谢Jakube改进了9个字节!目前还不如泥泞鱼的答案,但无论如何

KlzJ1VzWgKyJp\*=yJ)pN=tK=tJ

测试套件

翻译成python:

                            | z=input() #occurs by default
Klz                         | K=len(z)
   J1                       | J=1
     Vz                     | for N in z:
       WgKyJ                |   while K >= J*2:
            p\*             |     print("*", end="")
               =yJ          |     J=J*2
                  )         |     #end inside while
                   pN       |   print(N, end="")
                     =tK    |   K=K-1
                        =tJ |   J=J-1

1
Muddyfish的似乎已经死了...
Rɪᴋᴇʀ

5

JavaScript(ES6),61个字节

f=(s,d=2)=>s?d>s.length?s[0]+f(s.slice(1),d-2):'*'+f(s,d*2):s

递归函数执行以下操作:

  • 如果d小于或等于剩余的字符串长度除以2:

    附加*到输出并乘以d2

  • 其他:

    移动字符串并追加到输出,减去d

实际观看:

f=(s,d=2)=>s?d>s.length?s[0]+f(s.slice(1),d-2):'*'+f(s,d*2):s

input.oninput = e => output.innerHTML = f(input.value);
<input id="input" type="text"/>
<p id="output"></p>


1
通过将d的值加倍,再通过反转条件,再节省一个字节,可以节省2个字节:f=(s,d=2)=>s?d>s.length?s[0]+f(s.slice(1),d-2):'*'+f(s,d*2):s
Neil


2

C,125字节

main(int q,char**v){++v;int i=1,n=strlen(*v);while(n>(i*=2))putchar(42);for(i-=n;**v;--i,++*v)!i&&putchar(42),putchar(**v);}

这利用星形位置非常规则的模式来输出正确的编码。最初,我尝试了蛮力递归解决方案,但回顾起来,显然应该有一个更简单的数学解决方案。

从本质上讲,您将始终2^floor(log_2(length))在输出的开头加星号,并在2^ceil(log_2(length)) - length字符之后加最后一个星号(如果可以算出至少一个字符)。

(略)非高尔夫版本如下

main(int q,char**v){
   ++v;                         // refer to the first command line argument
   int i=1, n=strlen(*v);       // set up iteration variables

   while(n > (i*=2))            // print the first floor(log2(n)) '*'s
      putchar(42);

   for(i-=n;  **v;  --i, ++*v)  // print the string, and the final '*'
      !i&&putchar(42),putchar(**v);
}

1

JavaScript(ES6),88 77字节

f=(s,l=s.length,p=2)=>l<2?s:p<l?"*"+f(s,l,p*2):s.slice(0,p-=l)+"*"+s.slice(p)

起初我以为是abcde必须的,*a**bcde但事实证明它**abc*de同样有效。这意味着使用落地(log 2(s.length))前导星,加上长度不是2的幂的弦的附加星,可以容易地构建输出。

编辑:通过递归计算前导星星的数量节省了8个字节。通过将长度为1的特殊外壳字符串节省了另外3个字节,因此我可以将长度为2的幂的字符串视为额外的前导星。


0

Haskell,68个字节

f d[]=""
f d xs|length xs>=d*2='*':f(d*2)xs
f d(x:xs)=x:f(d-1)xs

确实与其他答案相同。如果为EOF,则输出一个空字符串。如果剩余长度大于两倍d,则输出一个星星并加倍d。否则,输出下一个字符并从中减去一个d

取消高尔夫:

f d (  [])                    = ""
f d (  xs) | length xs >= d*2 = '*' : f (d*2) xs
f d (x:xs)                    =  x  : f (d-1) xs
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.