Controlla la parola Lyndon


22

Una parola Lyndon è una stringa che è strettamente lessicograficamente più piccola di una qualsiasi delle sue rotazioni cicliche. Data una stringa binaria, determinare se è una parola Lyndon nel minor numero di byte possibile.

Ad esempio, 001011è una parola di Lyndon. Le sue rotazioni, elencate di seguito, sono ottenute spostando ripetutamente il primo simbolo alla fine.

001011
010110
101100
011001
110010
100101

Di questi, la stringa originale viene prima lessicograficamente, o equivalentemente, rappresenta il numero binario più piccolo.

Tuttavia, 001001non è una parola Lyndon perché una delle sue rotazioni è la stessa di se stessa, che la lega per lessicograficamente prima.

Un problema correlato

Input: una stringa binaria non vuota o un elenco di cifre 0e 1. Si può non usare i numeri, come 5a rappresentare 101.

Output: un valore Truthy o Falsey coerente che indica se la stringa è una parola Lyndon.

Non sono ammessi built-in specifici per le parole di Lyndon.

Casi test:

Le parole di Lyndon con lunghezza fino a 6 sono:

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

Le parole non di Lyndon di lunghezza fino a 4 sono:

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

Classifica:

Risposte:


5

Python 2, 42

Sembra essere abbastanza buono per confrontarsi con i suffissi invece di preoccuparsi di una rotazione.

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

L'allestimento della ricorsione non sembra molto bello; forse potrebbe essere fatto meglio.

Questa versione a 44 byte rende più ovvio cosa sta succedendo:

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

4

Haskell, 43 38 byte

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

scanl(const.tail)x xcrea un elenco di tutti i suffissi di x, compresa la stringa vuota ""alla fine, che viene rimossa con init.

Modifica: @feersum ha individuato un bug nella mia prima versione e mi è venuta l'idea che il confronto con i suffissi è sufficiente.


Come verifica che non vi siano rotazioni xuguali x?
feersum

@feersum: no. È un bug. Aggiustato. Grazie per averlo scoperto!
nimi,



2

CJam, 15 14 byte

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

Prova questo violino nell'interprete CJam o verifica tutti i casi di test contemporaneamente.

Come funziona

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 caratteri

Output 1su parole di Lyndon e 0altro.

0=0({/:)<\.

<\.prende i suffissi e poi /:ci dice come ordinarli lessicograficamente. {prende la voce all'indice 0-th e 0=verifica se è zero: se lo è, abbiamo una parola Lyndon, perché il suffisso più grande non cambierebbe posto in una specie; se è diverso da zero, non è una parola di Lyndon, perché alcuni suffissi sono lessicograficamente precedenti.

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

2

TeaScript , 10 byte

xe»x«xS(i©

Molto golf, molto breve. Provalo online

Spiegazione && 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
)

Vacca santa, stai battendo <s> Pyth </s> Dennis ! Come è possibile ?!
ETHproductions

2
@ETHproductions In un mondo in cui Dennis può giocare a golf tutto è possibile: p
Downgoat

Assaporerò questo momento finché dura, quindi le risposte di CJam e Pyth saranno probabilmente
giocate

Aspetta, aspetta ... Vedo che questo gestisce correttamente casi come 00, ma come fa a farlo senza rendersi conto che è uguale a se stesso (cioè quando i==0)?
ETHproductions

@ETHproductions Questo in realtà non funziona in modo molto simile alla risposta di feersum , semplicemente confrontare i suffissi è funzionalmente equivalente
Downgoat,

1

Haskell, 29

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

Verifica se sè al massimo ciascuno dei suoi suffissi non vuoti, come la risposta di Nimi .

L'espressione scanr(:)[]genera l'elenco di suffissi elencando.

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

Il initottiene quindi liberarsi della stringa vuota alla fine. Infine, all(s<=)controlla se ogni suffisso xsoddisfa s<=x. Poiché il primo suffisso è sstesso, <=è necessario un.


1

Rubino, 37 byte

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

test:

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

Burlesque, 15 byte

JiRJU_j<]x/==&&

Soprattutto 8 di quei 7 byte sono per verificare se non si lega. Altrimenti puoi andare semplicemente JiR<]==.

Spiegazione:

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 byte

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 byte

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

Sto praticamente concatenando la parola con se stessa e controllo se è ancora lì. Per verificare se è il numero più piccolo possibile, controllo solo che inizi con uno 0 e finisca con un 1.

test

[
['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 byte

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

ingresso

[ "1111"]

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.