收起反串


27

在此挑战中,将为您提供字母字符串作为输入。我们将给定输入的“反字符串”定义为所有字母都颠倒的字符串。例如

AaBbbUy -> aAbBBuY

您应该编写一个程序,该程序将字符串作为输入,并搜索最长的连续子字符串,该子字符串的反字符串也是连续子字符串。这两个子字符串不应重叠。

例如,如果给您字符串

fAbbAcGfaBBagF

粗体部分将是最长的字符串反字符串对。

一旦找到该对,您的程序应将它们分别折叠成一个字符。它应该通过删除每个子字符串的除第一个字符之外的所有字符来实现。例如上面的字符串

fAbbAcGfaBBagF

会成为

fAcGfagF

然后,您的程序应重复该过程,直到最长的字符串反字符串对为单个字符或更短。

例如,使用相同的字符串,折叠后的新最长对是

fAcGfagF

所以我们再次折叠字符串

fAcGag

现在该字符串无法再折叠,因此我们应将其输出。

如果候选对之间是平局(例如AvaVA),则您可以减少(AaAAvV,但不能Aa)。

这是因此答案将以字节计分,而字节数越少越好。

测试用例

fAbbAcGfaBBagF  ->  fAcGag
AvaVA ->  AaA / AvV
QQQQQQQ -> QQQQQQQ
fAbbAcQQQQaBBacqqqqA -> fAbcQBcq
gaq -> gaq
fAbbAcGfaBBagFaBBa -> fcGaBBag

动机

尽管这个问题似乎是任意的,但实际上是我在编写代码以处理基本面时遇到的问题。该过程可以用于将基本多边形减小为较小的n边。我试了一下之后,以为会打一点高尔夫球。


如果具有反字符串子字符串的最大子字符串具有多个anit-string子字符串,那么应该折叠所有子字符串还是仅折叠前两个子字符串?
乔纳森·弗雷希

@JonathanFrech任何两个。在候选对之间存在平局的情况。
小麦巫师

aaaAAAaaa -> aAaaa
乔纳森·弗雷奇

关于这个问题的一个子集,尖叫着奎因,但我无法动弹。
魔术

1
@MagicOctopusUrn之类的东西写一个两个周期的quine,其中程序的输出是其反字符串
乔纳森·弗雷希

Answers:


8

Perl,64 61字节

包括+1用于p

perl -pE 's/(.\K.{$%})(.*)(?=(.))(??{$1^$"x$%.$"})/$2$3/ while$%=--pos' <<< fAbbAcGfaBBagFaBBa

6

JavaScript(ES6),200字节

对I / O使用字符数组。

f=a=>(m=M=C=>a.map((_,i)=>a.map((_,j)=>C(i,j-i+1))))(I=>M((i,j)=>a.slice(i,i+j).some((n,k)=>n[c='charCodeAt']()^(a[I+k]||'')[c]()^32)|I+j>i|j<m||(x=[i,I],m=j)))&&m-->1?f(a,x.map(p=>a.splice(p+1,m))):a

在线尝试!


3

视网膜,119字节

.+
$&¶$&
T`Ll`lL`.*¶
/(.).*¶.*\1/^&0A`
¶&Lv$`(?<=(.)*)((.)(.)*).*¶(?>((?<-1>.)*.)(?<-4>.)*)(.*)\2
$5$6$3$'
N$`
$.&
}0G`

在线尝试!链接包括测试用例。说明:

.+
$&¶$&
T`Ll`lL`.*¶

复制输入并翻转第一个副本的大小写。

/(.).*¶.*\1/^&0A`

如果根本没有反字符串,则删除翻转的副本。

¶&Lv$`(?<=(.)*)((.)(.)*).*¶(?>((?<-1>.)*.)(?<-4>.)*)(.*)\2
$5$6$3$'

列出所有可能的折叠反字符串。

N$`
$.&
}0G`

按长度顺序对它们进行排序,选择最短的(即最长的反弦),然后重复进行,直到所有反弦都收起为止。


3

Python 3中189 181字节

感谢乔纳森·弗雷奇(Jonathan Frech)使其成为纯粹的单线笔。

f=lambda s,x=set():any(u in s[j+i:]and(x.add(s[:j+1]+s[j+i:].replace(u,u[0],1))or 1)for i in range(len(s),1,-1)for j in range(len(s))for u in[s[j:j+i].swapcase()])and f(x.pop())or s

在线尝试!

我自己的版本,现在已过时(189字节):

x=set()
def f(s):
 while any(u in s[j+i:]and(x.add(s[:j+1]+s[j+i:].replace(u,u[0],1))or 1)for i in range(len(s),1,-1)for j in range(len(s))for u in[s[j:j+i].swapcase()]):s=x.pop()
 return s

在线尝试!

any()尽早打破嵌套循环,并set()在理解中使用可变的全局对象。剩下的只是使用以下命令直接实现需求str.swapcase

Python 2,160字节

def f(s):
 for i in range(len(s),1,-1):
	for j in range(len(s)):
	 u=s[j:j+i].swapcase()
	 if u in s[j+i:]:return f(s[:j+1]+s[j+i:].replace(u,u[0],1))
 return s

在线尝试!

事实证明,具有早期突破功能的常规嵌套for循环return比的“聪明”技巧要短得多any


181字节 ; 递归方法。可变为set函数默认值不会与其他调用冲突,因为我认为您的代码会将设置完全弹出为空。
乔纳森·弗雷希

抱歉,我认为那x将不为空。当您拥有它时,我认为它符合要求。
乔纳森·弗雷希

很好,谢谢您的改进。
Bubbler '18

3

C(GCC) 240个 238 227 225 222 216字节

  • 保存了两个字节;删除了一个杂散变量定义。
  • 保存了十一个十三字节;golfed b|=S[p+m]!=S[q+m]+32-(S[q+m]>90)*64b|=abs(S[p+m]-S[q+m])-32b|=32-S[p+m]+S[q+m]&63
  • 保存了三个字节;golfed for(...;...;p++)S[p+1]=S[p+L];for(...;...;S[++p]=S[p+L]);
  • 多亏了ceilingcat,节省了六个字节。
p,P,q,Q,l,L,b,m;f(char*S){for(p=0;S[p];p++)for(l=0;S[l+++p];)for(q=0;b=S[q+~-l];!b&p+l<=q&l>L?L=l,P=p,Q=q:0,q++)for(b=0,m=l;m--;)b|=32-S[p+m]+S[q+m]&63;for(;b-2;)for(p=b++?-~Q-L:P;S[p];S[++p]=S[L+p]);~-L?L=0,f(S):0;}

在线尝试!


@ceilingcat谢谢。
乔纳森·弗雷希

0

Python 2,180个字节

def f(s):
 L=len(s)
 for x,y in[(i,i+j)for j in range(L,1,-1)for i in range(L-j)]:
	t=s[x:y];T=t.swapcase()
	if T in s[y:]:return f(s.replace(t,t[0],1).replace(T,T[0],1))
 return s

在线尝试!


0

Stax,30 个字节

î☼fúΩ§☺æ╒ºê@Ñ▀'╫Iqa{d]∟Sa5♦⌂─╚

运行并调试

同一程序的相应ascii表示法是这样的。

c%Dc:e{%orF..*:{_{32|^mY++_h.$1yh++R

它使用正则表达式方法。它反复进行正则表达式字符串替换。它从当前值的每个连续子字符串构建这些。例如,对于输入fAbbAcGfaBBagF,子字符串之一是AbbA,在这种情况下,正则表达式AbbA(.*)aBBa将替换为A$1a

c                                       get number of characters
 %D                                     repeat rest of program that many times
   c:e                                  get all substrings
      {%or                              order substrings longest to shortest
          F                             for each substring, execute the rest
           ..*:{                        build the string "(.*)"
                _{32|^m                 current substring with case inverted
                       Y                save the inverted case in register y
                        ++              concatenate search regex together
                                            e.g. "aBc(.*)AbC"
                          _h            first character of substring
                            .$1         "$1"
                               yh       first character of inverted case
                                 ++     concatenate replacement regex together
                                            e.g. "a$1A"
                                   R    do regex replacement


0

Japt -h,33 个字节

à ñÊÅÔ£=rX+"(.*)"+Xc^H ÈÎ+Y+XÎc^H

试试吧

à ñÊÅÔ£=rX+"(.*)"+Xc^H ÈÎ+Y+XÎc^H     :Implicit input of string U
à                                     :Combinations
  ñ                                   :Sort by
   Ê                                  :  Length
    Å                                 :Remove first element (the empty string)
     Ô                                :Reverse
      £                               :Map each X
       =                              :  Reassign to U
        r                             :  Global replacement
         X+"(.*)"+                    :  Append "(.*)" to X and then append
                  Xc                  :    Charcodes of X
                    ^H                :    XORed with 32
                      È               :  Pass each match X, with captured group Y, through the following function
                       Î+Y+           :    Append Y to the first character of X and then append
                           XÎc^H      :      The charcode of the first character of X XORed with 32
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.