N次元ベクトルの列挙


17

正の整数k > 1と非負の整数iを指定すると、非負の整数の- kタプル(または- k次元ベクトル)を生成します。すべてのためにk、ℕのにℕからマップkは全単射でなければなりません。つまり、すべての入力iは異なるタプルを生成する必要があり、可能なタプルはすべてinputによって生成される必要がありますi

プログラムまたは関数を作成し、STDIN(または最も近い代替)、コマンドライン引数または関数引数を介して入力を取得し、STDOUT(または最も近い代替)、関数の戻り値または関数(out)パラメーターを介して結果を出力できます。

出力には、便利で明確なフラットリスト形式を使用できます。

あなたのソリューションは、上の人工的な制限を課すべきではないkiはできますが、彼らはあなたの言語のネイティブ整数のサイズに収まることを仮定してもよいです。少なくとも、最大の値をサポートする必要があり255ますが、ネイティブの整数サイズでさえそれより小さくなります。

いずれかのために1 < k < 32、(あなたの答えはサポートされていない場合は、もちろん、あなたのコードは、ほんの数秒で結果を生成する必要があり、以前のルールによる大規模な、制限が相応に調整されていること)。これは何の問題もないはずです。それは、そのようなことは2まで働くことは、この課題を解決することが可能です128数秒ではなく、制限は実際の反復を避け回答にありへの結果を見つけること。i < 231i0i

選択したマッピングの説明と、それが全単射である理由の正当性を回答に含めてください(これは正式な証明である必要はありません)。

これはコードゴルフで、最短の回答(バイト単位)が勝ちです。

関連する課題

回答:


5

Pyth、15 12バイト

ms+0_%Q>_zdQ

テストスイート

私の変換はxnorの1つに似ていますが、ベース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 kCJamインタープリターでオンラインで試してください。

考え

次のようにf(i)を定義することにより、全単射写像f:N→N 2を構築できます。

  • iを2進数の配列に変換します。

  • 奇数の桁がある場合、この配列の前に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( i)))

上記のプロセスを続けると、最終的に全単射マップ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すべてのkth桁を読み取ることにより、バイナリ展開を1つにパックします。たとえば、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:>:)~<:

これは、左右の引数としてikをとる暗黙の二項動詞です。J.jsでオンラインで試してください。

考え

我々は、マップ定義N→Nの:F Kによって=(α:F(I)1、...α K-1、P 1 α K ... P 2 α K + 1 - 1 ...) ⟨p nがです素数の列と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(グラム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は、末尾から開始して2ビットごとに2進数を処理します。その結果q(z), q(z>>1)、2桁の数字が点在する2つの数字が得られzます。たとえば、594は12と17に分割されます。

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

これは全単射です。これは、元の数値を復元するために数値を圧縮して戻すことができるためです。

この関数gは、この全単射k-1時間を適用し、単一要素からペア、トリプル、k-タプルへと展開します。毎回、最後の要素は2つの要素に展開されます。これは、バイジェクションを介して入力をペアにマッピングし、出力の最初のエントリのペアの最初の要素を取得k-1し、2番目の要素に関数を再帰的に適用して残りのエントリを生成することにより、再帰的に行われます。


私はこの方法を複雑にしすぎていることに気付きました
...-xnor
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.