8
8
# nextprod,
9
9
10
10
11
- # integer partitions
11
+ # integer partitions
12
12
13
13
struct IntegerPartitions
14
14
n:: Int
@@ -24,17 +24,56 @@ function Base.iterate(p::IntegerPartitions, xs = Int[])
24
24
end
25
25
26
26
"""
27
- partitions(n)
28
-
29
- Generate all integer arrays that sum to `n`. Because the number of partitions can be very
30
- large, this function returns an iterator object. Use `collect(partitions(n))` to get an
31
- array of all partitions. The number of partitions to generate can be efficiently computed
32
- using `length(partitions(n))`.
27
+ partitions(n::Integer)
28
+
29
+ Generate all integer arrays that sum to `n`.
30
+
31
+ Because the number of partitions can be very large,
32
+ this function returns an iterator object.
33
+ Use `collect(partitions(n))` to get an array of all partitions.
34
+
35
+ The number of partitions to generate can be efficiently computed using
36
+ `length(partitions(n))`.
37
+
38
+ See also:
39
+ - [`integer_partitions(n::Integer)`](@ref)
40
+ for a non-iterator version that returns all partitions as a array
41
+ - [`partitions(n::Integer, m::Integer)`](@ref)
42
+ for partitions with exactly `m` parts.
43
+
44
+ ## Examples
45
+ ```jldoctest
46
+ julia> collect(partitions(2))
47
+ 2-element Vector{Vector{Int64}}:
48
+ [2]
49
+ [1, 1]
50
+
51
+ julia> collect(partitions(3))
52
+ 3-element Vector{Vector{Int64}}:
53
+ [3]
54
+ [2, 1]
55
+ [1, 1, 1]
56
+
57
+ julia> integer_partitions(3)
58
+ 3-element Vector{Vector{Int64}}:
59
+ [1, 1, 1]
60
+ [2, 1]
61
+ [3]
62
+
63
+ julia> first(partitions(10))
64
+ 1-element Vector{Int64}:
65
+ 10
66
+
67
+ julia> length(partitions(10))
68
+ 42
69
+ ```
70
+
71
+ # References
72
+ - [Integer partition - Wikipedia](https://en.wikipedia.org/wiki/Integer_partition)
33
73
"""
34
74
partitions (n:: Integer ) = IntegerPartitions (n)
35
75
36
76
37
-
38
77
function nextpartition (n, as)
39
78
isempty (as) && return Int[n]
40
79
@@ -97,12 +136,47 @@ Base.length(f::FixedPartitions) = npartitions(f.n,f.m)
97
136
Base. eltype (f:: FixedPartitions ) = Vector{Int}
98
137
99
138
"""
100
- partitions(n, m)
101
-
102
- Generate all arrays of `m` integers that sum to `n`. Because the number of partitions can
103
- be very large, this function returns an iterator object. Use `collect(partitions(n, m))` to
104
- get an array of all partitions. The number of partitions to generate can be efficiently
105
- computed using `length(partitions(n, m))`.
139
+ partitions(n::Integer, m::Integer)
140
+
141
+ Generate all integer partitions of `n` into exactly `m` parts, that sum to `n`.
142
+
143
+ Because the number of partitions can be very large,
144
+ this function returns an iterator object.
145
+ Use `collect(partitions(n, m))` to get an array of all partitions.
146
+
147
+ The number of partitions to generate can be efficiently computed using
148
+ `length(partitions(n, m))`.
149
+
150
+ See also: [`partitions(n::Integer)`](@ref)
151
+
152
+ ## Examples
153
+ ```jldoctest
154
+ julia> collect(partitions(4))
155
+ 5-element Vector{Vector{Int64}}:
156
+ [4]
157
+ [3, 1]
158
+ [2, 2]
159
+ [2, 1, 1]
160
+ [1, 1, 1, 1]
161
+
162
+ julia> collect(partitions(4, 2))
163
+ 2-element Vector{Vector{Int64}}:
164
+ [3, 1]
165
+ [2, 2]
166
+
167
+ julia> collect(partitions(4, 4))
168
+ 1-element Vector{Vector{Int64}}:
169
+ [1, 1, 1, 1]
170
+
171
+ julia> collect(partitions(4, 5))
172
+ Vector{Int64}[]
173
+
174
+ julia> partitions(4, 0)
175
+ ERROR: DomainError with (4, 0):
176
+ n and m must be positive
177
+ Stacktrace:
178
+ [...]
179
+ ```
106
180
"""
107
181
partitions (n:: Integer , m:: Integer ) =
108
182
n >= 1 && m >= 1 ?
@@ -176,11 +250,45 @@ Base.eltype(p::SetPartitions) = Vector{Vector{eltype(p.s)}}
176
250
"""
177
251
partitions(s::AbstractVector)
178
252
179
- Generate all set partitions of the elements of an array `s`, represented as arrays of
180
- arrays. Because the number of partitions can be very large, this function returns an
181
- iterator object. Use `collect(partitions(s))` to get an array of all partitions. The
182
- number of partitions to generate can be efficiently computed using
183
- `length(partitions(s))`.
253
+ Generate all set partitions of the elements of an array `s`,
254
+ represented as arrays of arrays.
255
+
256
+ Because the number of partitions can be very large,
257
+ this function returns an iterator object.
258
+ Use `collect(partitions(s))` to get an array of all partitions.
259
+
260
+ The number of partitions of an `n`-element set
261
+ is given by the n-th Bell number `Bn`:
262
+ `length(partitions(s)) == bellnum(length(s))`.
263
+
264
+ See also: [`bellnum`](@ref)
265
+
266
+ # Examples
267
+ ```jldoctest
268
+ julia> collect(partitions([1, 1]))
269
+ 2-element Vector{Vector{Vector{Int64}}}:
270
+ [[1, 1]]
271
+ [[1], [1]]
272
+
273
+ julia> collect(partitions(-1:-1:-2))
274
+ 2-element Vector{Vector{Vector{Int64}}}:
275
+ [[-1, -2]]
276
+ [[-1], [-2]]
277
+
278
+ julia> collect(partitions('a':'c'))
279
+ 5-element Vector{Vector{Vector{Char}}}:
280
+ [['a', 'b', 'c']]
281
+ [['a', 'b'], ['c']]
282
+ [['a', 'c'], ['b']]
283
+ [['a'], ['b', 'c']]
284
+ [['a'], ['b'], ['c']]
285
+
286
+ julia> length(partitions(1:10)) == bellnum(10)
287
+ true
288
+ ```
289
+
290
+ # References
291
+ - [Partition of a set - Wikipedia](https://en.wikipedia.org/wiki/Partition_of_a_set)
184
292
"""
185
293
partitions (s:: AbstractVector ) = SetPartitions (s)
186
294
@@ -257,11 +365,45 @@ Base.eltype(p::FixedSetPartitions) = Vector{Vector{eltype(p.s)}}
257
365
partitions(s::AbstractVector, m::Int)
258
366
259
367
Generate all set partitions of the elements of an array `s` into exactly `m` subsets,
260
- represented as arrays of arrays. Because the number of partitions can be very large,
261
- this function returns an iterator object. Use `collect(partitions(s, m))` to get
262
- an array of all partitions. The number of partitions into `m` subsets is equal to the
263
- Stirling number of the second kind, and can be efficiently computed using
264
- `length(partitions(s, m))`.
368
+ represented as arrays of arrays.
369
+
370
+ Because the number of partitions can be very large,
371
+ this function returns an iterator object.
372
+ Use `collect(partitions(s, m))` to get an array of all partitions.
373
+
374
+ The number of partitions into `m` subsets is equal to
375
+ the Stirling number of the second kind,
376
+ and can be efficiently computed using `length(partitions(s, m))`.
377
+
378
+ See also: [`stirlings2(n::Int, k::Int)`](@ref)
379
+
380
+ # Examples
381
+ ```jldoctest
382
+ julia> collect(partitions('a':'c', 3))
383
+ 1-element Vector{Vector{Vector{Char}}}:
384
+ [['a'], ['b'], ['c']]
385
+
386
+ julia> collect(partitions([1, 1, 1], 2))
387
+ 3-element Vector{Vector{Vector{Int64}}}:
388
+ [[1, 1], [1]]
389
+ [[1, 1], [1]]
390
+ [[1], [1, 1]]
391
+
392
+ julia> collect(partitions(1:3, 2))
393
+ 3-element Vector{Vector{Vector{Int64}}}:
394
+ [[1, 2], [3]]
395
+ [[1, 3], [2]]
396
+ [[1], [2, 3]]
397
+
398
+ julia> stirlings2(3, 2)
399
+ 3
400
+
401
+ julia> length(partitions(1:10, 3)) == stirlings2(10, 3)
402
+ true
403
+ ```
404
+
405
+ # References
406
+ - [Partition of a set - Wikipedia](https://en.wikipedia.org/wiki/Partition_of_a_set)
265
407
"""
266
408
partitions (s:: AbstractVector , m:: Int ) =
267
409
length (s) >= 1 && m >= 1 ?
@@ -394,15 +536,31 @@ end
394
536
"""
395
537
prevprod(a::Vector{Int}, x)
396
538
397
- Previous integer not greater than `x` that can be written as ``\\ prod k_i^{p_i}`` for
398
- integers ``p_1``, ``p_2``, etc.
539
+ Find the largest integer not greater than `x`
540
+ that can be expressed as a product of powers of the elements in `a`.
541
+
542
+ This function computes the largest value `y ≤ x` that can be written as:
543
+ ```math
544
+ y = \\ prod a_i^{n_i}
545
+ = a_1^{n_1} a_2^{n_2} \\ cdots a_k^{n_k}
546
+ \\ leq x
547
+ ```
548
+ where ``n_i`` is a non-negative integer, `k` is the length of Vector `a`.
549
+
550
+ # Examples
551
+ ```jldoctest
552
+ julia> prevprod([10], 1000) # 1000 = 10^3
553
+ 1000
399
554
400
- For integers ``i_1``, ``i_2``, ``i_3``, this is equivalent to finding the largest ``x``
401
- such that
555
+ julia> prevprod([2, 5], 30) # 25 = 2^0 * 5^2
556
+ 25
402
557
403
- ``i_1^{n_1} i_2^{n_2} i_3^{n_3} \\ leq x``
558
+ julia> prevprod([2, 3], 100) # 96 = 2^5 * 3^1
559
+ 96
404
560
405
- for integers ``n_1``, ``n_2``, ``n_3``.
561
+ julia> prevprod([2, 3, 5], 1) # 1 = 2^0 * 3^0 * 5^0
562
+ 1
563
+ ```
406
564
"""
407
565
function prevprod (a:: Vector{Int} , x)
408
566
if x > typemax (Int)
@@ -446,11 +604,43 @@ end
446
604
"""
447
605
integer_partitions(n)
448
606
449
- List the partitions of the integer `n`.
607
+ Generates all partitions of the integer `n` as a list of integer arrays,
608
+ where each partition represents a way to write `n` as a sum of positive integers.
609
+
610
+ See also: [`partitions(n::Integer)`](@ref)
450
611
451
612
!!! note
452
613
The order of the resulting array is consistent with that produced by the computational
453
614
discrete algebra software GAP.
615
+
616
+ # Examples
617
+ ```jldoctest
618
+ julia> integer_partitions(2)
619
+ 2-element Vector{Vector{Int64}}:
620
+ [1, 1]
621
+ [2]
622
+
623
+ julia> integer_partitions(3)
624
+ 3-element Vector{Vector{Int64}}:
625
+ [1, 1, 1]
626
+ [2, 1]
627
+ [3]
628
+
629
+ julia> collect(partitions(3))
630
+ 3-element Vector{Vector{Int64}}:
631
+ [3]
632
+ [2, 1]
633
+ [1, 1, 1]
634
+
635
+ julia> integer_partitions(-1)
636
+ ERROR: DomainError with -1:
637
+ n must be nonnegative
638
+ Stacktrace:
639
+ [...]
640
+ ```
641
+
642
+ # References
643
+ - [Integer partition - Wikipedia](https://en.wikipedia.org/wiki/Integer_partition)
454
644
"""
455
645
function integer_partitions (n:: Integer )
456
646
if n < 0
@@ -474,12 +664,46 @@ function integer_partitions(n::Integer)
474
664
end
475
665
476
666
477
-
478
- # Noncrossing partitions
667
+ # Noncrossing partitions
479
668
480
669
const _cmp = cmp
481
670
482
- # Produces noncrossing partitions of length n
671
+ """
672
+ ncpartitions(n::Int)
673
+
674
+ Generates all noncrossing partitions of a set of `n` elements,
675
+ returning them as a `Vector` of partition representations.
676
+
677
+ The number of noncrossing partitions of an `n`-element set
678
+ is given by the n-th Catalan number `Cn`:
679
+ `length(ncpartitions(n)) == catalannum(n)`.
680
+
681
+ See also: [`catalannum`](@ref)
682
+
683
+ # Examples
684
+ ```jldoctest
685
+ julia> ncpartitions(1)
686
+ 1-element Vector{Vector{Vector{Int64}}}:
687
+ [[1]]
688
+
689
+ julia> ncpartitions(3)
690
+ 5-element Vector{Vector{Vector{Int64}}}:
691
+ [[1], [2], [3]]
692
+ [[1], [2, 3]]
693
+ [[1, 2], [3]]
694
+ [[1, 3], [2]]
695
+ [[1, 2, 3]]
696
+
697
+ julia> catalannum(3)
698
+ 5
699
+
700
+ julia> length(ncpartitions(6)) == catalannum(6)
701
+ true
702
+ ```
703
+
704
+ # References
705
+ - [Noncrossing partition - Wikipedia](https://en.wikipedia.org/wiki/Noncrossing_partition)
706
+ """
483
707
function ncpartitions (n:: Int )
484
708
partitions = Vector{Vector{Int}}[]
485
709
_ncpart! (1 ,n,n,Vector{Int}[], partitions)
0 commit comments