Enumerating N-Dimensional Vectors

Pyth, 15 12 bytes

ms+0_%Q>_zdQ

Test suite

My transformation is similar to one of xnor's, but in base 10. It works by unzipping the input into k separate numbers:

n = 21003034
k = 3

21003034
 1  3  4    134
2  0  3     203
  0  0        0

The numbers are ordered in decreasing position of the rightmost digit, so that all orderings of any group of numbers are possible.

The way the code works is we reverse the input, then slice off the last 0, 1, ... k-1 digits, then take every kth digit, reverse again, stick a 0 at the begining, and convert to int.


CJam, 20 bytes

q~({4b2fmd2/z2fb~p}*

The mapping is bijective since it applies the mapping from this answer k - 1 times.

The program reads the input as i k. Try it online in the CJam interpreter.

Idea

We can construct a bijective mapping f : N → N2 by defining f(i) as follows:

  • Convert i into the array of its binary digits.

  • Prepend a 0 to this array if there is an odd number of digits.

  • Deinterleave the resulting array, forming to new ones in the process.

  • Convert those arrays from base 2 to integer. Define f1(i) and f2(i) as the results.

To obtain a bijective mapping g : N → N3, we can define g(n) := (f1(i), f1(f2(i)), f2(f2(i))).

To obtain a bijective mapping h : N → N4, we can define h(i) := (g1(i), g2(i), f1(g3(i)), f2(g3(i))).

Continuing the above process, we eventually arrive at a bijective map N → Nk.

Code

q~      e# Read and evaluate all input. This pushes i and k.
({      e# Do k-1 times:
  4b    e#   Convert the integer on the stack (initially i) to base 4.
  2fmd  e#   Replace each base-4 digit d by d/2 and d%2.
  2/    e#   Split into the chunks [d/2 d%2].
  z     e#   Transpose. This collects all quotients in one array and all
        e#   residues in another one.
  2fb   e#   Convert each array from base 2 to integer.
  ~     e#   Dump both integers on the stack.
  p     e#   Print the topmost one.
}*      e#

J, 38 28 27 bytes

(({.,g^:_1@}.)g=:_ q:>:)~<:

This is a tacit, dyadic verb that takes i and k as left and right arguments. Try it online with J.js.

Idea

We define a map f : N → Nk by f(i) := (α1, … αk-1, p1αk…p2αk+1… - 1), where ⟨pn is the sequence of prime numbers and i + 1 = p1α1p2α2.

By the Fundamental Arithmetic Theorem, the map g : N → Nω defined by g(i) := (α1, α2, …) (exponents of the prime factorization of i + 1) is bijective.

Since f(i) = (g1(i), … gk-1(i), g-1(gk(i), gk+1(i), …)), the map f is bijective as well.

Code

                            Left argument: i -- Right argument: k
                         <: Decerement k.
(                      )~   Reverse the order of the arguments and apply the
                            dyadic verb inside the parentheses to k-1 and i.
              g=:            Define a monadic helper verb g:
                     >:       Increment its right argument.
                 _ q:         Calculate the exponents of the prime factorization.
                             (implicit) Apply g to i.
(            )               Apply the dyadic verb inside the parentheses to k-1
                             and (g i).
           }.                 Drop the first k-1 elements of (g i)...
          @                   and...
     g^:_1                    apply the inverse of g to the result.
  {.                          Take the first k-1 elements of (g i).
    ,                         Append the rightmost result to the leftmost one.