Index finite lists of positive integers: Difference between revisions

→‎{{header|Perl 6}}: dealing with lists of length one + fusing the plain solution with the extra-credit one
(→‎{{header|Perl 6}}: dealing with lists of length one + fusing the plain solution with the extra-credit one)
Line 173:
=={{header|Perl 6}}==
 
<lang perl6>sub expand(Int $n is copy, Int $dimension where * > 10) {
return $n if $dimension == 1;
my @reversed-digits = gather while $n > 0 {
take $n % $dimension;
Line 183 ⟶ 184:
}, ^$dimension;
}
 
sub compress(*@n is copy where @n > 10) {
my $dimension = @n.elems;
return @n[0] if $dimension == 1;
reduce * * $dimension + *, 0, 0,
reverse gather while @n.any > 0 {
Line 194 ⟶ 196:
}
}
 
sub rank(@n) { compress compress(@n), +@n - 1}
sub unrank(Int $n) { expandmy ($a, $b) = |expand($n, 2); expand $a, $b + 1 }
 
say my @list = (^10).roll((2..20).pick);
say my $rank = rank @list;
say unrank $rank;</lang>
{{out}}
<pre>4 5 7 9 0 8 8 7 4 8 8 4 1
406578125236287223374090483
4 5 7 9 0 8 8 7 4 8 8 4 1</pre>
 
'''Extra credit'''
 
To get a bijection we need to shift the encoding of the length by two:
 
<lang perl6>sub rank(@n) { compress compress(@n), +@n - 2}
sub unrank(Int $n) { my ($a, $b) = expand($n, 2); expand $a, $b + 2 }
 
for ^10 {
my @unrank = unrank $_;
say $_, " <-> [", @unrank, "] <-> ", rank @unrank;
}</lang>
{{out}}
<pre>0 0 <-> 0
1 0 <-> 1
0 0 0 <-> 2
1 0 0 <-> 3
0 1 <-> 4
1 1 <-> 5
2 0 0 <-> 6
0 1 0 <-> 7
0 0 0 0 <-> 8
1 0 0 0 <-> 9
0 0 0 0 0 <-> 10</pre>
 
{{out}}
This does not deal with the degenerate case of lists of length one, though.
<pre>1 2 2 6 5 7
77692871663419443
1 02 02 06 <->5 97
0 <pre->0 [0] <-> 0
1 0<-> [1] <-> 1
02 <-> [0 0] <-> 2
13 0<-> [1 0] <-> 3
04 1<-> 0[2] <-> 74
05 0 0<-> 0[3] <-> 85
6 <-> [0 1] <-> 46
7 <-> [1 1] <-> 57
28 <-> [0 0 0] <-> 68
09 0<-> 0[1 0 0] <-> 109</pre>
 
=={{header|Python}}==
1,934

edits