Skip to content

Commit

Permalink
Trac #28182: Linear algorithm for squares in words
Browse files Browse the repository at this point in the history
This ticket implement a linear time algorithm to retrieve all the
distinct squares in a word.

URL: https://trac.sagemath.org/28182
Reported by: enadeau
Ticket author(s): Émile Nadeau
Reviewer(s): Nadia Lafrenière, Travis Scrimshaw
  • Loading branch information
Release Manager committed Oct 30, 2019
2 parents d649e7f + 71f2ab7 commit 07b08de
Show file tree
Hide file tree
Showing 3 changed files with 405 additions and 12 deletions.
8 changes: 8 additions & 0 deletions src/doc/en/reference/references/index.rst
Expand Up @@ -1813,6 +1813,14 @@ REFERENCES:
.. [DS1994] J. Dalbec and B. Sturmfels. Invariant methods in discrete and computational geometry,
chapter Introduction to Chow forms, pages 37-58. Springer Netherlands, 1994.
.. [DS2004] Dan Gusfield, Jens Stoye,
Linear time algorithms for finding and representing all the tandem repeats in a string,
Journal of Computer and System Sciences,
Volume 69, Issue 4,
2004,
Pages 525-546,
https://doi.org/10.1016/j.jcss.2004.03.004.
.. [Du2001] \I. Duursma, "From weight enumerators to zeta functions", in
Discrete Applied Mathematics, vol. 111, no. 1-2,
pp. 55-73, 2001.
Expand Down
34 changes: 22 additions & 12 deletions src/sage/combinat/words/finite_word.py
Expand Up @@ -229,7 +229,6 @@
from sage.rings.all import Integer, Infinity, ZZ, QQ
from sage.sets.set import Set


class FiniteWord_class(Word_class):
def __str__(self):
r"""
Expand Down Expand Up @@ -268,7 +267,6 @@ def __str__(self):
sage: print(w)
012340123401234012340123401234012340123401234012340123401234
"""
global word_options
if word_options['display'] == 'string':
ls = word_options['letter_separator']
letters = [str(_) for _ in self]
Expand All @@ -290,7 +288,6 @@ def _repr_(self):
sage: Word(range(100))._repr_()
'word: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,...'
"""
global word_options
if word_options['old_repr']:
if word_options['truncate'] and \
self.length() > word_options['truncate_length']:
Expand Down Expand Up @@ -4062,7 +4059,7 @@ def lyndon_factorization(self):
while k < i:
F.append(k + j - i + 1)
k = k + j - i
return Factorization([self[F[i]:F[i+1]] for i in range(len(F)-1)])
return Factorization([self[F[l]:F[l+1]] for l in range(len(F)-1)])

def inversions(self):
r"""
Expand Down Expand Up @@ -6864,14 +6861,27 @@ def is_square_free(self):
sage: Word('3211').is_square_free()
False
"""
L = self.length()
if L < 2:
return True
for start in range(0, L-1):
for end in range(start+2, L+1, 2):
if self[start:end].is_square():
return False
return True
from sage.combinat.words.suffix_trees import DecoratedSuffixTree
T = DecoratedSuffixTree(self)
return T.square_vocabulary() == [(0, 0)]

def squares(self):
r"""
Returns a set of all distinct squares of ``self``.
EXAMPLES::
sage: sorted(Word('cacao').squares())
[word: , word: caca]
sage: sorted(Word('1111').squares())
[word: , word: 11, word: 1111]
sage: w = Word('00110011010')
sage: sorted(w.squares())
[word: , word: 00, word: 00110011, word: 01100110, word: 1010, word: 11]
"""
from sage.combinat.words.suffix_trees import DecoratedSuffixTree
T = DecoratedSuffixTree(self)
return set(T.square_vocabulary(output='word'))

def is_cube(self):
r"""
Expand Down

0 comments on commit 07b08de

Please sign in to comment.