Перерахування 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

Пітон 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

Пітон 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-tuple. Щоразу останній елемент розширюється на два елементи. Це робиться рекурсивно шляхом відображення вводу в пару через біекцію, взяття першого елемента пари для першого введення виводу і рекурсивно застосовуючи функцію k-1до другого елемента для отримання решти записів.


Я зрозумів, що я роблю цей шлях занадто складним ...
xnor
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.