ヒルベルトのバイナリーホテル


18

この課題では、2つの特性を満たす機能(または完全なプログラム)を実装するよう求められます。これらのプロパティは次のとおりです。

  • 関数は、非負の整数に対する非負の整数係数を持つ多項式からの単射(可逆)関数でなければなりません。これは、2つの等しくない入力が等しい出力にマップできないことを意味します。

  • 関数は、入力から出力までの「オンビット」の総数を保持する必要があります。つまり、多項式の各係数の1ビットをカウントする場合、それらの合計は出力のバイナリ表現の1ビットの数と同じでなければなりません。例えば9ある1001ことが2つの持つようにバイナリ1ビット。


IO

非負の整数多項式は、特定のポイントの後、すべての整数がゼロになるような非負の整数の無限リストと同じです。したがって、多項式は、無限リスト(おそらく望ましくありませんが)またはリストの末尾の後に暗黙のゼロを持つ有限リストのいずれかで表されます。

多項式と有限リストの主な違いは、リストの末尾にゼロを追加するとリストが変更されることです。

リスト

多項式の最後にゼロを追加しても、その値は変わりません:

多項式

したがって、関数が入力として多項式を表す有限リストをとる場合、ゼロを追加しても結果が変わらないようにする必要があります。

多項式をリストとして表す場合、定数項を表す最初または最後のエントリでそれらを表すことができます。たとえば、次のいずれかの可能性があります。

前方または後方

最初のケースでは、リストの最後にゼロを追加しても結果は変わりません。2番目の場合、リストの先頭にゼロを追加しても結果は変わりません。

もちろん、言語が多項式をサポートしている場合、それらを入力として使用できます。

出力は、任意の標準的な方法による非負の整数出力でなければなりません。


これはため、回答はバイト単位でスコアリングされ、バイト数は少ない方が良いでしょう。


である[]か、[0]有効な入力?
ジョンファンミン

1
@JungHwanMinはい、両方ともゼロ多項式です。
ウィートウィザード

私はあなたがゼロを分割するために1を置くことを意味知っているが、いくつかの方法が動作していないように見えるかもしれない良い...
l4m2

1
@ l4m2申し訳ありませんが、どちらのコメントもわかりません。あなたの質問に関する限り、何に先行ゼロがありますか?多項式、係数?「書かれていないゼロ」の意味もわかりません。
小麦ウィザード

1
画像は本当に必要ですか(つまり、リッチテキストを使用して表現することはできません)?なぜなら、画像を見る能力のない人々はあなたの挑戦を完全に見ることができないからです。
マインドウィン

回答:


6

ゼリー、8バイト

BFṢḄæ«ÆẸ

オンラインでお試しください!

左インバース、5バイト

Bċ0ÆE

オンラインでお試しください!

使い方

BFṢḄæ«ÆẸ  Main link. Argument: A (array)

B         Binary; convert each integer in A to base 2.
 F        Flatten; concatenate the resulting binary arrays.
  Ṣ       Sort the resulting bit array.
   Ḅ      Convert from base 2 to integer, yielding an integer x with as much set
          bits as there are set bits in A.
      ÆẸ  Unexponents; convert A = [a1, a2, ...] to y = (p1**a1 + p2**a2 + ...),
          where pn is the n-th prime number.
          By the fundamental theorem of arithmetic, the resulting integer is unique
          for each array A without trailing zeroes.
    æ«    Bitshift left; compute x * 2**y.

6

Wolfram言語(Mathematica)36 20バイト

x#/.x->2^(#/.x->2)!&

オンラインでお試しください!

入力として多項式f(x)を取ります。y = f(y)を評価します。y= 2 ^(f(2)!)。残念ながら、これは出力がかなり大きくなることを意味します。

y * f(y)を評価すると、yが任意の係数よりも大きい2のべき乗である場合は常に1ビットの数が保持されます。これは上記で選択した値に当てはまります。y = 2 ^(f(2)!)を選択して、結果を単射にします。

  • yの値が同じである2つの異なる入力は、基本的にyの2つの異なる数値を読み取るため、異なる出力を生成します。
  • k = f(2)、したがってyを修正すると、入力がkに等しい定数多項式のときにy * f(y)の最小値が達成され、入力が基底を与える多項式のときに最大値が達成されます。 -2のkの展開。最初のケースではy * f(y)= 2 ^(k!)* kで、2番目のケースではy * f(y)<2 ^(k!* ceil(lg k))です。 2 ^((k + 1)!)*(k + 1)より
  • その結果、f(2)<g(2)の2つの多項式fとgの場合、fから得られる整数は、gから得られる整数より小さくなります。

5

Wolfram言語(Mathematica)、61バイト

Tr[2^((2#2-1)2^#)&@@@Position[Reverse/@#~IntegerDigits~2,1]]&

オンラインでお試しください!

2つの正の整数を単一の正の整数にマッピングできます。ましょうa, b2つの正の整数です。次にa, b -> (2a - 1) 2^(b-1)、NxNからNへの全単射です。

この関数は、1入力内のすべてのビットの位置(1の位置から)を検出し、上記のマップの単射のみのバリアントを各位置に適用します。次に、結果の各数値が2の累乗に引き上げられ、すべての数値が加算されます(注入NxN-> Nマップを適用したので大丈夫です)。

例えば:

{1, 2, 3}
{{1}, {1, 0}, {1, 1}}             (* Convert to binary *)
{{1}, {0, 1}, {1, 1}}             (* Reverse each *)
{{1, 1}, {2, 2}, {3, 1}, {3, 2}}  (* Position of 1s *)
{2, 12, 8, 24}                    (* Inject to N *)
{4, 4096, 256, 16777216}          (* Raise to the power of 2 *)
16781572                          (* Add *)

逆関数(124バイト)

##+#&~Fold~#&@*Reverse/@Normal@SparseArray[{Log2[j=#~BitAnd~-#],(#/j+1)/2}->1&@@@(Reverse[#~IntegerDigits~2]~Position~1-1)]&

以下は、単射性をテストするための逆関数です。

オンラインでお試しください!


5

パイソン2118の 117 114 103 100バイト

Jonathan Frechによる100バイト:

a=input()
while a[0]<1:a.pop(0)
y="".join("2"+bin(v)[2:]for v in a)
print~-2**y.count("1")<<int(y,3)

オンラインでお試しください!

ゴルフの可能性を持つ103バイト1

a=input()
while a[0]<1:a.pop(0)
x="".join(map(bin,a))
print~-(1<<x.count("1"))<<int(x.replace(*"b2"),3)

オンラインでお試しください!

ジョナサンフレッシュのおかげで-15バイト

最初に「オンビット」を含む数値を作成し、次に3進数として解釈される配列の単項表現を作成します。

3進数は、数値を2進文字列(0bNNN)に変換してからに置き換えbて作成され2ます。

1代わりに12進数に変換することで14バイトを節約できましたが、TIOがメモリを使い果たしたため、これを使用することにしました。


@JonathanFrechありがとうございました:)
fergusq

1

05AB1E、14バイト

gÅpImPoIbS{2β*

オンラインでお試しください!

DennisのJellyソリューションと同じ結果が得られますが、テクニックは少し異なります。

どうやって?

入力を試してみましょう [1, 2, 3]

gÅpImPoIbS{2β* | Full program.
               | STACK: [[1, 2, 3]]
               |
g              | Push the length.
               | STACK: [3]
 Åp            | Generate the first N primes.
               | STACK: [[2, 3, 5]]
   Im          | Push the input, and apply pairwise exponentiation.
               | STACK: [2, 9, 125]
     P         | Push the product.
               | STACK: 2250
      o        | Push 2 ** N.
               | STACK: 2 ** 2250 (way too large)
       Ib      | Push the input and convert to binary.
               | STACK: [2 ** 2250, ['1', '10', '11']].
         S{    | Sort all the characters.
               | STACK: [2 ** 2250, ['0', '1', '1', '1', '1']]
           2β  | Convert from binary.
               | STACK: [2 ** 2250, 15]
             * | Multiplication.
               | STACK: [2 ** 2250 * 15]
               | Implicitly print the top of the stack (2 ** 2250 * 15).


0

JavaScriptの6、96の 83バイト

x=>(t=x.map(k=>(x[0]+=k)&&2+k.toString(2)).join``).replace(/0|2/g,'')+'0'.repeat(t)

バイナリ式を出力します

([1,2]) => 3*2^21210(Decimal)
([0,1,2]) => 3*2^21210
([1,2,0]) => 3*2^2121020
([1,2,3,4]) => 31*2^212102112100(Threotically)

ゼロはゼロを表す空の文字列につながる
l4m2

replace(/0|2/g,0)デコードに難しい仕事もそうですが、
l4m2

わからないx=>(t=x.map(k=>(x[0]+=k)&&2+k.toString(2)).join``).replace(/2/g,'0'.repeat(t))。大丈夫感じるが、証明できない
l4m2
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.