检查Lyndon字


22

一个林登字是一个字符串,它是严格字典序小比任何其循环旋转。给定一个二进制字符串,请确定它是否是尽可能少的字节中的Lyndon字。

例如,001011是Lyndon单词。通过重复将第一个符号移到末尾,可以得到下面列出的旋转角度。

001011
010110
101100
011001
110010
100101

其中,原始字符串按字典顺序排在第一位,或者等效地代表最小的二进制数。

但是,001001它不是Lyndon单词,因为它的一种旋转方式与其本身相同,因此最早在字典上联系在一起。

一个相关的问题。

输入:非空的二进制字符串或数字列表01。您不能使用数字5来表示101

输出:一致的Truthy或Falsey值,指示字符串是否为Lyndon单词。

不允许专门用于Lyndon单词的内置函数。

测试用例:

长度不超过6的Lyndon单词是:

0
1
01
001
011
0001
0011
0111
00001
00011
00101
00111
01011
01111
000001
000011
000101
000111
001011
001101
001111
010111
011111

长度不超过4的非林登词为:

00
10
11
000
010
100
101
110
111
0000
0010
0100
0101
0110
1000
1001
1010
1011
1100
1101
1110
1111

排行榜:

Answers:


5

Python 2,42

与后缀进行比较,而不用打扰,似乎已经足够了。

f=lambda s,i=1:i/len(s)or s<s[i:]*f(s,i+1)

递归的设置似乎不是很好;也许可以做得更好。

这个44字节的版本使发生的事情更加明显:

lambda s:all(s<=s[i:]for i in range(len(s)))

4

Haskell,43 38字节

f x=all(x<=)$init$scanl(const.tail)x x

scanl(const.tail)x x构建的所有后缀的列表x,包括""末尾的空字符串,用剥离init

编辑:@feersum在我的第一个版本中发现了一个错误,并提出了与后缀进行比较就足够了的想法


它如何检查没有任何旋转x等于x
feersum 2015年

@feersum:不会。这是一个错误。固定它。感谢您的发现!
nimi 2015年



2

CJam,15个 14字节

r_,,\fm<(f>1-!

在CJam解释器中尝试这种小提琴或立即验证所有测试用例

怎么运行的

r              e# Read a token from STDIN.
 _,            e# Push the length of a copy.
   ,           e# Turn length L into [0 ... L-1].
    \fm<       e# Rotate the token 0, ..., and L-1 units to the left.
        (      e# Shift out the first rotation, i.e., the original token.
         f>    e# Compare all other rotations with this one.
           1-  e# Remove 1 from the resulting array of Booleans.
             ! e# Apply logical NOT to turn an empty array into 1, and a
               e# non-empty one into 0.

2

J,11个字符

输出1Lyndon单词和0其他单词。

0=0({/:)<\.

<\.带后缀,然后/:告诉我们如何按字典顺序对其进行排序。{0-th索引处获取条目,并0=检查它是否为零:如果是,则我们有一个Lyndon单词,因为最大的后缀不会在某种程度上改变位置;如果它不为零,则它不是Lyndon单词,因为某些后缀在字典上更早。

   0=0({/:)<\. '001011'
1
   0=0({/:)<\. '001001'
0

2

TeaScript,10个字节

xe»x«xS(i©

非常高尔夫,很短。在线尝试

说明&&取消高尔夫

xe(#x<=xS(i))

xe(#      // Loop through x
          // Check if all iterations return true
    x <=  // Input is less than or equal to...
    xS(i) // Input chopped at current index
)

天哪,你是在殴打Pyth </ s> Dennis!这怎么可能?
ETHproductions

2
@ETHproductions在丹尼斯可以超越高尔夫球的世界中,一切皆有可能:p
Downgoat 2015年

我会在持续的那一刻细细品味这点,然后CJam和Pyth的答案可能会打得更多
Downgoat

等等,等等...我看到它可以正确处理诸如之类的情况00,但是如何做到这一点而又不使自己等于自身(即when i==0)呢?
ETHproductions

@ETHproductions实际上并没有像feersum的回答那样循环,只是比较后缀在功能上是等效的
Downgoat 2015年

1

29岁的哈斯克尔

f s=all(s<=)$init$scanr(:)[]s

检查是否s最多每个非空后缀,如nimi的答案

该表达式scanr(:)[]通过列出生成后缀列表。

>> scanr(:)[] "abcd"
["abcd","bcd","cd","d",""]

init随后摆脱末尾的空字符串。最后,all(s<=)检查每个后缀是否都x满足s<=x。由于第一个后缀s本身,<=因此需要a。


1

Ruby,37个字节

->s{(1...s.size).all?{|i|s[i..-1]>s}}

测试:

lyndon_words = %w(0 1 01 001 011 0001 0011 0111 00001 00011 00101 00111
                  01011 01111 000001 000011 000101 000111 001011 001101
                  001111 010111 011111)

not_lyndon_words = %w(00 10 11 000 010 100 101 110 111 0000 0010 0100 0101
                      0110 1000 1001 1010 1011 1100 1101 1110 1111)

f=->s{(1...s.size).all?{|i|s[i..-1]>s}}

p lyndon_words.all? &f      # => true
p not_lyndon_words.any? &f  # => false

1

滑稽,15字节

JiRJU_j<]x/==&&

这7个字节中的8个主要用于检查它是否不绑定。否则,您可以简单地选择JiR<]==

说明:

J       -- duplicate word
iR      -- all rotations
J       -- duplicate list of all rotations
U_      -- check if list contains no duplicates
j       -- swap
<]      -- find minimum of the list
x/      -- rotate top
==      -- compare minimum with the original word
&&      -- and results of min == orig and list unique


0

Javascript(ES6),129个字节

a=Array;s=prompt();console.log(a.from(a(s.length),(x,i)=>i).map(n=>(s.substring(n)+s.substring(0,n--))).sort().pop().contains(s))

0

Javascript,91 87字节

f=x=>(y=(x+x).slice(1,-1),x[0]==x||!(y.indexOf(x)+1)&&!x.indexOf('0')&&x.slice(-1)==1);

我基本上是将单词与自身连接起来,并检查它是否仍然存在。要检查它是否是最小的数字,我只是检查它是否以0开头并以1结尾。

测验

[
['0',1],
['1',1],
['01',1],
['001',1],
['011',1],
['0001',1],
['0011',1],
['0111',1],
['00001',1],
['00011',1],
['00101',1],
['00111',1],
['01011',1],
['01111',1],
['000001',1],
['000011',1],
['000101',1],
['000111',1],
['001011',1],
['001101',1],
['001111',1],
['010111',1],
['011111',1],
['00',0],
['10',0],
['11',0],
['000',0],
['010',0],
['100',0],
['101',0],
['110',0],
['111',0],
['0000',0],
['0010',0],
['0100',0],
['0101',0],
['0110',0],
['1000',0],
['1001',0],
['1010',0],
['1011',0],
['1100',0],
['1101',0],
['1110',0],
['1111',0]
].forEach(t =>{ 
  r=f(t[0])
  x=t[1]
  console.log('Test '+(r==x?'OK':'Fail (Expected: ' + x +')')
  +'\nInput: '+t[0]+'\nResult: ' +r+'\n')                       
})  

0

Mathematica,86个字节

(s=Table[#~StringRotateLeft~i,{i,StringLength@#}];Last@s==First@Sort@s&&s~Count~#==1)&

输入

[“ 1111”]

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.