Перечисление N-мерных векторов


17

Если задано положительное целое k > 1и неотрицательное целое число i, kсоздайте кортеж (или k-мерный вектор) неотрицательных целых чисел. Для каждого k, отображение из ℕ в ℕ к , должно быть биективен . То есть каждый вход iдолжен создавать отдельный кортеж, а каждый возможный кортеж должен создаваться каким-либо вводом i.

Вы можете написать программу или функцию, принимая ввод через STDIN (или ближайшую альтернативу), аргумент командной строки или аргумент функции и выводя результат через STDOUT (или ближайшую альтернативу), возвращаемое значение функции или параметр функции (out).

Вы можете использовать любой удобный, однозначный, плоский формат списка для вывода.

Ваше решение не должно налагать никаких искусственных ограничений на kи , iно вы можете предположить , что они вписываются в родной размер целого вашего языка. По крайней мере, вы должны поддерживать значения вплоть до 255, хотя даже ваш собственный целочисленный размер меньше этого.

В любом случае 1 < k < 32, ваш код должен дать результат в считанные секунды (конечно, если ваш ответ не поддерживает такой большой размер из-за предыдущего правила, ограничение корректируется соответствующим образом). Это не должно быть проблемой: это можно решить эту проблему таким образом, что он работает до 2 128 в течение нескольких секунд, но предел есть , чтобы избежать ответов , которые на самом деле итерации от до , чтобы найти результат.i < 231i0i

Пожалуйста, включите в свой ответ описание выбранного вами отображения и обоснование его биективности (это не обязательно должно быть формальным доказательством).

Это код гольф, самый короткий ответ (в байтах) выигрывает.

Связанные проблемы

Ответы:


5

Pyth, 15 12 байт

ms+0_%Q>_zdQ

Тестирование

Мое преобразование похоже на одно из xnor, но в базе 10. Оно работает, распаковывая вход в k отдельных чисел:

n = 21003034
k = 3

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

Числа упорядочены в убывающей позиции самой правой цифры, так что возможны все упорядочения любой группы чисел.

Код работает следующим образом: мы переворачиваем ввод, затем отрезаем последние 0, 1, ... k-1цифры, затем берем каждую kдесятую цифру, снова переворачиваем, вставляем a 0в начале и преобразуем в int.


4

CJam, 20 байтов

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

Отображение является биективным, поскольку оно применяет сопоставление из этого ответа k - 1 раз.

Программа читает вход как i k. Попробуйте онлайн в интерпретаторе CJam .

идея

Мы можем построить биективное отображение f: N → N 2 , определив f (i) следующим образом:

  • Преобразуйте i в массив его двоичных цифр.

  • Добавьте 0 к этому массиву, если есть нечетное количество цифр.

  • Отмените чередование результирующего массива, формируя новые в процессе.

  • Преобразовать эти массивы из базы 2 в целое число. Определите f 1 (i) и f 2 (i) как результаты.

Чтобы получить биективное отображение g: N → N 3 , мы можем определить g (n): = (f 1 (i), f 1 (f 2 (i)), f 2 (f 2 (i))) .

Чтобы получить биективное отображение h: N → N 4 , мы можем определить h (i): = (g 1 (i), g 2 (i), f 1 (g 3 (i)), f 2 (g 3 ( я))) .

Продолжая описанный выше процесс, мы в итоге получаем биективное отображение N → N k .

Код

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#

Идея xnor также дает 20 байтов (или меньше, если вы играете в гольф лучше, чем я): q~2bW%1$Te]/zWf%2fbp(обратный порядок ввода)
Мартин Эндер

3

CJam, 18 байт

q~({)2bW%_1#p))b}*

Он использует более глупую формулу.

Попробуй это здесь .

объяснение

q~          e# Read input.
({          e# Repeat k-1 times:
    )       e# Increment the current integer (initially i), to make it positive.
    2b      e# Convert to binary.
    W%      e# Reverse the binary.
            e# The result can be any non-empty binary string without trailing 0s.
    _1#     e# Find the position of the first 1, or the number of initial 0s.
    p       e# Print.
    )       e# Extract the final bit, which is always 1.
            e# An array that can be any binary string is left in the stack.
    )       e# Increment the 1 to make it 2.
    b       e# Convert the binary string to a number using base 2.
            e# Only the number of initial 0s doesn't affect the result,
            e# which is exactly what is printed before.
}*          e# The final integer is printed automatically when the program ends.

Таким образом, он отображает положительное целое число на:

  1. Количество конечных нулей.
  2. Исходное целое число с удаленными конечными нулями, обратное и конечное (первоначально начальное) 1 удалено.

3

Python 2, 62

lambda z,k:[int('0'+bin(z)[~i:1:-k][::-1],2)for i in range(k)]

Этот код уродлив и пригоден для игры в гольф, но идея очень проста.

Упакуйте kдвоичные расширения в одно, читая каждую kцифру с разными смещениями. Например, с k=3, вход 357отображается в (3,0,7):

101100101 <- 357
  1  0  1 -> 5
 0  0  0  -> 0
1  1  1   -> 7

Сжатие чисел обратно вместе меняет его, так что это биекция. При этом думайте о двоичных разложениях как о бесконечном числе ведущих нулей.


3

J 38 28 27 байт

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

Это молчаливый диадический глагол, который принимает i и k как левый и правый аргументы. Попробуйте его в Интернете с J.js .

идея

Определим отображение F: N → N K по F (I) = (а 1 , ... & alpha ; K-1 , р 1 α к ... р 2 & alpha ; K + 1 ... - 1) , где ⟨p п является последовательность простых чисел и i + 1 = p 1 α 1 p 2 α 2 .

По основной арифметической теореме отображение g: N → N ω, определяемое как g (i): = (α 1 , α 2 ,…) (показатели простой факторизации i + 1 ), биективно.

Поскольку f (i) = (g 1 (i),… g k-1 (i), g -1 (g k (i), g k + 1 (i),…)) , отображение f биективно как Что ж.

Код

                            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.

Почему ваша функция биективна?
xnor

@xnor По крайней мере, одно из моих объяснений не было, так как я поменял пару индексов по ошибке. Я добавил пробный эскиз.
Денис

1

Python 2, 72

q=lambda z:z and z%2+2*q(z/4)
g=lambda z,k:1/k*[z]or[q(z)]+g(q(z/2),k-1)

Функция qдействует на двоичные числа, беря каждый второй бит, начиная с конца. В результате q(z), q(z>>1)приводятся два числа, чьи двоичные цифры перемежаются, чтобы дать z. Например, 594 разбивается на 12 и 17.

1001010010   <- 594
 0 1 1 0 0   ->  12
1 0 0 0 1    ->  17

Это биекция, потому что мы можем сжать числа вместе, чтобы восстановить исходное число.

Функция gприменяет это k-1время биекции , расширяясь от одного элемента к паре к тройке ... к k-тупле. Каждый раз последний элемент расширяется до двух элементов. Это делается рекурсивно, сопоставляя входные данные с парой через биекцию, беря первый элемент пары для первой записи выходных данных и рекурсивно применяя функцию k-1ко второму элементу для получения оставшихся записей.


Я понял, что делаю этот путь слишком сложным ...
xnor
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.