@@ -7,6 +7,7 @@ export is_palindrome, is_pandigital, is_pandigital_nz
77export is_triangular, is_square, is_pentagonal, is_hexagonal
88export divisors, proper_divisors
99export get_σ_tbl, get_max_exp, undigits
10+ export with_replacement_permutations
1011
1112function is_palindrome (num; base= 10 )
1213 x = num
@@ -134,4 +135,49 @@ function undigits(T::Type{<:Integer}, lst::Vector{U}; base::Integer = 10) where
134135 foldr ((x, acc) -> acc * base + x, lst; init = zero (T))
135136end
136137
138+ struct WithReplacementPermutations{T}
139+ a:: T
140+ t:: Integer
141+ end
142+
143+ with_replacement_permutations (a, t:: Integer ) = WithReplacementPermutations (a, t)
144+
145+ function Base. iterate (p:: WithReplacementPermutations , st = nothing )
146+ if isnothing (st)
147+ length (p. a) == 0 && p. t > 0 && return nothing
148+
149+ return ([p. a[1 ] for _ in 1 : p. t], ones (Int, p. t))
150+ else
151+ for k = p. t: - 1 : 1
152+ st[k] == length (p. a) && continue
153+
154+ result = Array {eltype(p.a)} (undef, p. t)
155+ for j = 1 : k
156+ result[j] = p. a[st[j]]
157+ end
158+
159+ st[k] += 1
160+ idx = st[k]
161+ result[k] = p. a[idx]
162+ for j = (k + 1 ): p. t
163+ st[j] = 1
164+ result[j] = p. a[1 ]
165+ end
166+
167+ return (result, st)
168+ end
169+
170+ return nothing
171+ end
172+ end
173+
174+ function Base. length (p:: WithReplacementPermutations )
175+ length (p. a) < p. t && return 0
176+ return Int (length (p. a) ^ p. t)
177+ end
178+
179+ Base. eltype (p:: WithReplacementPermutations ) = Vector{eltype{p. a}}
180+
181+ Base. IteratorSize (p:: WithReplacementPermutations ) = Base. HasLength ()
182+
137183end # module
0 commit comments