Herhangi bir (kısıtlı) sonsuz küme ve bunların sırasız çiftleri arasında değişmeli bir injektif fonksiyon tasarlayın


18

İlgili, ancak bu yalnızca pozitif tamsayılar gerektirir ve değişmeli olmak zorunda değildir

Cantor Eşleştirme İşlevi bu Wikipedia makalesinde açıklanmaktadır . Esasen, iki X ve Y değerine uygulandığında, sonuç verilen X ve Y orijinal değerlerini elde edebilecek bir işlemdir.

Göreviniz iki işlev tasarlamaktır: biri gerçekleştiren X, Y -> Zve diğeri gerçekleştiren Z -> X, Y. İşte yakalama: X, Y -> Zdeğişmeli olmalı. Bu araçlar Z -> X, Y, giriş olup olmadığını belirlemek için mümkün olmayacaktır X, Yya Y, X.

Bu zorluğun resmi tanımı:

Sayılabilir sonsuz bir sayı kümesi S seçin.
Aşağıdaki görevleri gerçekleştiren iki işlev tasarlayın:

  • S'de sırasız bir değer çifti verildiğinde, S cinsinden bir değer döndürün
  • İlk işlevden bir dönüş değeri verildiğinde, ilk işlevden geçirildiğinde giriş tamsayı olarak değerlendirilen sırasız değer çiftini döndürün. Giriş ilk işlevden bir dönüş değeri değilse, bu ters işlev davranışını umurumda değil.

Gereksinimler

  • Sonuç, çalışmalar arasında aynı olmalıdır.
  • {a, a} sırasız bir çift

Not: Bir kanıt sağlarsanız cevabınızın benden bir upvote alma olasılığı daha yüksektir, ancak yanıt aldığımda cevapları test edeceğim ve oldukça işe yaradığından emin olduktan sonra cevaplayacağım.


Değil bu uyum daha iyi yapar puzzling.stackexchange.com ?
Jakube

2
@Jakube Kod yazmanız gerektiği için zorunlu olarak değil.
Bay Xcoder

Çiftlerin benzersiz olduğunu varsayıyorum, ancak bu çiftlerde kullanılan sayılar değil mi? Peki 1,2çiftlerden biri ne zaman , 1,3potansiyel bir çift de olabilir (her ikisi de kullanım 1)?
Kevin Cruijssen

@KevinCruijssen Ne demek istediğinden emin değilim
HyperNeutrino

@Giuseppe Tersin doğru siparişi vermesi gerekmez; o işlev için bu sadece var fve bunun tersi g, sorted((x, y))aynı olmalıdırsorted(g(f(x, y)))
HyperNeutrino

Yanıtlar:


13

Haskell , 65 + 30 = 95 bayt

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

Çevrimiçi deneyin!

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

Çevrimiçi deneyin!


Not: İki işlev kodu paylaşabilirse, bu yalnızca 75 bayttır:

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

Çevrimiçi deneyin! Etki alanı pozitif tamsayılardır. İşlev (#)eşleştirmeyi, işlev (l!!)tersini gerçekleştirir. Kullanım örneği: Her iki (#) 5 3ve (#) 3 5verim 12ve (l!!) 12verimleri (5,3).

Bu, tüm sıralanmış çiftleri sonsuz bir listede açıkça listeleyerek çalışır 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), ...`

Bu durumda kodlama sadece bu listedeki dizindir.


OP tarafından paylaşılan kod iki kez sayılmalıdır
gururlu haskeller

5

Pyth , 8 + 6 = 14 bayt

ij\aSQ16

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

Çevrimiçi deneyin!

c.HQ\a

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

Çevrimiçi deneyin!
Domain: Pozitif tamsayılar.


güzel yaklaşım! +1
HyperNeutrino

4
Gibi sayıların bir sürü için çalışmıyor mu 2ve 10(alandadır) örneğin
Emigna

Elbette. Örnek1 , Örnek2
Emigna

2. fonksiyonun S sadece herhangi bir değer için çalışması gerekiyordu , sadece ilk fonksiyonu ile oluşturulan bir değil (Ben aynı hata yaptım).
Arnauld

4

Jöle , 8 + 11 = 19 bayt

Rod'un algoritması çalışmadığından geri döndü.

Bu, pozitif tamsayıların etki alanı üzerinde çalışır.

Alır xve y2 bağımsız değişken olarak, hangi sırayla, döner de önemli değil z.

»’RSð+ð«

Çevrimiçi deneyin!

Alır zve döner[min(x, y), max(x, y)]

R€Ẏ,Rx`$ị@€

Çevrimiçi deneyin!


1
Neden inişler? Bu Rod'in algoritması değil.
Outgolfer Erik

4

JavaScript (ES7), 44 bayt

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

Negatif olmayan tamsayılardan bir alt kümesine eşler.


4

C (gcc) , 36 + 39 = 75 bayt

İki bayt kaydettiği için @tsh'e teşekkürler.

Etki alanı negatif olmayan tamsayılar.

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

Alır xve ygeri döner z.

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

İki elemanlı bir intdizi alır. İkinci eleman zçağrıdan önce olarak ayarlanmalıdır . Çağrı ardından riçerir xve y.

Çevrimiçi deneyin!


(x+1)->-~x
tsh

3

Jöle , 13 11 bayt

pozitif tamsayı pozitif tamsayıya çifti, 5 bayt

Ṁc2+Ṃ

Çevrimiçi deneyin!

pozitif tamsayı çiftine pozitif tamsayı, 6 bayt

ŒċṀÞị@

Çevrimiçi deneyin!

Algoritma

Tüm düzensiz pozitif tamsayı çiftlerinin kümesini maksimumlarına ve ardından toplamlarına göre sıralarsak, aşağıdaki sırayı alırız.

{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},…

İlk işlev bir çift {x, y} alır ve dizinini bu sırayla bulur.

İkinci fonksiyon pozitif bir tamsayı alır z ve döner z inci dizisinin madde.

Bu eşlemenin @ EriktheOutgolfer'ın Jelly cevabı ile aynı olduğunu unutmayın. .

Nasıl çalışır

Ṁ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
Açıklama lütfen. Bunun geçerli olduğundan emin değilim ...
Outgolfer Erik

Algoritmayı ekledim.
Dennis

Bir şey bana iyi uymuyor ... bunun da geçersiz olup olmadığından emin değilim. Temelde her ikisini de kullandığınız gibi iyi yapışmaz cve Œċ... yanlış olsa da. BTW cevap verdim benim cevap oldu> _>
Outgolfer Erik

Fark çiftler için minimaldir. Eğer Cı- değiştirmeden kombinasyonları hesaplar ve Ƈ , kombinasyonlar hesaplar nƇ2 = nc2 + n .
Dennis

2

Mathematica (35 + 53) = 78 Bayt

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

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

Bu, Z <--> ZxZ için Min ve Max ile birlikte iyi bilinen ikinci dereceden eşleştirme işlevidir.


2

Ruby, 66 bayt

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

Bunu kolaylaştırmak için kurnazca sonsuz bir set seçmek için bir yol bulmaya çalışıyorum, bu şimdiye kadar aldığım en iyisi.

F (x, y) = 2 x-1 bitsel veya 2 y-1 tanımlıyoruz . Etki alanı, özyinelemeli olarak 1,2 içerdiği tanımlanan kümeden ve kümedeki sayılar üzerinde f çağrılarak üretilebilen tüm sayılardan oluşur (f (1,1) = 1 ve f (2,2) = 2, böylece 1 ve 2'nin tersleri vardır). Ortaya çıkan sayıların tümü ikili genişlemelerinde bir veya iki 1'e sahiptir ve 1'lerin endeksleri kümedeki sayılara karşılık gelir. Endeksleri alarak orijinal sırasız çifti çıkarabiliriz. Sadece bir tane 1 varsa, bu çiftin elemanlarının eşit olduğu anlamına gelir.

Örneğin, f (3,5) 20'dir, çünkü taban 2'de 20, 10100'dür ve 3. ve 5. en az önemli yerlerde 1'ler vardır.



Teşekkürler, S aslında OEIS dizisinin bir alt kümesidir, çünkü sadece 1'leri S'de dizinleri olan sayıları içerir
histokrat

ah evet, elbette. İlk birkaç terimle (32'ye kadar) eşleşen başka bir dizi yok.
Giuseppe

S'ye 0 ekleyin ve birkaç azalmayı kaydedebilirsiniz.
nwellnhof

2

Java 8, 153 146 141 137 + 268 224 216 205 bayt

Çift işlevi

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);}

Çevrimiçi deneyin!

Depair işlevi

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))};}

Çevrimiçi deneyin!


1
Birkaç parça golf yapabilirsiniz. Pair fonksiyonunda: int i=(""+a[0]).length()olabilir int i=(f+a[0]).length(); arasındaki boşluk c=0,j;i>0;kaldırılabilir; a[0].parseIntolabilir new Integer. Depair fonksiyonunda: her üçü r.parseIntde olabilir r.decode; t.length()iki kere kullandığınız için int değişkeni yapabilirsiniz .
Kevin Cruijssen


1

JavaScript, 72 bayt

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

Pozitif tamsayılar için çalışır (teoride). Oldukça basit bir fikir: iki sayıyı bazı (sihirli) sırayla sıralayın, bir harfle dize olarak bağlayın "a", onaltılık tamsayı olarak ayrıştırın.


1

MATL, 6 + 8 = 14 bayt

Kodlama fonksiyonu, iki giriş alır n, m. Nci prime ve mth prime ürün çıktıları.

,iYq]*

Adımlar:

  • , - İki kez yapın
  • i - Push girişi
  • Yq - Pop girişi, itme girişi prime
  • ]* - Sonu iki kez yapın, her iki astarı ve itme ürününü açın

Kod çözme işlevi, bir giriş m alır. N'nin ana faktörlerinin her birinin altındaki prim sayısını verir.

iYf"@Zqn

Adımlar:

  • i - Push girişi
  • Yf - Pop input, push array of prime factors
  • " - For n in array
  • @Zq - Push array of primes below n
  • n - Pop array, push length of array

This is commutative because multiplication is commutative, and injective because prime factorizations are unique. Not that this is not onto the integers.


0

Husk, 5+3=8 bytes

I really hope I got the challenge right, I see some deleted answers that seem valid to me...

Couples of positive integers to a single positive integer:

¤*!İp

Try it online!

It works by taking the numbers at the given indices (1-indexed) from the list of prime numbers, and multiplying them.

Result of the first function to couples of positive integers:

mṗp

Try it online!

We factorize the input number and return the index in the list of primes of all (both) of its factors.

Worked example

Given (4,1) as a starting couple, we take the fourth and first prime numbers (7,2) and multiply them → 14. This multiplication is what makes the function indipendent on the order of the two elements.

Starting from 14, we factorize it (2,7) and return the indices of 2 and 7 in the list of prime numbers → (1,4).


Actually, looking at the deleted answer from Arnauld, its algorithm is even better, and porting it to Husk would result in 6 bytes... Could someone confirm whether its solution (and mine too) is valid or not?
Leo

Doesn't work for primes (which are in the domain of positive integers)
Emigna

@Emigna the second function doesn't, but primes are never returned by the first one...
Leo

Alan adınız pozitif tamsayılardır, bu nedenle her iki yöntemin de pozitif tamsayılar için çalışması gerekir. EDIT: veya en azından eskiden bir gereklilikti. Geçerli kurallar alan adının bir alt kümesine izin veriyor gibi görünüyor.
Emigna

0

C # , 80 bayt (38 + 42)


Veri

Encoder

  • Int32 lA numarasını girin
  • Int32 rA numarasını girin
  • Çıktı Int64 Her iki giriş de kaynaşmış

şifre çözücü

  • Girdi Int32 v Değer
  • Çıktı Int32[] İki orijinal girişe sahip bir dizi.

golfed

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

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

Ungolfed

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

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

Okunmamış okunabilir

// 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 };
};

Tam kod

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 )} ]" );
        }
    }
}

Salıverme

  • v1.0 - 80 bytes- İlk çözüm.

notlar

  • Yok

0

Python: 41 + 45 = 86

kodlayıcı: 41

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

(11110111, 11110111)

kod çözücü: 45

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

[4, 3]

Daha eski deneme:

Python: 114: 30 + 84

kodlayıcı: 30

2 tamsayıyı kabul eder, bir dize döndürür

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

(432, 432)

kod çözücü: 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

kod çözücü2: 120

jeneratör kavrayışı ve toplamı ile bir başka girişim

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
ikinci denemeye dayanarak: e=lambda*x:10**sum(x)-10**min(x);d=lambda z:map(z .count,'09'); TIO
tsh

@tsh çok güzel. Daha sonra uyarlayacağım, ya da kendi cevabını gönderebilirsin
Maarten Fabré
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.