任意の(制限された)無限集合とその順序付けられていないペアの間の可換単射関数を設計する


18

関連するが、これは正の整数のみを必要とし、可換である必要はない

Cantorペアリング関数は、このウィキペディアの記事で説明されています。基本的に、2つの値XとYに適用されると、結果が与えられて元の値XとYを取得できるような操作です。

あなたの仕事は、実行する機能と実行する機能の2つの機能を設計X, Y -> ZすることZ -> X, Yです。キャッチは次のとおりX, Y -> Zです。可換でなければなりません。これはZ -> X, Y、入力がX, Yまたはであったかどうかを判断できないことを意味しますY, X

この課題の正式な定義は次のとおりです。

カウント可能な数の無限集合Sを選択します。
次のタスクを実行する2つの関数を設計します。

  • Sの値の順序付けられていないペアを指定すると、Sの値を返します
  • 初期関数からの戻り値を指定すると、最初の関数を通過したときに入力整数に評価される値の順序付けられていないペアを返します。入力が最初の関数からの戻り値でない場合、この逆関数の動作は気にしません。

必要条件

  • 結果は実行間で同一である必要があります。
  • {a, a} 順不同のペアです

注:証拠を提供すると、あなたの答えは私から賛成票を受け取る可能性が高くなりますが、答えが得られたらテストし、それがうまくいくと確信したら票決します。


これはpuzzling.stackexchange.comにより適していますか?
ジャクベ

2
@Jakube必ずしもコードを書く必要があるため、そうではありません。
ミスターXcoder

ペアは一意であると仮定していますが、それらのペアで使用される数字は一意ではありませんか?では1,2、ペアの1 1,3つがいつペアになる可能性もあります(両方ともを使用1)。
ケビンCruijssen

@KevinCruijssen私はあなたが何を意味するかわからない
HyperNeutrino

@Giuseppe逆数は正しい順序を返す必要はありません。それは、機能のためだけのことだfとその逆gsorted((x, y))と同じでなければなりませんsorted(g(f(x, y)))
HyperNeutrino

回答:


13

Haskell、65 + 30 = 95バイト

a#b=length.fst$span(<(max a b,min a b))[(a,b)|a<-[1..],b<-[1..a]]

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

([(a,b)|a<-[1..],b<-[1..a]]!!)

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


注: 2つの関数がコードを共有する場合、これは75バイトのみです。

(l!!)
a#b=length.fst$span(<(max a b,min a b))l
l=[(a,b)|a<-[1..],b<-[1..a]]

オンラインでお試しください!ドメインは正の整数です。関数(#)はペアリングを実行し、関数は(l!!)その逆を実行します。使用例:(#) 5 3(#) 3 5yield 12、および(l!!) 12yieldsの両方(5,3)

これは、ソートされたすべてのペアを無限リストに明示的にリストすることにより機能しますl

l = [(1,1),(2,1),(2,2),(3,1),(3,2),(3,3),(4,1),(4,2),(4,3),(4,4),(5,1),(5,2),(5,3),(5,4),(5,5),(6,1), ...`

エンコードは、このリストの単なるインデックスになります。


OPにより、共有コードは2回カウントされる必要があります
誇り高いhaskeller

5

Pyth、8 + 6 = 14バイト

ij\aSQ16

    SQ   # Sort the input
 j\a     # join with "a"
i     16 # convert from base 16 to base 10

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

c.HQ\a

 .HQ     # convert from base 10 to 16
c   \a   # split on "a"

オンラインでお試しください!
ドメイン:正の整数。


素敵なアプローチ!+1
HyperNeutrino

4
以下のような数字の多くのために動作しません2し、10(ドメイン内にある)例えば
Emigna

承知しました。例1例2
Emigna

2番目の関数は、最初の関数で生成された値だけでなく、Sのすべての値に対して機能するはずです(同じ間違いをしました)。
アーナルド

4

ゼリー、8 + 11 = 19バイト

Rodのアルゴリズムが機能しなかったため、ロールバックされました。

これは、正の整数のドメインで機能します。

xyを2つの引数として受け取り、どちらの順序でもかまいませんz

»’RSð+ð«

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

受け取りzとリターン[min(x, y), max(x, y)]

R€Ẏ,Rx`$ị@€

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


1
なぜダウン投票なのですか?これはRodのアルゴリズムではありません。
エリックアウトゴルファー

4

JavaScript(ES7)、44バイト

(x,y)=>x>y?x*x+y:y*y+x
z=>[x=z**.5|0,y=z-x*x]

非負の整数からそのサブセットにマップします。


4

C(gcc)、36 + 39 = 75バイト

2バイトを保存してくれた@tshに感謝します。

ドメインは非負の整数です。

p(x,y){return y>x?p(y,x):-~x*x/2+y;}

を取りxyを返しますz

u(int*r){for(*r=0;r[1]>*r;r[1]-=++*r);}

2要素のint配列を受け取ります。2番目の要素はz、呼び出しの前に設定する必要があります。コールの後rが含まxy

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


(x+1)->-~x
tsh

3

ゼリー13 11バイト

正の整数と正の整数のペア、5バイト

Ṁc2+Ṃ

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

正の整数から正の整数のペア、6バイト

ŒċṀÞị@

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

アルゴリズム

正の整数のすべての順序付けられていないペアのセットを最大値で並べ替えてから合計で並べ替えると、次のシーケンスが得られます。

{1,1}、{1,2}、{2,2}、{1,3}、{2,3}、{3,3}、{1,4}、{2,4}、{3 、4}、{4,4}、{1,5}、{2,5}、{3,5}、{4,5}、{5,5}、…

最初の関数はペア{x、y}を受け取り、このシーケンスでインデックスを見つけます。

2番目の関数は正の整数zを取り、シーケンスのz 番目のアイテムを返します。

このマッピングは@EriktheOutgolferのJelly answerと同じであることに注意してください。

使い方

Ṁc2+Ṃ   Main link. Argument: [x, y]
        Let m = max(x, y) and n = min(x, y).

Ṁ       Maximum; yield m.
 c2     2-combinations; yield mC2 = m(m-1)/2.
        Note that there's one pair with maximum 1 ({1,1}), two pairs with maximum 2
        ({1,2}, {2,2}), etc., so there are 1 + 2 + … + (m-1) = m(m-1)/2 pairs with
        maximum less than m.
    Ṃ   Minimum; yield n.
        Note that {x,y} is the n-th pair with maximum m.
   +    Add; yield mC2 + n.
        This finds {x,y}'s index in the sequence.
ŒċṀÞị@  Main link. Argument: z

Œċ      2-combinations w/replacement; yield all pairs [x, y] such that x ≤ y ≤ z.
  ṀÞ    Sort by maximum.
    ị@  Retrieve the pair at index z (1-based).

2
説明してください。これが有効であるとは確信していません...
エリックアウトゴルファー

アルゴリズムを追加しました。
デニス

何かが私にしっかりとはまりません...これも無効かどうかはわかりませんが。基本的には一種のあなたが両方を使用することも固執しないcŒċ、私は間違っているかもしれないが...。ところで、それはあなたがゴルフをしなかったという私の答えでした> _>
エリックアウトゴルファー

ペアの違いは最小限です。場合Cは、交換することなくそれらの組み合わせを計算しƇは、との組み合わせを計算nƇ2= NC2 + N
デニス

2

Mathematica(35 + 53)= 78バイト

((x=Min[#])+(y=Max[#]))(x+y+1)/2+y&

(i=Floor[(-1+Sqrt[1+8#])/2];{#-i(1+i)/2,i(3+i)/2-#})&

これは、Z <-> ZxZを最小および最大と組み合わせて無秩序にするための、よく知られた2次ペアリング関数です。


2

ルビー、66バイト

f=->x,y{2**~-x|2**~-y}
g=->n{x,y=(1..n).select{|i|n[i-1]>0};[x,y||x]}

私はこれを簡単にするために無限のセットを巧妙に選択する方法を見つけようとしていますが、これはこれまでで最高です。

f(x、y)= 2 x-1 bitwise-or 2 y-1を定義します。ドメインは、1,2を含むものとして再帰的に定義されたセットと、セット内の番号に対してfを呼び出すことによって生成できるすべての番号で構成されます(f(1,1)= 1およびf(2,2)= 2に注意してください)そのため、1と2には逆があります)。結果の数値はすべて、バイナリ展開で1または2の1を持ち、1のインデックスはセットの数値に対応します。インデックスを取得することで、元の順序付けられていないペアを取得できます。1が1つしかない場合、ペアの要素が等しいことを意味します。

たとえば、f(3,5)は20です。これは、20が基数2で10100であり、3番目と5番目の最下位に1があるためです。



それだけで、その1秒S.内のインデックスを持っている番号含まれているため、おかげで、Sはかかわらず、実際にそのOEISの配列のサブセットである
histocrat

ああ、もちろん。さて、他のシーケンスは最初のいくつかの用語(最大32)に一致しません。
ジュゼッペ

Sに0を追加すると、いくつかのデクリメントを保存できます。
nwellnhof

2

ジャワ8、153 146 141 137 + 268 224 216 205バイト

ペア機能

a->{String f="";for(int i=(f+a[0]).length(),c=0,j;i>0;i-=c,f+=c,c=0)for(j=1;j<10;c+=i-j++<0?0:1);return new Integer(a[0]+""+a[1]+"0"+f);}

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

デペア機能

r->{String a=r+"",t=a.substring(a.lastIndexOf('0')+1);int l=0,i=l,o=t.length();for(;i<o;l+=r.decode(t.charAt(i++)+""));return new int[]{r.decode(a.substring(0,l)),r.decode(a.substring(l,a.length()-o-1))};}

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


1
いくつかのパーツをゴルフできます。ペア関数では、次のint i=(""+a[0]).length()ようになりint i=(f+a[0]).length()ます。間のスペースはc=0,j;i>0;削除できます。a[0].parseIntすることができますnew Integer。depair関数では、3つすべてr.parseIntが可能r.decodeです。またt.length()、2回使用するため、のint変数を作成できます。
ケビンCruijssen

1

05AB1E、6 + 11 = 17バイト

私のゼリーのポートの答え。

ドメイン:正の整数。

リスト[x, y]を入力として受け取り、を返しますz

{`<LO+

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

z入力として正の整数を取り、を返します[min(x, y), max(x, y)]

L2ã€{RÙR¹<è

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

-5 エミニャに感謝します


2番目のプログラムでは、L2で
E

@Emigna素敵なトリック2ã€{RÙR
エリックアウトゴルファー

1

JavaScript、72バイト

f=a=>eval('0x'+a.sort().join`a`)
g=n=>n.toString(16).split`a`.map(x=>+x)

(理論上)正の整数で機能します。非常に単純なアイデア:2つの数を(魔法の)順序で並べ替え、文字"a"で文字列として接続し、16進整数として解析します。


1

MATL、6 + 8 = 14バイト

エンコード機能。2つの入力n、mを取ります。n番目の素数とm番目の素数の積を出力します。

,iYq]*

手順:

  • , -2回行う
  • i -プッシュ入力
  • Yq -入力をポップ、入力のプライムをプッシュ
  • ]* -終了2回、両方の素数をポップし、製品をプッシュ

デコード関数、1つの入力mを受け取ります。nの各素因数より下の素数を出力します。

iYf"@Zqn

手順:

  • i -プッシュ入力
  • Yf -入力をポップし、素因数の配列をプッシュする
  • " -配列のnの場合
  • @Zq -n以下の素数の配列をプッシュする
  • n -ポップ配列、配列の長さをプッシュ

乗算は可換であるためこれは可換であり、素因数分解は一意であるため単射です。これは整数上ではないということではありません。


0

、5 + 3 = 8バイト

私は本当に挑戦が正しかったことを願っています、私にとって有効なように見えるいくつかの削除された答えが表示されます...

正の整数の単一の正の整数への結合:

¤*!İp

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

これは、素数のリストから指定されたインデックス(1からインデックス付き)の数を取得し、それらを乗算することで機能します。

正の整数のカップルに対する最初の関数の結果:

mṗp

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

入力数を因数分解し、その要素のすべて(両方)の素数のリストにインデックスを返します。

実施例

与えられた(4,1)開始夫婦として、我々は、第四と第一の素数を取り(7,2)、それらを掛けます→14。この乗算は、2つの要素の順序で関数を独立させるものです。

始めて14、我々はそれを因数分解(2,7)してのインデックスを返す2と、7素数のリストの中を→ (1,4)


実際、Arnauldから削除された回答を見ると、そのアルゴリズムはさらに優れており、Huskに移植すると6バイトになります。
レオ

素数(正の整数の領域にある)では機能しません
エミナ

第二の機能はしませんが、素数は...最初のもので返されることはありません@Emigna
レオ

ドメインは正の整数であるため、両方のメソッドが正の整数で機能する必要があります。編集:または少なくともそれが要件であったもの。現在のルールでは、ドメインのサブセットが許可されているようです。
エミグナ

0

C#、80バイト(38 + 42)


データ

エンコーダー

  • 入力 Int32 l番号
  • 入力 Int32 r番号
  • Int64両方の整数が融合された出力

デコーダ

  • 入力 Int32 v
  • 出力 Int32[] 2つの元のintを持つ配列。

ゴルフ

// Encoder
e=(l,r)=>{return(long)l<<32|(uint)r;};

// Decoder
d=v=>{return new[]{v>>32,v&0xFFFFFFFFL};};

非ゴルフ

// Encoder
e = ( l, r ) => {
    return (long) l << 32 | (uint) r;
};

// Decoder
d = v => {
    return new[] {
        v >> 32,
        v & 0xFFFFFFFFL };
};

読みやすい

// Encoder
// Takes a pair of ints
e = ( l, r ) => {

    // Returns the ints fused together in a long where the first 32 bits are the first int
    // and the last 32 bits the second int
    return (long) l << 32 | (uint) r;
};

// Decoder
// Takes a long
d = v => {

    // Returns an array with the ints decoded where...
    return new[] {

        // ... the first 32 bits are the first int...
        v >> 32,

        // ... and the last 32 bits the second int
        v & 0xFFFFFFFFL };
};

完全なコード

using System;
using System.Collections.Generic;

namespace TestBench {
    public class Program {
        // Methods
        static void Main( string[] args ) {
            Func<Int32, Int32, Int64> e = ( l, r ) => {
                return(long) l << 32 | (uint) r;
            };
            Func<Int64, Int64[]> d = v => {
                return new[] { v >> 32, v & 0xFFFFFFFFL };
            };

            List<KeyValuePair<Int32, Int32>>
                testCases = new List<KeyValuePair<Int32, Int32>>() {
                    new KeyValuePair<Int32, Int32>( 13, 897 ),
                    new KeyValuePair<Int32, Int32>( 54234, 0 ),
                    new KeyValuePair<Int32, Int32>( 0, 0 ),
                    new KeyValuePair<Int32, Int32>( 1, 1 ),
                    new KeyValuePair<Int32, Int32>( 615234, 1223343 ),
                };

            foreach( KeyValuePair<Int32, Int32> testCase in testCases ) {
                Console.WriteLine( $" ENCODER: {testCase.Key}, {testCase.Value} = {e( testCase.Key, testCase.Value )}" );
                Console.Write( $"DECODING: {e( testCase.Key, testCase.Value )} = " );
                PrintArray( d( e( testCase.Key, testCase.Value ) ) );

                Console.WriteLine();
            }

            Console.ReadLine();
        }

        public static void PrintArray<TSource>( TSource[] array ) {
            PrintArray( array, o => o.ToString() );
        }
        public static void PrintArray<TSource>( TSource[] array, Func<TSource, String> valueFetcher ) {
            List<String>
                output = new List<String>();

            for( Int32 index = 0; index < array.Length; index++ ) {
                output.Add( valueFetcher( array[ index ] ) );
            }

            Console.WriteLine( $"[ {String.Join( ", ", output )} ]" );
        }
    }
}

リリース

  • v1.0の - 80 bytes-初期ソリューション。

ノート

  • なし

0

Python:41 + 45 = 86

エンコーダー:41

e=lambda*x:int('1'*max(x)+'0'+'1'*min(x))
e(4, 3), e(3,4)

(11110111、11110111)

デコーダー:45

d=lambda z:[len(i)for i in str(z).split('0')]
d(11110111)

[4、3]

古い試み:

Python:114:30 + 84

エンコーダー:30

2つの整数を受け入れ、文字列を返します

e=lambda*x:2**max(x)*3**min(x)
e(3, 4), e(4, 3)

(432、432)

デコーダー:86

def d(z):
 x=y=0
 while 1-z%2:
  x+=1
  z/=2
 while 1-z%3:
  y+=1
  z/=3
 return x,y
d(432)

4、3

デコーダー2:120

ジェネレーターの理解と合計の別の試み

def d(z):
 x=sum(1 for i in range(z)if not z%(2**i))-1
 z/=2**x
 return x,sum(1 for i in range(int(z))if not z%(3**i))-1

1
2回目の試行に基づく:e=lambda*x:10**sum(x)-10**min(x);d=lambda z:map(z .count,'09'); TIO
tsh

@tshとてもいい。後で適応するか、独自の回答を提出することができます
マールテンファブレ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.