Перевірте слово Ліндона


22

Ліндон слово є рядком , яка є строго лексикографічно менше , ніж будь-який з його циклічних обертань. Давши двійковий рядок, визначте, чи це слово Ліндона в якомога менше байтах.

Наприклад, 001011це слово Ліндона. Його обертання, перелічені нижче, отримуються шляхом багаторазового переміщення першого символу до кінця.

001011
010110
101100
011001
110010
100101

З них початковий рядок надходить лексикографічно першим, або рівнозначно, являє собою найменше двійкове число.

Однак 001001це не слово Ліндона, оскільки одне з його обертань є таким самим, як і воно, що пов’язує його з лексикографічно ранніми ознаками.

Пов'язана проблема.

Введення: Непорожній двійковий рядок або список цифр 0і 1. Ви не можете використовувати цифри, як 5представити 101.

Вихід: Послідовне значення Truthy або Falsey, яке говорить, чи є рядок словом Ліндона.

Вбудовані спеціально для слів Ліндона заборонені.

Тестові приклади:

Словами Ліндона довжиною до 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

Пітон 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: це не так. Це помилка. Виправлено це. Дякуємо, що дізналися!
німі



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 char

Виводи 1на слова Ліндона та 0інше.

0=0({/:)<\.

<\.бере суфікси, а потім /:розповідає, як сортувати їх лексикографічно. {приймає запис у 0-му індексі і 0=перевіряє, чи не дорівнює нулю: якщо він є, у нас є слово Ліндона, оскільки найбільший суфікс не міняв би місця у своєму роді; якщо це ненульове значення, це не слово Ліндона, тому що якийсь суфікс є лексикографічно раніше.

   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> Dennis ! Як це можливо навіть ?!
ETHproductions

2
@ETHproductions У світі, де Денніс може бути поза полем для гольфу все можливе: p
Пуховик

Я смакую цей момент, поки він триватиме, тоді відповіді CJam і Pyth, ймовірно, будуть побільше гольфу
Downgoat

Почекайте, зачекайте ... Я бачу, що це належним чином обробляє такі випадки 00, але як це зробити, не вловивши себе рівним собі (тобто коли i==0)?
ETHproductions

@ETHproductions Це на самому ділі не так же, як цикл feersum в відповідь , просто порівнюючи суфікси функціонально еквівалентні
Downgoat

1

Хаскелл, 29

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

Перевіряє, чи sє максимум кожен із його не порожніх суфіксів, як відповідь німі .

Вираз scanr(:)[]генерує список суфіксів, перераховуючи.

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

initПотім позбавляється від порожнього рядка в кінці. Нарешті, all(s<=)перевіряє, чи xзадовольняє кожен суфікс s<=x. Оскільки перший суфікс sсам по собі, <=потрібен а.


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/==&&

Переважно 8 з цих 7 байтів перевіряють, чи не пов'язано це. Інакше можна їхати просто 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

Математика, 86 байт

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

вхід

["1111"]

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.