リンドンの単語を確認する


22

リンドン・ワードは厳密である文字列で辞書順で小さいその環状の回転のいずれよりも。バイナリ文字列が与えられたら、それができるだけ少ないバイト数のリンドン語かどうかを判断します。

たとえば001011、Lyndonの単語です。以下にリストされているその回転は、最初のシンボルを最後まで繰り返し移動することによって取得されます。

001011
010110
101100
011001
110010
100101

これらのうち、元の文字列は辞書的に最初に来るか、同等に、最小のバイナリ数を表します。

ただし、001001Lyndonの単語ではありません。これは、その回転の1つがそれ自体と同じであるため、辞書的に最も早いものに結び付けられているためです。

関連する問題。

入力:空でないバイナリ文字列または数字0とのリスト1。を表すために数字を使用することはできません5101

出力:文字列がリンドン語かどうかを示す一貫したTruthyまたはFalseyの値。

Lyndonの単語専用のビルトインは許可されていません。

テストケース:

最大6文字のリンドン語は次のとおりです。

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

リーダーボード:

回答:


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

@feersum:ありません。バグです。修正しました。見つけてくれてありがとう!
nimi



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©

非常に短いゴルフ。オンラインで試す

説明&& Ungolfed

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
)

聖なる牛、あなたは<s> Pyth </ s> デニスを破っています!これはどのように可能ですか?!
-ETHproductions

2
@ETHproductionsデニスがゴルフで勝負できる世界では、何でも可能です:p
Downgoat

それが続く間、私はその後CJamとPyth答えはおそらくよりgolfedされ、この瞬間を味わうだろう
Downgoat

待って、待って...これはのようなケースを適切に処理しているように見えますが00、それ自体と等しい(つまりwhen i==0)ことをキャッチせずにこれを行うにはどうすればよいですか?
ETHproductions

@ETHproductionsこれは実際にはfeersumの答えのように循環しません。単に接尾辞を比較することは機能的に同等です
-Downgoat

1

ハスケル、29

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

以下のsように、空ではない接尾辞がそれぞれ最大であるかどうかを確認しますnimiのanswerのます

この式scanr(:)[]は、リストによってサフィックスのリストを生成します。

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

initそして、最後に空の文字列を取り除きます。最後に、all(s<=)すべての接尾辞がをx満たすかどうかを確認しますs<=x。最初の接尾辞はsそれ自体なので、a <=が必要です。


1

ルビー、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"]

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.