%8      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{ | } ~        !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./01234567Safe Generates graphviz .dot file from a forest. The first argument tells whether to make the individual trees clustered subgraphs; the second is the name of the graph.Generates graphviz .dot@ file from a tree. The first argument is the name of the graph. 8 9: -make the individual trees clustered subgraphs#reverse the direction of the arrowsname of the graph"reverse the direction of the arrowname of the graph   8 9: Safe,Integer vectors. The indexing starts from 1.+Vector partitions. Basically a synonym for .jGenerates all vector partitions ("algorithm M" in Knuth). The order is decreasing lexicographic. SafeNPartitions of a multiset. Internally, this uses the vector partition algorithmSafe 2Infinite list of primes, using the TMWE algorithm.YA relatively simple but still quite fast implementation of list of primes. By Will Ness Ghttp://www.haskell.org/pipermail/haskell-cafe/2009-November/068441.html?List of primes, using tree merge with wheel. Code by Will Ness.TGroups integer factors. Example: from [2,2,2,3,3,5] we produce [(2,3),(3,2),(5,1)] #The naive trial division algorithm.Largest integer k such that 2^k is smaller or equal to nSmallest integer k such that 2^k is larger or equal to nInteger square root (largest integer whose square is smaller or equal to the input) using Newton's method, with a faster (for large numbers) inital guess based on bit shifts.=Smallest integer whose square is larger or equal to the input*We also return the excess residue; that is (a,r) = integerSquareRoot' n means that "a*a + r = n a*a <= n < (a+1)*(a+1)xNewton's method without an initial guess. For very small numbers (<10^10) it is somewhat faster than the above version. Efficient powers modulo m. powerMod a k m == (a^k) `mod` m!eMiller-Rabin Primality Test (taken from Haskell wiki). We test the primality of the first argument n by using the second argument a' as a candidate witness. If it returs False, then n is composite. If it returns True, then n is either prime or composite.A random choice between 2 and (n-2) is a good choice for a. !;<=>? ! ! !;<=>?None-The boolean argument will True only for the last element08extend lines with spaces so that they have the same line"#$%&'()*+,-./0123456789:;<=>?@"#$%&'()*+,-./0123456789:;<=>?@"#$%&'()*+,-./0123456789:;<=>?@"#$%&'()*+,-./0123456789:;<=>?@NoneAOrder of elements in a matrixDVertical separatorEempty separatorFn spacesG$some custom list of characters, eg. " - "5 (the characters are interpreted as below each other)HHorizontal separatorIempty separatorJn spacesKsome custom string, eg. " | "NVertical alignmentRHorizontal alignmentV1A type class to have a simple way to draw things XnThe type of a (rectangular) ASCII figure. Internally it is a list of lines of the same length plus the size.LNote: The Show instance is pretty-printing, so that it's convenient in ghci.\An empty (0x0) rectanglecDExtends an ASCII figure with spaces horizontally to the given width dBExtends an ASCII figure with spaces vertically to the given heighte3Extend horizontally with the given number of spacesf6Extend vertically with the given number of empty linesgHorizontal indentationhVertical indentationm@Horizontally pads with the given number of spaces, on both sidesnCVertically pads with the given number of empty lines, on both sidesoAPads by single empty lines vertically and two spaces horizontallypHorizontal concatenationqVertical concatenations)Automatically tabulates ASCII rectangles.t4Adds a caption to the bottom, with default settings.u"Adds a caption to the bottom. The BoolL flag specifies whether to add an empty between the caption and the figurevAn ASCII box of the given sizew(An "rounded" ASCII box of the given size:ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrsAwhether to use row-major or column-major ordering of the elements (Right x)3 creates x columns, while @(Left y)$ creates y rowslist of ASCII rectanglestuvwxyz9ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy:XYZ[VWz\]^_`abRSTUNOPQLMcdefghHIJKijDEFGklmnopqrABCstuvwxy'ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz None{H"Tuples" fitting into a give shape. The order is lexicographic, that is, &sort ts == ts where ts = tuples' shape Example: \tuples' [2,3] = [[0,0],[0,1],[0,2],[0,3],[1,0],[1,1],[1,2],[1,3],[2,0],[2,1],[2,2],[2,3]]|,positive "tuples" fitting into a give shape.}# = \prod_i (m_i + 1)~# = \prod_i m_i# = (m+1) ^ len # = m ^ len {|}~length (width)maximum (height)length (width)maximum (height) {|}~ {|}~ {|}~ Safe   None (-1)^kA000142.A006882.A007318.A given row of the Pascal triangle; equivalent to a sequence of binomial numbers, but much more efficient. You can also left-fold over it. +pascalRow n == [ binomial n k | k<-[0..n] ]Catalan numbers. OEIS:A000108.(Catalan's triangle. OEIS:A009766. Note: fcatalanTriangle n n == catalan n catalanTriangle n k == countStandardYoungTableaux (toPartition [n,k])cRows of (signed) Stirling numbers of the first kind. OEIS:A008275. Coefficients of the polinomial (x-1)*(x-2)*...*(x-n+1),. This function uses the recursion formula.O(Signed) Stirling numbers of the first kind. OEIS:A008275. This function uses &, so it shouldn't be used to compute many Stirling numbers.Argument order: signedStirling1st n k3(Unsigned) Stirling numbers of the first kind. See .[Stirling numbers of the second kind. OEIS:A008277. This function uses an explicit formula.Argument order: stirling2nd n kBernoulli numbers. bernoulli 1 == -1%2 and bernoulli k == 0 for k>2 and odd|. This function uses the formula involving Stirling numbers of the second kind. Numerators: A027641, denominators: A027642.PBell numbers (Sloane's A000110) from B(0) up to B(n). B(0)=B(1)=1, B(2)=2, etc. %The Bell numbers count the number of set partitions of a set of size nSee (http://en.wikipedia.org/wiki/Bell_numberiThe n-th Bell number B(n), using the Stirling numbers of the second kind. This may be slower than using . NoneIN All possible ways to choose kZ elements from a list, without repetitions. "Antisymmetric power" for lists. Synonym for . choose_ k n' returns all possible ways of choosing k disjoint elements from [1..n] choose_ k n == choose k [1..n]All possible ways to choose k elements from a list, with repetitions*. "Symmetric power" for lists. See also Math.Combinat.Compositions. TODO: better name?A synonym for .*"Tensor power" for lists. Special case of : 2tuplesFromList k xs == listTensor (replicate k xs) See also Math.Combinat.Tuples. TODO: better name?"Tensor product" for lists.3Sublists of a list having given number of elements.# = binom { n } { k }.All sublists of a list.# = 2^n.randomChoice k n& returns a uniformly random choice of k elements from the set [1..n]Example: Zdo cs <- replicateM 10000 (getStdRandom (randomChoice 3 7)) mapM_ print $ histogram cs@?From a list of $k$ numbers, where the first is in the interval [1..n], the second in [1..n-1], the third in [1..n-2], we create a size k subset of n.1Knuth's method. The first argument is the number n.A?From a list of $k$ numbers, where the first is in the interval [1..n], the second in [1..n-1], the third in [1..n-2], we create a size k subset of n. @A @A None A  composition of an integer n into k parts is an ordered kB-tuple of nonnegative (sometimes positive) integers whose sum is n.kCompositions fitting into a given shape and having a given degree. The order is lexicographic, that is, .sort cs == cs where cs = compositions' shape kbAll positive compositions of a given number (filtrated by the length). Total number of these is 2^(n-1),All compositions fitting into a given shape.+Nonnegative compositions of a given length. # = \binom { len+d-1 } { len-1 }(Positive compositions of a given length.randomComposition k n8 returns a uniformly random composition of the number n as an (ordered) sum of k  nonnegative numbersrandomComposition1 k n8 returns a uniformly random composition of the number n as an (ordered) sum of k positive numbers shapesumlengthsumlengthsum NoneCN;Disjoint cycle notation for permutations. Internally it is [[Int]].NStandard notation for permutations. Internally it is an array of the integers [1..n]. 7Assumes that the input is a permutation of the numbers [1..n].9Checks whether the input is a permutation of the numbers [1..n].Checks the input.Returns n2, where the input is a permutation of the numbers [1..n] This is compatible with Maple's convert(perm,'disjcyc'). BPlus 1 or minus 1.TAction of a permutation on a set. If our permutation is encoded with the sequence [p1,p2,...,pn](, then in the two-line notation we have '( 1 2 3 ... n ) ( p1 p2 p3 ... pn ).We adopt the convention that permutations act  on the left> (as opposed to Knuth, where they act on the right). Thus,  Apermute pi1 (permute pi2 set) == permute (pi1 `multiply` pi2) set3The second argument should be an array with bounds (1,n)(. The function checks the array bounds.The list should be of length n.*Multiplies two permutations together. See  for our conventions. The inverse permutation.The trivial permutation.A synonym for Permutations of [1..n]) in lexicographic order, naive algorithm.# = n!A synonym for .A synonym for .,Generates a uniformly random permutation of [1..n] . Durstenfeld's algorithm (see  *http://en.wikipedia.org/wiki/Knuth_shuffle).Generates a uniformly random cyclic permutation of [1..n]. Sattolo's algorithm (see  *http://en.wikipedia.org/wiki/Knuth_shuffle).YGenerates all permutations of a multiset. The order is lexicographic. A synonym for 3# = \frac { (sum_i n_i) ! } { \prod_i (n_i !) } Generates all permutations of a multiset (based on "algorithm L" in Knuth; somewhat less efficient). The order is lexicographic. (CDBE$$&CDBENone'bWhich orientation to draw the Ferrers diagrams. For example, the partition [5,4,1] corrsponds to:In standard English notation:  @@@@@ @@@@ @<In English notation rotated by 90 degrees counter-clockwise: @ @@ @@ @@ @@@And in French notation:  @ @@@@ @@@@@English notation7English notation rotated by 90 degrees counterclockwise:French notation (mirror of English notation to the x axis)|A partition of an integer. The additional invariant enforced here is that partitions are monotone decreasing sequences of positive integers. The Ord instance is lexicographical.3Sorts the input, and cuts the nonpositive elements.%Assumes that the input is decreasing.BChecks whether the input is an integer partition. See the note at ! This returns True. if the input is non-increasing sequence of positive integers (possibly empty); False otherwise."The first element of the sequence.:The length of the sequence (that is, the number of parts).QThe weight of the partition (that is, the sum of the corresponding sequence)."The dual (or conjugate) partition.IA simpler, but bit slower (about twice?) implementation of dual partitionFrom a sequence  [a1,a2,..,an]' computes the sequence of differences [a1-a2,a2-a3,...,an-0]Example: telements (toPartition [5,4,1]) == [ (1,1), (1,2), (1,3), (1,4), (1,5) , (2,1), (2,2), (2,3), (2,4) , (3,1) ]-We convert a partition to exponential form. (i,e) mean (i^e); for example  [(1,4),(2,3)] corresponds to (1^4)(2^3) = [2,2,2,1,1,1,1]. Another example: NtoExponentialForm (Partition [5,5,3,2,2,2,2,1,1]) == [(1,2),(2,4),(3,1),(5,2)]DComputes the number of "automorphisms" of a given integer partition.Partitions of d.Partitions of d , as listskAll integer partitions up to a given degree (that is, all integer partitions whose sum is less or equal to d)kAll integer partitions up to a given degree (that is, all integer partitions whose sum is less or equal to d), grouped by weight6All integer partitions fitting into a given rectangle.IAll integer partitions fitting into a given rectangle, grouped by weight.# = \binom { h+w } { h }Integer partitions of d+, fitting into a given rectangle, as lists.RPartitions of d, fitting into a given rectangle. The order is again lexicographic.q `dominates` p returns True if q >= p] in the dominance order of partitions (this is partial ordering on the set of partitions of n).See ,http://en.wikipedia.org/wiki/Dominance_order+Lists all partitions of the same weight as lambda and also dominated by lambda0 (that is, all partial sums are less or equal): UdominatedPartitions lam == [ mu | mu <- partitions (weight lam), lam `dominates` mu ]+Lists all partitions of the sime weight as mu and also dominating mu3 (that is, all partial sums are greater or equal): VdominatingPartitions mu == [ lam | lam <- partitions (weight mu), lam `dominates` mu ]Lists partitions of n into k parts. Xsort (partitionsWithKParts k n) == sort [ p | p <- partitions n , numberOfParts p == k ]Naive recursive algorithm.Partitions of n with only odd partsPartitions of n with distinct parts.Note: Klength (partitionsWithDistinctParts d) == length (partitionsWithOddParts d) Returns Truef of the first partition is a subpartition (that is, fit inside) of the second. This includes equality :Sub-partitions of a given partition with the given weight: Psort (subPartitions d q) == sort [ p | p <- partitions d, isSubPartitionOf p q ] 'All sub-partitions of a given partitionThe Pieri rule computes s[lambda]*h[n] as a sum of s[mu]-s (each with coefficient 1).See for example ,http://en.wikipedia.org/wiki/Pieri's_formulaThe dual Pieri rule computes s[lambda]*e[n] as a sum of s[mu]-s (each with coefficient 1) Synonym for (asciiFerrersDiagram' EnglishNotation '@'Try for example: HautoTabulate RowMajor (Right 8) (map asciiFerrersDiagram $ partitions 9)>(height,width)(height,width)(height,width)d(height,width)dk = number of partsn = the integer we partitionk = number of partsn = the integer we partition     <     >     8     None<     None35 An element (i,j)x of the resulting tableau (which has shape of the given partition) means that the vertical part of the hook has length i, and the horizontal part j. The  hook length is thus i+j-1. Example: m> mapM_ print $ hooks $ toPartition [5,4,1] [(3,5),(2,4),(2,3),(2,2),(1,1)] [(2,4),(1,3),(1,2),(1,1)] [(1,1)] 4Checks whether a sequence of positive integers is a  lattice wordF, which means that in every initial part of the sequence any number i) occurs at least as often as the number i+1!OStandard Young tableaux of a given shape. Adapted from John Stembridge,  ?http://www.math.lsa.umich.edu/~jrs/software/SFexamples/tableaux."hook-length formula#ASemistandard Young tableaux of given shape, "naive" algorithm $+Stanley's hook formula (cf. Fulton page 55) !"#$% !"#$% !"#$ !"#$%None35&Set of (i,j) pairs with i>=j>=1.)Triangular arrays0Generates all tableaux of size k. Effective for k<=6.2;Note: This is slow (it actually generates all the tableaux)3<We can flip the numbers in the tableau so that the interval [1..c] becomes [c..1][. This way we a get a maybe more familiar form, when each row and each column is strictly  decreasing" (to the right and to the bottom).#FGHI&'()JKL*+,-MNO./PQRSTUV012W34XY&'()*+,-./01234&'()+*,-./34012 FGHI&'()JKL*+,-MNO./PQRSTUV012W34XYNone5HA plane partition encoded as a tablaeu (the "Z" heights are the numbers)99Throws an exception if the input is not a plane partition:DThe XY projected shape of a plane partition, as an integer partition;!The Z height of a plane partition>oStacks layers of partitions into a plane partition. Throws an exception if they do not form a plane partition.?Stacks layers of partitions into a plane partition. This is unsafe in the sense that we don't check that the partitions fit on the top of each other.@0The "layers" of a plane partition (in direction Z). We should have ,unsafeStackLayers (planePartLayers pp) == ppA"Plane partitions of a given weight 56789:;<=>?@A 56789:;<=>?@A 56789:;<=>?@A 56789:;<=>?@ANoneCBMThe series [1,0,0,0,0,...], which is the neutral element for the convolution.CConstant zero seriesD-Power series representing a constant functionE9The power series representation of the identity function xF#The power series representation of x^nMConvolution of series (that is, multiplication of power series). The result is always an infinite list. Warning: This is slow!N3Convolution (= product) of many series. Still slow!OGGiven a power series, we iteratively compute its multiplicative inverseP#Given a power series starting with 1?, we can compute its multiplicative inverse without divisions.Qg `composeSeries` f" is the power series expansion of g(f(x)). This is a synonym for flip substitute.%We require that the constant term of f is zero.Rsubstitute f g& is the power series corresponding to g(f(x))Y. Equivalently, this is the composition of univariate functions (in the "wrong" order).yNote: for this to be meaningful in general (not depending on convergence properties), we need that the constant term of f is zero.S&Coefficients of the Lagrange inversionT$We expect the input series to match (0:1:_)H. The following is true for the result (at least with exact arithmetic): substitute f (integralLagrangeInversion f) == (0 : 1 : repeat 0) substitute (integralLagrangeInversion f) f == (0 : 1 : repeat 0)U$We expect the input series to match (0:a1:_)X. with a1 nonzero The following is true for the result (at least with exact arithmetic): qsubstitute f (lagrangeInversion f) == (0 : 1 : repeat 0) substitute (lagrangeInversion f) f == (0 : 1 : repeat 0)VPower series expansion of exp(x)WPower series expansion of cos(x)XPower series expansion of sin(x)YPower series expansion of cosh(x)ZPower series expansion of sinh(x)[Power series expansion of log(1+x)\Power series expansion of (1-Sqrt[1-4x])/(2x)+ (the coefficients are the Catalan numbers)]Power series expansion of  /1 / ( (1-x^k_1) * (1-x^k_2) * ... * (1-x^k_n) )Example:(coinSeries [2,3,5])!!k is the number of ways to pay k3 dollars with coins of two, three and five dollars.TODO: better name?^BGeneralization of the above to include coefficients: expansion of <1 / ( (1-a_1*x^k_1) * (1-a_2*x^k_2) * ... * (1-a_n*x^k_n) ) aConvolution of many eG, that is, the expansion of the reciprocal of a product of polynomialsbThe same, with coefficients.dbThis is the most general function in this module; all the others are special cases of this one. eThe power series expansion of -1 / (1 - x^k_1 - x^k_2 - x^k_3 - ... - x^k_n)f!Convolve with (the expansion of) -1 / (1 - x^k_1 - x^k_2 - x^k_3 - ... - x^k_n)gThe expansion of =1 / (1 - a_1*x^k_1 - a_2*x^k_2 - a_3*x^k_3 - ... - a_n*x^k_n)h!Convolve with (the expansion of) =1 / (1 - a_1*x^k_1 - a_2*x^k_2 - a_3*x^k_3 - ... - a_n*x^k_n)j!Convolve with (the expansion of)  21 / (1 +- x^k_1 +- x^k_2 +- x^k_3 +- ... +- x^k_n)Should be faster than using h . Note:  corresponds to the coefficient -1 in g8 (since there is a minus sign in the definition there)!)BCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghij)BCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghij)BCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghij)BCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijNonekA skew partition  lambda/mu is represented by the list &[ (mu_i , lambda_i-mu_i) | i<-[1..n] ]mmkSkewPartition (lambda,mu) creates the skew partition  lambda/mu. Throws an error if mu is not a sub-partition of lambda.nReturns Z if mu is not a sub-partition of lambda.pFThis function "cuts off" the "uninteresting parts" of a skew partitionqGReturns the outer and inner partition of a skew partition, respectively klmnopqrstuvw klmnopqrstuv klmnopqrstuvw klmnopqrstuvwNoneNx>A skew tableau is represented by a list of offsets and entries|0Semi-standard skew tableaux filled with numbers [1..n]The reversed rows, concatenatedThe reversed rows, concatenated7Fills a skew partition with content, in row word order :Fills a skew partition with content, in column word order ZIf the skew tableau's row word is a lattice word, we can make a partition from its contentxyz{|}~Bstring representing the elements of the inner (unfilled) partition xyz{|}~xyz{|}~ xyz{|}~NoneN A Gelfand-Tstetlin tableauHKostka numbers (via counting Gelfand-Tsetlin patterns). See for example *http://en.wikipedia.org/wiki/Kostka_numberK(lambda,mu)==0 unless lambda dominates mu: [[ mu | mu <- partitions (weight lam) , kostkaNumber lam mu > 0 ] == dominatedPartitions lamFVery naive (and slow) implementation of Kostka numbers, for reference.$Lists all (positive) Kostka numbers  K(lambda,mu) with the given lambda: xkostkaNumbersWithGivenLambda lambda == Map.fromList [ (mu , kostkaNumber lambda mu) | mu <- dominatedPartitions lambda ]_It's much faster than computing the individual Kostka numbers, but not as fast as it could be.$Lists all (positive) Kostka numbers  K(lambda,mu) with the given mu: ukostkaNumbersWithGivenMu mu == Map.fromList [ (lambda , kostkaNumber lambda mu) | lambda <- dominatingPartitions mu ]CThis function uses the iterated Pieri rule, and is relatively fast.MGenerates all Kostka-Gelfand-Tsetlin tableau, that is, triangular arrays like /[ 3 ] [ 3 , 2 ] [ 3 , 1 , 0 ] [ 2 , 0 , 0 , 0 ]_with both rows and column non-increasing such that the top diagonal read lambda (in this case  lambda=[3,2]>) and the diagonal sums are partial sums of mu (in this case  mu=[2,1,1,1])BThe number of such GT tableaux is the Kostka number K(lambda,mu).-This returns the corresponding Kostka number: ^countKostkaGelfandTsetlinPatterns lambda mu == length (kostkaGelfandTsetlinPatterns lambda mu) Computes the Schur expansion of h[n1]*h[n2]*h[n3]*...*h[nk]n via iterating the Pieri rule. Note: the coefficients are actually the Kostka numbers; the following is true: vMap.toList (iteratedPieriRule (fromPartition mu)) == [ (lam, kostkaNumber lam mu) | lam <- dominatingPartitions mu ]KThis should be faster than individually computing all these Kostka numbers.AIterating the Pieri rule, we can compute the Schur expansion of %h[lambda]*h[n1]*h[n2]*h[n3]*...*h[nk] Computes the Schur expansion of e[n1]*e[n2]*e[n3]*...*e[nk]n via iterating the Pieri rule. Note: the coefficients are actually the Kostka numbers; the following is true: Map.toList (iteratedDualPieriRule (fromPartition mu)) == [ (dualPartition lam, kostkaNumber lam mu) | lam <- dominatingPartitions mu ]jThis should be faster than individually computing all these Kostka numbers. It is a tiny bit slower than .AIterating the Pieri rule, we can compute the Schur expansion of %e[lambda]*e[n1]*e[n2]*e[n3]*...*e[nk]None[@A diagram is a set of boxes in a skew shape (in the right order)\'A filling is a pair consisting a shape nu and a lattice permutation lpNaive, reference implementation of the Littlewood-Richardson rule, based on the definition "count the semistandard skew tableaux whose row content is a lattice word"lrRule3 computes the expansion of a skew Schur function  s[lambda/mu]$ via the Littlewood-Richardson rule.-Adapted from John Stembridge's Maple code: >http://www.math.lsa.umich.edu/~jrs/software/SFexamples/LR_rule_lrRule lambda mu4 computes the expansion of the skew Schur function  s[lambda/mu]$ via the Littlewood-Richardson rule.]Note: we use reverse ordering in Diagrams compared the Stembridge's code. Also, for performance reasons, we need the length of the diagram[\]^[\]^NoneA partition of the set [1..n] (in standard order) Synonym for  Synonym for  ^sort (setPartitionsWithKParts k n) == sort [ p | p <- setPartitions n , numberOfParts p == k ]List all set partitions of [1..n], naive algorithmSet partitions of the set [1..n] into k parts.Set partitions are counted by the Bell numbersSet partitions of size k3 are counted by the Stirling numbers of second kindk = number of partsn = size of the setk = number of partsn = size of the setk = number of partsn = size of the set  None35DA binary tree with leaves and internal nodes decorated with types a and b, respectively..A binary tree with leaves decorated with type a.+Convert a binary tree to a rose tree (from  Data.Tree)8Generates all sequences of nested parentheses of length 2n in lexigraphic order. Synonym for . Synonym for . Synonym for .Generates all sequences of nested parentheses of length 2n. Order is lexicographical (when right parentheses are considered smaller then left ones). Based on "Algorithm P" in Knuth, but less efficient because of the "idiomatic" code.oGenerates a uniformly random sequence of nested parentheses of length 2n. Based on "Algorithm W" in Knuth.ONth sequence of nested parentheses of length 2n. The order is the same as in #. Based on "Algorithm U" in Knuth.NGenerates all binary trees with n nodes. At the moment just a synonym for .9# = Catalan(n) = \frac { 1 } { n+1 } \binom { 2n } { n }.FThis is also the counting function for forests and nested parentheses.=Generates all binary trees with n nodes. The naive algorithm.1Generates an uniformly random binary tree, using .Grows a uniformly random binary tree. "Algorithm R" (Remy's procudere) in Knuth. Nodes are decorated with odd numbers, leaves with even numbers (from the set [0..2n]"). Uses mutable arrays internally.3Draws a binary tree in ASCII, ignoring node labels.Example: FautoTabulate RowMajor (Right 5) $ map asciiBinaryTree_ $ binaryTrees 4) _n!N; should satisfy 1 <= N <= C(n) `abc.defgh )  # _`abcNone35!]A lattice path is a path using only the allowed steps, never going below the zero level line y=0. nNote that if you rotate such a path by 45 degrees counterclockwise, you get a path which uses only the steps (1,0) and (0,1)Z, and stays above the main diagonal (hence the name, we just use a different convention).A step in a lattice path the step (1,1) the step (1,-1)5Draws the path into a list of lines. For example try: =autotabulate RowMajor (Right 5) (map asciiPath $ dyckPaths 4)=A lattice path is called "valid", if it never goes below the y=0 line.;A Dyck path is a lattice path whose last point lies on the y=0 line Maximal height of a lattice path.Endpoint of a lattice path, which starts from (0,0).BReturns the coordinates of the path (excluding the starting point (0,0), but including the endpoint)Counts the up-stepsCounts the down-steps'Counts both the up-steps and down-steps2Number of peaks of a path (excluding the endpoint)-Number of points on the path which touch the y=00 zero level line (excluding the starting point (0,0)S, but including the endpoint; that is, for Dyck paths it this is always positive!).BNumber of points on the path which touch the level line at height h (excluding the starting point (0,0), but including the endpoint). dyckPaths m lists all Dyck paths from (0,0) to (2m,0). hRemark: Dyck paths are obviously in bijection with nested parentheses, and thus also with binary trees.!Order is reverse lexicographical: +sort (dyckPaths m) == reverse (dyckPaths m) dyckPaths m lists all Dyck paths from (0,0) to (2m,0).  .sort (dyckPathsNaive m) == sort (dyckPaths m) *Naive recursive algorithm, order is ad-hocThe number of Dyck paths from (0,0) to (2m,0)# is simply the m'th Catalan number.The trivial bijection,The trivial bijection in the other directionboundedDyckPaths h m lists all Dyck paths from (0,0) to (2m,0) whose height is at most h. Synonym for .boundedDyckPathsNaive h m lists all Dyck paths from (0,0) to (2m,0) whose height is at most h. sort (boundedDyckPaths h m) == sort [ p | p <- dyckPaths m , pathHeight p <= h ] sort (boundedDyckPaths m m) == sort (dyckPaths m) <Naive recursive algorithm, resulting order is pretty ad-hoc.All lattice paths from (0,0) to (x,y). Clearly empty unless x-y is even. Synonym for All lattice paths from (0,0) to (x,y). Clearly empty unless x-y is even. Note that 1sort (dyckPaths n) == sort (latticePaths (0,2*n))<Naive recursive algorithm, resulting order is pretty ad-hoc.ALattice paths are counted by the numbers in the Catalan triangle.touchingDyckPaths k m lists all Dyck paths from (0,0) to (2m,0)# which touch the zero level line y=0 exactly kI times (excluding the starting point, but including the endpoint; thus, k" should be positive). Synonym for .touchingDyckPathsNaive k m lists all Dyck paths from (0,0) to (2m,0)# which touch the zero level line y=0 exactly kI times (excluding the starting point, but including the endpoint; thus, k should be positive). csort (touchingDyckPathsNaive k m) == sort [ p | p <- dyckPaths m , pathNumberOfZeroTouches p == k ]<Naive recursive algorithm, resulting order is pretty ad-hoc.DThere is a bijection from the set of non-empty Dyck paths of length 2n which touch the zero lines t times, to lattice paths from (0,0) to  (2n-t-1,t-1) (just remove all the down-steps just before touching the zero line, and also the very first up-step). This gives us a counting formula.peakingDyckPaths k m lists all Dyck paths from (0,0) to (2m,0) with exactly k peaks. Synonym for peakingDyckPathsNaive k m lists all Dyck paths from (0,0) to (2m,0) with exactly k peaks. [sort (peakingDyckPathsNaive k m) = sort [ p | p <- dyckPaths m , pathNumberOfPeaks p == k ]<Naive recursive algorithm, resulting order is pretty ad-hoc.Dyck paths of length 2m with k+ peaks are counted by the Narayana numbers &N(m,k) = binom{m}{k} binom{m}{k-1} / m'A uniformly random Dyck path of length 2m"h = the touch levelh = maximum heightm = half-lengthh = maximum heightm = half-lengthk = number of zero-touchesm = half-lengthk = number of zero-touchesm = half-lengthk = number of zero-touchesm = half-lengthk = number of peaksm = half-lengthk = number of peaksm = half-lengthk = number of peaksm = half-length!" None$A non-crossing partition of the set [1..n]t in standard form: entries decreasing in each block and blocks listed in increasing order of their first entries..Checks whether a set partition is noncrossing.Implementation method: we convert to a Dyck path and then back again, and finally compare. Probably not very efficient, but should be better than a naive check for crosses...)5Warning: This function assumes the standard ordering!zConvert to standard form: entries decreasing in each block and blocks listed in increasing order of their first entries.<Throws an error if the input is not a non-crossing partitionCIf a set partition is actually non-crossing, then we can convert it7Bijection between Dyck paths and noncrossing partitionsBased on: David Callan: &Sets, Lists and Noncrossing Partitions&Fails if the input is not a Dyck path.Safe version of 0The inverse bijection (should never fail proper -s) Safe version %Lists all non-crossing partitions of [1..n]XEquivalent to (but orders of magnitude faster than) filtering out the non-crossing ones: f(sort $ catMaybes $ map setPartitionToNonCrossing $ setPartitions n) == sort (nonCrossingPartitions n)%Lists all non-crossing partitions of [1..n] into k parts. nsort (nonCrossingPartitionsWithKParts k n) == sort [ p | p <- nonCrossingPartitions n , numberOfParts p == k ]:Non-crossing partitions are counted by the Catalan numbersNon-crossing partitions with k* parts are counted by the Naranaya numbers'Uniformly random non-crossing partitionk = number of parts n = size of the setk = number of parts n = size of the setNone358Adds unique labels to the nodes (including leaves) of a h8Adds unique labels to the nodes (including leaves) of a g.regularNaryTrees d n' returns the list of (rooted) trees on n$ nodes where each node has exactly d0 children. Note that the leaves do not count in n. Naive algorithm.Ternary trees on n nodes (synonym for regularNaryTrees 3)We have clength (regularNaryTrees d n) == countRegularNaryTrees d n == \frac {1} {(d-1)n+1} \binom {dn} {n}  %# = \frac {1} {(2n+1} \binom {3n} {n} All trees on nZ nodes where the number of children of all nodes is in element of the given set. Example: autoTabulate RowMajor (Right 5) $ map asciiTreeVertical $ map labelNChildrenTree_ $ semiRegularTrees [2,3] 2 [ length $ semiRegularTrees [2,3] n | n<-[0..] ] == [1,2,10,66,498,4066,34970,312066,2862562,26824386,...](The latter sequence is A027307 in OEIS: https://oeis.org/A027307Remark: clearly, we have .semiRegularTrees [d] n == regularNaryTrees d n:Vertical ASCII drawing of a tree, without labels. Example: PautoTabulate RowMajor (Right 5) $ map asciiTreeVertical_ $ regularNaryTrees 2 4 Nodes are denoted by @ , leaves by *.Prints all labels. Example: HasciiTreeVertical $ addUniqueLabelsTree_ $ (regularNaryTrees 3 9) !! 666Nodes are denoted by (label) , leaves by label.9Prints the labels for the leaves, but not for the nodes.DThe leftmost spine (the second element of the pair is the leaf node)(The leftmost spine without the leaf node/The length (number of edges) on the left spine 0leftSpineLength tree == length (leftSpine_ tree)i is leaf, j is node=Attaches the depth to each node. The depth of the root is 0. .Attaches the number of children to each node. fComputes the set of equivalence classes of rooted trees (in the sense that the leaves of a node are  unordered ) with  n = length ks| leaves where the set of heights of the leaves matches the given set of numbers. The height is defined as the number of edges from the leaf to the root. TODO: better name?'(degree = number of children of each nodenumber of nodes!set of allowed number of childrennumber of nodes     kl(      (       '     klNoneSdefgh      NoneA wordy, describing (non-uniquely) an element of a group. The identity element is represented (among others) by the empty word.A generator of a (free) groupThe index of a generator 'Generators are shown as small letters: a, b, c;, ... and their inverses are shown as capital letters, so A=a^-1, B=b^-1, etc."The inverse of a generator#The inverse of a word$:Lists all words of the given length (total number will be (2g)^n'). The numbering of the generators is [1..g].%cLists all words of the given length which do not contain inverse generators (total number will be g^n'). The numbering of the generators is [1..g].&2A random group generator (or its inverse) between 1 and g'9A random group generator (but never its inverse) between 1 and g(A random word of length n using g generators (or their inverses))A random word of length n using g$ generators (but not their inverses)*kMultiplication of the free group (returns the reduced result). It is true for any two words w1 and w2 that EmultiplyFree (reduceWordFree w1) (reduceWord w2) = multiplyFree w1 w2+6Reduces a word in a free group by repeatedly removing x*x^(-1) and x^(-1)*x pairs. The set of  reduced words^ forms the free group; the multiplication is obtained by concatenation followed by reduction.,%Counts the number of words of length n& which reduce to the identity element.Generating function is 9Gf_g(u) = \frac {2g-1} { g-1 + g \sqrt{ 1 - (8g-4)u^2 } }-%Counts the number of words of length n whose reduced form has length k (clearly n and k3 must have the same parity for this to be nonzero): ^countWordReductionsFree g n k == sum [ 1 | w <- allWords g n, k == length (reduceWordFree w) ].'Multiplication in free products of Z2's/'Multiplication in free products of Z3's0'Multiplication in free products of Zm's1%Reduces a word, where each generator x# satisfies the additional relation x^2=1" (that is, free products of Z2's)2%Reduces a word, where each generator x# satisfies the additional relation x^3=1" (that is, free products of Z3's)3%Reduces a word, where each generator x# satisfies the additional relation x^m=1" (that is, free products of Zm's)4BCounts the number of words (without inverse generators) of length n= which reduce to the identity element, using the relations x^2=1.Generating function is 9Gf_g(u) = \frac {2g-2} { g-2 + g \sqrt{ 1 - (4g-4)u^2 } }The first few g cases: A000984 = [ countIdentityWordsZ2 2 (2*n) | n<-[0..] ] = [1,2,6,20,70,252,924,3432,12870,48620,184756...] A089022 = [ countIdentityWordsZ2 3 (2*n) | n<-[0..] ] = [1,3,15,87,543,3543,23823,163719,1143999,8099511,57959535...] A035610 = [ countIdentityWordsZ2 4 (2*n) | n<-[0..] ] = [1,4,28,232,2092,19864,195352,1970896,20275660,211823800,2240795848...] A130976 = [ countIdentityWordsZ2 5 (2*n) | n<-[0..] ] = [1,5,45,485,5725,71445,925965,12335685,167817405,2321105525,32536755565...]5BCounts the number of words (without inverse generators) of length nJ whose reduced form in the product of Z2-s (that is, for each generator x we have x^2=1) has length k (clearly n and k3 must have the same parity for this to be nonzero): _countWordReductionsZ2 g n k == sum [ 1 | w <- allWordsNoInv g n, k == length (reduceWordZ2 w) ]6BCounts the number of words (without inverse generators) of length n= which reduce to the identity element, using the relations x^3=1. acountIdentityWordsZ3NoInv g n == sum [ 1 | w <- allWordsNoInv g n, 0 == length (reduceWordZ2 w) ] In mathematica, the formula is: BSum[ g^k * (g-1)^(n-k) * k/n * Binomial[3*n-k-1, n-k] , {k, 1,n} ] !"#$g = number of generators n = length of the word%g = number of generators n = length of the word&g = number of generators 'g = number of generators (g = number of generators n = length of the word)g = number of generators n = length of the word*+,*g = number of generators in the free group n = length of the unreduced word-*g = number of generators in the free group n = length of the unreduced wordk = length of the reduced word./01234*g = number of generators in the free group n = length of the unreduced word5*g = number of generators in the free group n = length of the unreduced wordk = length of the reduced word6*g = number of generators in the free group n = length of the unreduced word7 !"#$%&'()*+,-./0123456 !7"#$%&'()*+,-./0123456 !"#$%&'()*+,-./01234567NoneTdefgh ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy{|}~      !"#$     m !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwwxyz{|}~           !"#$%&'()*+,-./0123456789:;<=>?@ABBCDEFG1HIJKLMNOOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~A      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRS T UVWXYZZ[\]^_`abcdefghijklmnopqrstuvwxywxzwx{wx|wx}k~k~combi_HoKu3nMnDf35M5MDCHHgSsMath.Combinat.Trees.NaryMath.Combinat.Trees.BinaryMath.Combinat.Trees.GraphvizMath.Combinat.Partitions.Vector!Math.Combinat.Partitions.MultisetMath.Combinat.Numbers.PrimesMath.Combinat.HelperMath.Combinat.ASCIIMath.Combinat.TuplesMath.Combinat.SignMath.Combinat.NumbersMath.Combinat.SetsMath.Combinat.CompositionsMath.Combinat.Permutations Math.Combinat.Partitions.IntegerMath.Combinat.Tableaux*Math.Combinat.Tableaux.GelfandTsetlin.ConeMath.Combinat.Partitions.PlaneMath.Combinat.Numbers.SeriesMath.Combinat.Partitions.SkewMath.Combinat.Tableaux.Skew%Math.Combinat.Tableaux.GelfandTsetlin+Math.Combinat.Tableaux.LittlewoodRichardsonMath.Combinat.Partitions.SetMath.Combinat.LatticePaths$Math.Combinat.Partitions.NonCrossingMath.Combinat.FreeGroupsMath.Combinat.PartitionsMath.Combinat.Trees Math.CombinataddUniqueLabelsForest_addUniqueLabelsTree_addUniqueLabelsForestaddUniqueLabelsTreeBinTree'Branch'Leaf'BinTreeBranchLeafDotgraphvizDotBinTreegraphvizDotBinTree'graphvizDotForestgraphvizDotTree IntVectorvectorPartitions_vectorPartitionsfasc3B_algorithm_MpartitionMultisetprimes primesSimple primesTMWEgroupIntegerFactorsintegerFactorsTrialDivision integerLog2 ceilingLog2isSquareintegerSquareRootceilingSquareRootintegerSquareRoot'integerSquareRootNewton'powerModmillerRabinPrimalityTestdebugswappairs pairsWithsum'equatingreverseOrderingreverseCompare reverseSort groupSortBynubOrd mapWithLast mapWithFirstmapWithFirstLastmkLinesUniformWidthmkBlocksUniformHeightmkUniformBlocks hConcatLines vConcatLinescount histogramfromJust intToBool boolToIntnestunfold1unfold unfoldEitherunfoldM mapAccumM longZipWith MatrixOrderRowMajorColMajorVSep VSepEmpty VSepSpaces VSepStringHSep HSepEmpty HSepSpaces HSepString AlignmentAlignVAlignVTopVCenterVBottomHAlignHLeftHCenterHRight DrawASCIIasciiASCII asciiSize asciiLines emptyRect asciiXSize asciiYSize asciiString printASCIIasciiFromLinesasciiFromString hExtendTo vExtendTo hExtendWith vExtendWithhIndentvIndenthSepSize hSepStringvSepSize vSepStringhPadvPadpadhCatWithvCatWithtabulate autoTabulatecaptioncaption'asciiBoxroundedAsciiBox asciiNumber asciiShow $fShowASCIItuples'tuples1' countTuples' countTuples1'tuplestuples1 countTuples countTuples1 binaryTuplesSignPlusMinus signValue paritySign oppositeSignmulSignproductOfSigns $fMonoidSignparitySignValue factorialdoubleFactorialbinomial pascalRow multinomialcatalancatalanTrianglesignedStirling1stArraysignedStirling1stunsignedStirling1st stirling2nd bernoullibellNumbersArray bellNumberchoosechoose_combinecomposetuplesFromList listTensor kSublistscountKSublistssublists countSublists randomChoice Composition compositions'countCompositions'allCompositions1allCompositions' compositionscountCompositions compositions1countCompositions1randomCompositionrandomComposition1DisjointCycles PermutationfromPermutationpermutationArraytoPermutationUnsafearrayToPermutationUnsafe isPermutation toPermutationpermutationSizefromDisjointCyclesdisjointCyclesUnsafedisjointCyclesToPermutationpermutationToDisjointCyclesisEvenPermutationisOddPermutationsignOfPermutationisCyclicPermutationpermute permuteListmultiplyinverseidentity permutations _permutationspermutationsNaive_permutationsNaivecountPermutationsrandomPermutation_randomPermutationrandomCyclicPermutation_randomCyclicPermutationrandomPermutationDurstenfeldrandomCyclicPermutationSattolopermuteMultisetcountPermuteMultisetfasc2B_algorithm_LPartitionConventionEnglishNotationEnglishNotationCCWFrenchNotationPairHasNumberOfParts numberOfParts Partition mkPartitiontoPartitionUnsafe toPartition isPartition fromPartitionheightwidth heightWidthweight dualPartition_dualPartition_dualPartitionNaive diffSequenceelements _elementstoExponentialForm_toExponentialFormfromExponentialFromcountAutomorphisms_countAutomorphisms partitions _partitionscountPartitions allPartitionsallPartitionsGroupedallPartitions'allPartitionsGrouped'countAllPartitions'countAllPartitions _partitions' partitions'countPartitions' dominatesdominatedPartitions_dominatedPartitionsdominatingPartitions_dominatingPartitionspartitionsWithKPartscountPartitionsWithKPartspartitionsWithOddPartspartitionsWithDistinctPartsisSubPartitionOf subPartitions_subPartitionsallSubPartitions_allSubPartitions pieriRule dualPieriRuleasciiFerrersDiagramasciiFerrersDiagram'$fDrawASCIIPartition$fHasNumberOfPartsPartitionTableau asciiTableau_shapeshape dualTableaucontenthooks hookLengthsrowWordrowWordToTableau columnWordcolumnWordToTableau isLatticeWordstandardYoungTableauxcountStandardYoungTableauxsemiStandardYoungTableauxcountSemiStandardYoungTableaux $fDrawASCII[]TriunTriTriangularArraytriangularArrayUnsafefromTriangularArrayasciiTriangularArraygtSimplexContent_gtSimplexContentgtSimplexTableaux_gtSimplexTableauxcountGTSimplexTableauxinvertGTSimplexTableau_invertGTSimplexTableau PlanePart fromPlanePartisValidPlanePart toPlanePartplanePartShapeplanePartZHeightplanePartWeight singleLayer stackLayersunsafeStackLayersplanePartLayersplanePartitions unitSeries zeroSeries constSeriesidSeries powerTerm addSeries subSeries negateSeries scaleSeries mulSeriesproductOfSeriesconvolve convolveManyreciprocalSeriesintegralReciprocalSeries composeSeries substitute lagrangeCoeffintegralLagrangeInversionlagrangeInversion expSeries cosSeries sinSeries coshSeries sinhSeries log1Series dyckSeries coinSeries coinSeries'convolveWithCoinSeriesconvolveWithCoinSeries'productPSeriesproductPSeries'convolveWithProductPSeriesconvolveWithProductPSeries'pseriesconvolveWithPSeriespseries'convolveWithPSeries' signedPSeriesconvolveWithSignedPSeries SkewPartitionmkSkewPartitionsafeSkewPartitionskewPartitionWeightnormalizeSkewPartitionfromSkewPartitionouterPartitioninnerPartitiondualSkewPartitionasciiSkewFerrersDiagramasciiSkewFerrersDiagram'$fDrawASCIISkewPartition SkewTableau skewShapedualSkewTableausemiStandardSkewTableauxasciiSkewTableauasciiSkewTableau'skewTableauRowWordskewTableauColumnWordfillSkewPartitionWithRowWordfillSkewPartitionWithColumnWordskewTableauRowContent$fDrawASCIISkewTableau$fFunctorSkewTableauGT kostkaNumberkostkaNumberReferenceNaivekostkaNumbersWithGivenLambdakostkaNumbersWithGivenMuasciiGTkostkaGelfandTsetlinPatternskostkaGelfandTsetlinPatterns'!countKostkaGelfandTsetlinPatternsiteratedPieriRuleiteratedPieriRule'iteratedPieriRule''iteratedDualPieriRuleiteratedDualPieriRule'iteratedDualPieriRule'' lrRuleNaivelrRule_lrRule SetPartition_standardizeSetPartitionfromSetPartitiontoSetPartitionUnsafetoSetPartition_isSetPartition setPartitionssetPartitionsWithKPartssetPartitionsNaivesetPartitionsWithKPartsNaivecountSetPartitionscountSetPartitionsWithKParts$fHasNumberOfPartsSetPartitionParen LeftParen RightParenleafforgetNodeDecorations toRoseTree toRoseTree'parenthesesToStringstringToParenthesesforestToNestedParenthesesforestToBinaryTreenestedParenthesesToForestnestedParenthesesToForestUnsafenestedParenthesesToBinaryTree#nestedParenthesesToBinaryTreeUnsafebinaryTreeToNestedParenthesesbinaryTreeToForestnestedParenthesesrandomNestedParenthesesnthNestedParenthesescountNestedParenthesesfasc4A_algorithm_Pfasc4A_algorithm_Wfasc4A_algorithm_U binaryTreescountBinaryTreesbinaryTreesNaiverandomBinaryTreefasc4A_algorithm_RasciiBinaryTree_ LatticePathStepUpStepDownStep asciiPath isValidPath isDyckPath pathHeight pathEndpointpathCoordinatespathNumberOfUpStepspathNumberOfDownStepspathNumberOfUpDownStepspathNumberOfPeakspathNumberOfZeroTouchespathNumberOfTouches' dyckPathsdyckPathsNaivecountDyckPathsnestedParensToDyckPathdyckPathToNestedParensboundedDyckPathsboundedDyckPathsNaive latticePathslatticePathsNaivecountLatticePathstouchingDyckPathstouchingDyckPathsNaivecountTouchingDyckPathspeakingDyckPathspeakingDyckPathsNaivecountPeakingDyckPathsrandomDyckPath NonCrossing_isNonCrossing_isNonCrossingUnsafe_standardizeNonCrossingfromNonCrossingtoNonCrossingUnsafe toNonCrossingtoNonCrossingMaybesetPartitionToNonCrossingdyckPathToNonCrossingPartition#dyckPathToNonCrossingPartitionMaybenonCrossingPartitionToDyckPath$_nonCrossingPartitionToDyckPathMaybenonCrossingPartitionsnonCrossingPartitionsWithKPartscountNonCrossingPartitions$countNonCrossingPartitionsWithKPartsrandomNonCrossingPartition$fHasNumberOfPartsNonCrossingregularNaryTrees ternaryTreescountRegularNaryTreescountTernaryTreessemiRegularTreesasciiTreeVertical_asciiTreeVerticalasciiTreeVerticalLeavesOnly leftSpine rightSpine leftSpine_ rightSpine_leftSpineLengthrightSpineLengthclassifyTreeNode isTreeLeaf isTreeNode isTreeLeaf_ isTreeNode_treeNodeNumberOfChildrencountTreeNodescountTreeLeavescountTreeLabelsWithcountTreeNodesWithlabelDepthTreelabelDepthForestlabelDepthTree_labelDepthForest_labelNChildrenTreelabelNChildrenForestlabelNChildrenTree_labelNChildrenForest_ derivTreesWord GeneratorGenInvunGenshowGenshowWord inverseGen inverseWordallWords allWordsNoInvrandomGeneratorrandomGeneratorNoInv randomWordrandomWordNoInv multiplyFreereduceWordFreecountIdentityWordsFreecountWordReductionsFree multiplyZ2 multiplyZ3 multiplyZm reduceWordZ2 reduceWordZ3 reduceWordZmcountIdentityWordsZ2countWordReductionsZ2countIdentityWordsZ3NoInv$fFunctorGeneratordigraphBracket binTreeDot' binTree'Dot'find2kmpow'mulMod squareModpowModmakeChoiceFromIndicesKnuthmakeChoiceFromIndicesNaivesignValueOfPermutation#randomPermutationDurstenfeldSattoloReverseHoleTableauReverseTableauHolebinom2index'deIndex'toHolenextHolereverseTableau normalize normalize' startHole enumHoleshelper newLines'newLinessizes'$fDrawASCIIArray$fIxTribaseGHC.BaseNothingDiagramFillingfillings nextLetter parenToChar$fDrawASCIIBinTree$fTraversableBinTree$fFoldableBinTree$fFunctorBinTreeconta_LKCPrTJwOTOLk4OU37YmeN Data.Tree subForest rootLabelNodeTreeForest Data.EitherLeftRight derivTrees'$fDrawASCIITree