Anonymous user
Permutations/Rank of a permutation: Difference between revisions
→{{header|Ruby}}
m (→{{header|Ruby}}: removed a default argument) |
|||
Line 887:
include Enumerable
attr_reader :num_elements, :size
def initialize(num_elements)
@num_elements = num_elements
@size = fact(num_elements)
end
def each
return self.to_enum unless block_given?
(0...@size
end
def unrank(r) # nonrecursive version of Myrvold Ruskey unrank2 algorithm.
pi =
(@num_elements-1).downto(1) do |n|
s, r = r.divmod(fact(n))
Line 907 ⟶ 906:
pi
end
def rank(
pi = pi.dup
pi1 = pi.zip(0...pi.size).sort.map(&:last)
(pi.size-1).downto(0).inject(0) do |memo,i|
pi[i], pi[pi1[i]] = pi[pi1[i]], (s = pi[i])
pi1[s], pi1[i] = pi1[i], pi1[s]
memo += s * fact(i)
end
end
private
def fact(n)
end
end</lang>▼
▲</lang>
Demo:
<lang ruby>puts "All permutations of 3 items from and back to rank."
perm = Permutation.new(3)
(0...perm.size
puts "\n4 random samples of 12 items
perm = Permutation.new(12)
4.times{
puts "\n4 random uniq samples of 144 items:"
perm, rands = Permutation.new(144), {}
# generate 1_000_000 unique random numbers in the range (0...144!) (takes about 2.5 seconds)
rands[rand(perm.size)] = true until rands.size == 1_000_000
random_perms
# random_perms is lazy. Generate permutations one by one:
4.times do
</lang>▼
p prm = perm.unrank(r)
p perm.rank(prm) == r
▲end</lang>
{{out}}
<pre style="overflow:auto">
Line 954 ⟶ 953:
5 --> [0, 1, 2] --> 5
4 random samples of 12 items
99442243 --> [
337326172 --> [
468353447 --> [
4 random uniq samples of 144 items:
2764575360456493218947191346199563786344679440083424317164174964729286291440941279012888793089017925404664271586714233946361449878956286173028220761623980334868793458099951877456608056440904453668056576598920423670911869425117449937938198123808117853
[12, 130, 62, 35, 60, 95, 2, 31, 54, 61, 51, 18, 48, 118, 32, 124, 17, 9, 122, 10, 86, 137, 24, 90, 57, 138, 120, 94, 53, 3, 40, 15, 69, 11, 22, 134, 87, 143, 115, 8, 129, 49, 43, 50, 97, 16, 41, 127, 93, 119, 73, 6, 65, 106, 55, 100, 88, 42, 64, 5, 121, 77, 131, 72, 126, 113, 78, 0, 46, 68, 39, 76, 116, 34, 107, 110, 139, 26, 83, 38, 141, 80, 56, 84, 23, 142, 111, 75, 82, 103, 70, 21, 123, 66, 104, 96, 27, 135, 33, 1, 140, 37, 81, 105, 112, 132, 102, 92, 14, 136, 91, 20, 7, 13, 25, 59, 36, 133, 79, 19, 63, 45, 28, 67, 109, 85, 108, 114, 44, 128, 99, 101, 4, 89, 117, 47, 29, 52, 98, 74, 30, 125, 58, 71]▼
[
true
[135, 85, 65, 80, 63, 118, 51, 140, 102, 6, 41, 50, 141, 55, 21, 52, 1, 9, 72, 5, 66, 103, 79, 49, 119, 109, 107, 134, 114, 54, 61, 44, 142, 71, 117, 43, 19, 112, 13, 100, 31, 22, 14, 139, 91, 2, 33, 115, 10, 99, 78, 37, 143, 116, 106, 15, 96, 122, 136, 26, 38, 56, 132, 53, 128, 127, 76, 126, 94, 29, 87, 73, 125, 88, 81, 69, 25, 108, 4, 68, 64, 60, 77, 20, 110, 3, 24, 120, 0, 92, 86, 67, 46, 89, 130, 28, 98, 104, 40, 105, 11, 17, 39, 30, 95, 129, 83, 57, 62, 82, 97, 8, 74, 113, 133, 70, 35, 12, 90, 23, 59, 121, 137, 16, 47, 32, 58, 111, 84, 45, 138, 101, 42, 123, 93, 124, 36, 75, 27, 34, 7, 131, 18, 48]▼
581378746619134421610590787114075883604639790081640446988853702372476235480735354011614748882838959943069972039765230962978435387565720009660107060797009355093335736922722607963964082214822692777188121231234716922053393200924081454086807468556348101
[
true
3862828872557168655028927772314213364838836589595169123363755483846504171095746597867391615687467779932466719611353020149271086793608853169788146783569713115890942229488492262312988677553070567823077055419333248270326769623765923370471995234511383513
▲[
true
2918302898022044898081980708265879018867198180047026696353345520178885195108521785334274488901945168232326479535713828754624213355248635860483646511664861481065235873861496511507890774391370483865270125811094164531568140755985423978860285012352192610
▲[
true
</pre>
Really generating one million unique random permutations of 144 elements would take an estimated 11 hours on one core of my machine.
|