78
78
# https://www.gnu.org/licenses/
79
79
# ****************************************************************************
80
80
from __future__ import annotations
81
+ from typing import Iterator
81
82
82
83
from .combinat import CombinatorialElement , catalan_number
83
84
from sage .combinat .combinatorial_map import combinatorial_map
@@ -141,10 +142,9 @@ def replace_parens(x):
141
142
"""
142
143
if x == '(' :
143
144
return open_symbol
144
- elif x == ')' :
145
+ if x == ')' :
145
146
return close_symbol
146
- else :
147
- raise ValueError
147
+ raise ValueError
148
148
149
149
150
150
def replace_symbols (x ):
@@ -185,10 +185,9 @@ def replace_symbols(x):
185
185
"""
186
186
if x == open_symbol :
187
187
return '('
188
- elif x == close_symbol :
188
+ if x == close_symbol :
189
189
return ')'
190
- else :
191
- raise ValueError
190
+ raise ValueError
192
191
193
192
194
193
class DyckWord (CombinatorialElement ):
@@ -605,7 +604,7 @@ def __str__(self) -> str:
605
604
sage: print(DyckWord([1, 1, 0, 0]))
606
605
(())
607
606
"""
608
- return "" .join (map ( replace_symbols , [ x for x in self ]) )
607
+ return "" .join (replace_symbols ( x ) for x in self )
609
608
610
609
def to_path_string (self , unicode = False ) -> str :
611
610
r"""
@@ -1756,7 +1755,27 @@ def tamari_interval(self, other):
1756
1755
from sage .combinat .interval_posets import TamariIntervalPosets
1757
1756
return TamariIntervalPosets .from_dyck_words (self , other )
1758
1757
1759
- def to_area_sequence (self ) -> list :
1758
+ def _area_sequence_iter (self ) -> Iterator [int ]:
1759
+ """
1760
+ Return an iterator producing the area sequence.
1761
+
1762
+ .. SEEALSO:: :meth:`to_area_sequence`
1763
+
1764
+ EXAMPLES::
1765
+
1766
+ sage: d = DyckWord([1, 0, 1, 0])
1767
+ sage: [a for a in d._area_sequence_iter()]
1768
+ [0, 0]
1769
+ """
1770
+ a = 0
1771
+ for move in self :
1772
+ if move == open_symbol :
1773
+ yield a
1774
+ a += 1
1775
+ else :
1776
+ a -= 1
1777
+
1778
+ def to_area_sequence (self ) -> list [int ]:
1760
1779
r"""
1761
1780
Return the area sequence of the Dyck word ``self``.
1762
1781
@@ -1806,15 +1825,7 @@ def to_area_sequence(self) -> list:
1806
1825
sage: DyckWord([1,1,0,1,0,0,1,1,0,1,0,1,0,0]).to_area_sequence()
1807
1826
[0, 1, 1, 0, 1, 1, 1]
1808
1827
"""
1809
- seq = []
1810
- a = 0
1811
- for move in self :
1812
- if move == open_symbol :
1813
- seq .append (a )
1814
- a += 1
1815
- else :
1816
- a -= 1
1817
- return seq
1828
+ return list (self ._area_sequence_iter ())
1818
1829
1819
1830
1820
1831
class DyckWord_complete (DyckWord ):
@@ -1927,8 +1938,8 @@ def list_parking_functions(self):
1927
1938
sage: DyckWord([1,0,1,0,1,0]).list_parking_functions()
1928
1939
Standard permutations of 3
1929
1940
"""
1930
- alist = self .to_area_sequence ()
1931
- return Permutations ([i - alist [ i ] + 1 for i in range ( len ( alist ) )])
1941
+ alist = self ._area_sequence_iter ()
1942
+ return Permutations ([i - ai + 1 for i , ai in enumerate ( alist )])
1932
1943
# TODO: upon implementation of ParkingFunction class
1933
1944
# map(ParkingFunction, Permutations([i - alist[i]+1 for i in range(len(alist))]))
1934
1945
@@ -1956,9 +1967,9 @@ def reading_permutation(self) -> Permutation:
1956
1967
sage: DyckWord([1,0,1,1,0,0,1,0]).reading_permutation()
1957
1968
[3, 4, 2, 1]
1958
1969
"""
1959
- alist = self .to_area_sequence ()
1960
- if not alist :
1970
+ if not self :
1961
1971
return Permutation ([]) # type: ignore
1972
+ alist = self .to_area_sequence ()
1962
1973
m = max (alist )
1963
1974
p1 = Word ([m - alist [- i - 1 ]
1964
1975
for i in range (len (alist ))]).standard_permutation ()
@@ -2075,10 +2086,10 @@ def to_312_avoiding_permutation(self) -> Permutation:
2075
2086
True
2076
2087
"""
2077
2088
n = self .semilength ()
2078
- area = self .to_area_sequence ()
2089
+ area = self ._area_sequence_iter ()
2079
2090
pi = Permutations (n ).one ()
2080
- for j in range ( n ):
2081
- for i in range (area [ j ] ):
2091
+ for j , aj in enumerate ( area ):
2092
+ for i in range (aj ):
2082
2093
pi = pi .apply_simple_reflection (j - i )
2083
2094
return pi
2084
2095
@@ -2793,9 +2804,9 @@ def area_dinv_to_bounce_area_map(self) -> DyckWord:
2793
2804
sage: DyckWord([1,0,1,0]).area_dinv_to_bounce_area_map()
2794
2805
[1, 1, 0, 0]
2795
2806
"""
2796
- a = self .to_area_sequence ()
2797
- if not a :
2807
+ if not self :
2798
2808
return self
2809
+ a = self .to_area_sequence ()
2799
2810
a .reverse ()
2800
2811
image = []
2801
2812
for i in range (max (a ), - 2 , - 1 ):
@@ -2844,13 +2855,13 @@ def bounce_area_to_area_dinv_map(self) -> DyckWord:
2844
2855
sage: DyckWord([1,0,1,0]).bounce_area_to_area_dinv_map()
2845
2856
[1, 1, 0, 0]
2846
2857
"""
2847
- aseq = self .to_area_sequence ()
2858
+ aseq = self ._area_sequence_iter ()
2848
2859
out : list [int ] = []
2849
2860
zeros : list [int ] = []
2850
- for i in range ( len ( aseq )) :
2851
- p = (zeros + [len (out )])[aseq [ i ] ]
2861
+ for ai in aseq :
2862
+ p = (zeros + [len (out )])[ai ]
2852
2863
out = [1 ] + out [p :] + [0 ] + out [:p ]
2853
- zeros = [0 ] + [j + len (out ) - p for j in zeros [:aseq [ i ] ]]
2864
+ zeros = [0 ] + [j + len (out ) - p for j in zeros [:ai ]]
2854
2865
return DyckWord (out ) # type:ignore
2855
2866
2856
2867
def area (self ) -> int :
@@ -3093,9 +3104,11 @@ def dinv(self, labeling=None) -> int:
3093
3104
"""
3094
3105
alist = self .to_area_sequence ()
3095
3106
cnt = 0
3096
- for j in range (len (alist )):
3107
+ for j , aj in enumerate (alist ):
3108
+ if labeling is not None :
3109
+ lj = labeling [j ]
3097
3110
for i in range (j ):
3098
- if (alist [i ] - alist [ j ] == 0 and (labeling is None or labeling [i ] < labeling [ j ] )) or (alist [i ] - alist [ j ] == 1 and (labeling is None or labeling [i ] > labeling [ j ] )):
3111
+ if (alist [i ] == aj and (labeling is None or labeling [i ] < lj )) or (alist [i ] - aj == 1 and (labeling is None or labeling [i ] > lj )):
3099
3112
cnt += 1
3100
3113
return cnt
3101
3114
@@ -3933,10 +3946,12 @@ def __iter__(self):
3933
3946
3934
3947
class height_poset (UniqueRepresentation , Parent ):
3935
3948
r"""
3936
- The poset of complete Dyck words compared componentwise by
3937
- ``heights``.
3949
+ The poset of complete Dyck words compared componentwise by ``heights``.
3950
+
3938
3951
This is, ``D`` is smaller than or equal to ``D'`` if it is
3939
3952
weakly below ``D'``.
3953
+
3954
+ This is implemented by comparison of area sequences.
3940
3955
"""
3941
3956
def __init__ (self ):
3942
3957
r"""
@@ -3974,7 +3989,7 @@ def le(self, dw1, dw2):
3974
3989
3975
3990
.. SEEALSO::
3976
3991
3977
- :meth:`heights< sage.combinat.dyck_word.DyckWord.heights> `
3992
+ :meth:`~ sage.combinat.dyck_word.DyckWord.to_area_sequence `
3978
3993
3979
3994
EXAMPLES::
3980
3995
@@ -3994,10 +4009,10 @@ def le(self, dw1, dw2):
3994
4009
True, False, False, False, False, True]
3995
4010
"""
3996
4011
if len (dw1 ) != len (dw2 ):
3997
- raise ValueError ("Length mismatch: %s and %s" % ( dw1 , dw2 ) )
3998
- sh = dw1 .heights ()
3999
- oh = dw2 .heights ()
4000
- return all (sh [ i ] <= oh [ i ] for i in range ( len ( dw1 ) ))
4012
+ raise ValueError (f"length mismatch: { dw1 } and { dw2 } " )
4013
+ ar1 = dw1 ._area_sequence_iter ()
4014
+ ar2 = dw2 ._area_sequence_iter ()
4015
+ return all (a1 <= a2 for a1 , a2 in zip ( ar1 , ar2 ))
4001
4016
4002
4017
4003
4018
class CompleteDyckWords_size (CompleteDyckWords , DyckWords_size ):
0 commit comments