Rancang fungsi injeksi komutatif antara pasangan tak terbatas (terbatas) dan pasangan tak berurutannya

18

Terkait, tetapi ini hanya membutuhkan bilangan bulat positif dan tidak harus komutatif

Fungsi Penyandingan Cantor dijelaskan dalam artikel Wikipedia ini . Pada dasarnya, ini adalah operasi sehingga ketika diterapkan pada dua nilai X dan Y, seseorang dapat memperoleh nilai asli X dan Y yang memberikan hasilnya.

Tugas Anda adalah merancang dua fungsi: satu yang berkinerja X, Y -> Zdan yang lain berkinerja Z -> X, Y. Inilah tujuannya: X, Y -> Zharus komutatif. Ini berarti bahwa Z -> X, Ytidak akan dapat menentukan apakah input itu X, Yatau Y, X.

Definisi formal dari tantangan ini adalah:

Pilih satu set S angka yang tak terhingga jumlahnya.
Desain dua fungsi yang melakukan tugas-tugas berikut:

  • Dengan pasangan nilai yang tidak teratur dalam S, kembalikan nilai dalam S
  • Diberi nilai pengembalian dari fungsi awal, kembalikan pasangan nilai yang tidak berurutan yang mengevaluasi ke integer input ketika melewati fungsi pertama. Saya tidak peduli tentang perilaku fungsi terbalik ini jika input bukan nilai balik dari fungsi pertama.

Persyaratan

  • Hasilnya harus identik antara berjalan.
  • {a, a} adalah pasangan yang tidak teratur

Catatan: jawaban Anda lebih mungkin untuk mendapatkan upvote dari saya jika Anda memberikan bukti, tetapi saya akan menguji jawaban ketika saya sampai dan menaikannya setelah saya cukup yakin itu berhasil.

HyperNeutrino
sumber
Bukankah ini lebih cocok untuk puzzling.stackexchange.com ?
Jakube
2
@ Jakube Tidak harus, karena Anda diharuskan untuk menulis kode.
Tn. Xcoder
Saya berasumsi pasangan unik, tetapi angka yang digunakan dalam pasangan itu tidak? Jadi kapan 1,2salah satu pasangan, 1,3juga bisa menjadi pasangan potensial (keduanya digunakan 1)?
Kevin Cruijssen
@KevinCruijssen Saya tidak yakin apa yang Anda maksud
HyperNeutrino
@ Giuseppe Pembalik tidak perlu dapat mengembalikan urutan yang benar; hanya saja untuk fungsi fdan kebalikannya g, sorted((x, y))harus sama dengansorted(g(f(x, y)))
HyperNeutrino

Jawaban:

13

Haskell , 65 + 30 = 95 byte

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

Cobalah online!

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

Cobalah online!


Catatan: Ketika dua fungsi dapat berbagi kode, ini hanya 75 byte:

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

Cobalah online! Domain adalah bilangan bulat positif. Fungsi (#)melakukan pemasangan, fungsi (l!!)terbalik. Contoh penggunaan: Keduanya (#) 5 3dan (#) 3 5hasil 12, dan (l!!) 12hasil (5,3).

Ini berfungsi dengan mencantumkan secara eksplisit semua pasangan yang disortir dalam daftar tak terbatas 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), ...`

Pengodean kemudian hanya indeks dalam daftar ini.

Laikoni
sumber
oleh OP, kode bersama harus dihitung dua kali
bangga haskeller
5

Pyth , 8 + 6 = 14 byte

ij\aSQ16

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

Cobalah online!

c.HQ\a

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

Cobalah online!
Domain: Bilangan bulat positif.

tongkat
sumber
pendekatan yang bagus! +1
HyperNeutrino
4
Tidak berfungsi untuk banyak angka seperti 2dan 10misalnya (yang ada di domain)
Emigna
Tentu. Example1 , Example2
Emigna
Fungsi ke-2 seharusnya berfungsi untuk nilai apa pun dalam S, bukan hanya yang dihasilkan dengan fungsi pertama (saya membuat kesalahan yang sama).
Arnauld
4

Jelly , 8 + 11 = 19 byte

Digulung mundur karena algoritma Rod tidak berfungsi.

Ini berfungsi pada domain bilangan bulat positif.

Membawa xdan ysebagai 2 argumen, tidak masalah di urutan mana, kembali z.

»’RSð+ð«

Cobalah online!

Mengambil zdan mengembalikan[min(x, y), max(x, y)]

R€Ẏ,Rx`$ị@€

Cobalah online!

Erik the Outgolfer
sumber
1
Mengapa downvotes? Ini bukan algoritma Rod.
Erik the Outgolfer
4

JavaScript (ES7), 44 byte

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

Peta dari bilangan bulat non-negatif ke subset daripadanya.

Neil
sumber
4

C (gcc) , 36 + 39 = 75 byte

Terima kasih kepada @tsh karena telah menyimpan dua byte.

Domain adalah bilangan bulat non-negatif.

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

Dibutuhkan x dan y, mengembalikan z.

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

Membawa dua elemen int array . Elemen kedua harus diatur zsebelum panggilan. Setelah panggilan rberisi xdan y.

Cobalah online!

nwellnhof
sumber
(x+1)->-~x
tsh
3

Jeli , 13 11 byte

sepasang bilangan bulat positif ke bilangan bulat positif, 5 byte

Ṁc2+Ṃ

Cobalah online!

bilangan bulat positif untuk memasangkan bilangan bulat positif, 6 byte

ŒċṀÞị@

Cobalah online!

Algoritma

Jika kita mengurutkan set semua pasangan bilangan bulat positif tidak berurut dengan jumlah maksimum dan jumlah mereka, kita mendapatkan urutan berikut.

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

Fungsi pertama mengambil pasangan {x, y} dan menemukan indeksnya dalam urutan ini.

Fungsi kedua mengambil bilangan bulat positif z dan mengembalikan item ke- z dari urutan.

Perhatikan bahwa pemetaan ini sama dengan jawaban Jelly @ EriktheOutgolfer .

Bagaimana itu bekerja

Ṁ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).
Dennis
sumber
2
Mohon penjelasannya. Saya tidak yakin ini valid ...
Erik the Outgolfer
Saya telah menambahkan algoritme.
Dennis
Sesuatu tidak menempel dengan baik kepada saya ... meskipun saya tidak yakin apakah ini juga tidak valid. Pada dasarnya itu tidak cocok dengan yang Anda gunakan keduanya cdan Œċ... meskipun saya mungkin salah. Btw itu jawaban saya bahwa Anda mengungguli> _>
Erik the Outgolfer
Perbedaannya minimal untuk pasangan. Jika C menghitung kombinasi tanpa penggantian dan Ƈ menghitung kombinasi dengan, nƇ2 = nC2 + n .
Dennis
2

Mathematica (35 + 53) = 78 Bytes

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

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

Ini adalah salah satu fungsi pairing kuadratik yang diketahui untuk Z <--> ZxZ yang dikombinasikan dengan Min dan Max untuk membuatnya tidak teratur.

Kelly Lowder
sumber
2

Ruby, 66 byte

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

Saya mencoba menemukan cara untuk secara cerdik memilih satu set infinite untuk mempermudah ini, ini adalah yang terbaik yang saya dapatkan sejauh ini.

Kami mendefinisikan f (x, y) = 2 x-1 bitwise-atau 2 y-1 . Domain terdiri dari himpunan yang didefinisikan secara rekursif sebagai berisi 1,2, dan semua angka yang dapat dihasilkan dengan memanggil f pada angka-angka dalam himpunan (perhatikan bahwa f (1,1) = 1 dan f (2,2) = 2, jadi 1 dan 2 memiliki invers). Angka-angka yang dihasilkan semuanya memiliki satu atau dua 1s dalam ekspansi biner mereka, dengan indeks 1s yang sesuai dengan angka dalam set. Kita bisa mengeluarkan pasangan yang tidak terurut asli dengan mengambil indeks. Jika hanya ada satu 1, itu berarti elemen pasangan sama.

Sebagai contoh, f (3,5) adalah 20, karena 20 adalah 10100 di basis 2, yang memiliki 1 di tempat ke-3 dan ke-5 paling signifikan.

histokrat
sumber
S = set ini (tautan OEIS)
Giuseppe
Terima kasih, S sebenarnya adalah bagian dari urutan OEIS itu karena itu hanya mencakup angka-angka yang 1-nya memiliki indeks dalam S.
histokrat
ah ya tentu saja. Ya, tidak ada urutan lain yang cocok dengan beberapa istilah pertama (hingga 32).
Giuseppe
Tambahkan 0 ke S dan Anda dapat menyimpan beberapa pengurangan.
nwellnhof
2

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

Fungsi berpasangan

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

Cobalah online!

Fungsi depair

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

Cobalah online!

Roberto Graham
sumber
1
Anda dapat bermain golf beberapa bagian. Dalam fungsi pasangan: int i=(""+a[0]).length()bisa int i=(f+a[0]).length(); ruang antara c=0,j;i>0;bisa dihilangkan; a[0].parseIntbisa new Integer. Dalam fungsi depair: ketiganya r.parseIntbisa r.decode; dan Anda bisa membuat variabel int untuk t.length(), karena Anda menggunakannya dua kali.
Kevin Cruijssen
1

05AB1E , 6 + 11 = 17 byte

Port jawaban Jelly-ku.

Domain: bilangan bulat positif.

Mengambil daftar [x, y]sebagai input, mengembalikan z.

{`<LO+

Cobalah online!

Mengambil bilangan bulat positif zsebagai input, mengembalikan [min(x, y), max(x, y)].

L2ã€{RÙR¹<è

Cobalah online!

-5 Terima kasih kepada Emigna .

Erik the Outgolfer
sumber
Program kedua Anda dapat menghemat 5 byte dengan L2ã € {RÙRI <è
Emigna
@Emigna Trik yang bagus dengan 2ã€{RÙR!
Erik the Outgolfer
1

JavaScript, 72 byte

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

Berfungsi untuk bilangan bulat positif (dalam teori). Gagasan yang cukup sederhana: urutkan dua angka dalam beberapa urutan (ajaib), hubungkan sebagai string dengan huruf "a", parsing sebagai hex integer.

tsh
sumber
1

MATL, 6 + 8 = 14 byte

Fungsi encoding, membutuhkan dua input n, m. Output produk dari nth prime dan mth prime.

,iYq]*

Langkah:

  • , - Lakukan dua kali
  • i - Masukan push
  • Yq - Input pop, tekan input'th prima
  • ]* - Akhiri lakukan dua kali, pop prima dan dorong produk

Fungsi decoding, membutuhkan satu input m. Menghasilkan jumlah bilangan prima di bawah masing-masing faktor utama n.

iYf"@Zqn

Langkah:

  • i - Masukan push
  • Yf - Input pop, push array faktor prima
  • " - Untuk n dalam array
  • @Zq - Dorong array bilangan prima di bawah ini n
  • n - Pop array, dorong panjang array

Ini komutatif karena perkalian adalah komutatif, dan injeksi karena faktorisasi prima yang unik. Bukan berarti ini bukan ke bilangan bulat.

Dave
sumber
0

Sekam , 5 + 3 = 8 byte

Saya benar-benar berharap saya mendapat tantangan dengan benar, saya melihat beberapa jawaban yang dihapus yang tampaknya valid untuk saya ...

Pasangan bilangan bulat positif ke bilangan bulat positif tunggal:

¤*!İp

Cobalah online!

Ini bekerja dengan mengambil angka pada indeks yang diberikan (1-diindeks) dari daftar bilangan prima, dan mengalikannya.

Hasil dari fungsi pertama untuk pasangan bilangan bulat positif:

mṗp

Cobalah online!

Kami memfaktisasi jumlah input dan mengembalikan indeks dalam daftar bilangan prima dari semua (kedua) faktornya.

Contoh yang berhasil

Diberikan (4,1)sebagai pasangan pemula, kami mengambil bilangan prima keempat dan pertama (7,2)dan mengalikannya → 14. Penggandaan inilah yang membuat fungsi tidak tergantung pada urutan dua elemen.

Mulai dari 14, kami memfaktorkannya (2,7)dan mengembalikan indeks 2dan 7dalam daftar bilangan prima → (1,4).

Leo
sumber
Sebenarnya, melihat jawaban yang dihapus dari Arnauld, algoritmenya bahkan lebih baik, dan memindahkannya ke Husk akan menghasilkan 6 byte ... Bisakah seseorang mengonfirmasi apakah solusinya (dan juga milik saya) valid atau tidak?
Leo
Tidak berfungsi untuk bilangan prima (yang berada dalam domain bilangan bulat positif)
Emigna
@Emigna fungsi kedua tidak, tetapi bilangan prima tidak pernah dikembalikan oleh yang pertama ...
Leo
Domain Anda adalah bilangan bulat positif, sehingga kedua metode harus berfungsi untuk bilangan bulat positif. EDIT: atau setidaknya yang dulu menjadi persyaratan. Aturan saat ini tampaknya memungkinkan subset domain.
Emigna
0

C # , 80 byte (38 + 42)


Data

Encoder

  • Masukkan Int32 l nomor A
  • Masukkan Int32 r nomor A
  • Keluaran Int64 Kedua int menyatu bersama

Dekoder

  • Masukkan Int32 v nilai
  • Keluaran Int32[] Array dengan dua int asli.

Golf

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

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

Tidak disatukan

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

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

Tidak terbaca dibaca

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

Kode lengkap

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

Rilis

  • v1.0 - 80 bytes- Solusi awal.

Catatan

  • Tidak ada
auhmaan
sumber
0

Python: 41 + 45 = 86

encoder: 41

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

(11110111, 11110111)

decoder: 45

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

[4, 3]

Upaya yang lebih lama:

Python: 114: 30 + 84

encoder: 30

menerima 2 bilangan bulat, mengembalikan string

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

(432, 432)

decoder: 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

decoder2: 120

upaya lain dengan pemahaman dan penjumlahan generator

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
Maarten Fabré
sumber
1
berdasarkan upaya kedua: e=lambda*x:10**sum(x)-10**min(x);d=lambda z:map(z .count,'09');TIO
tsh
@ tsh sangat bagus. Saya akan menyesuaikannya nanti, atau Anda dapat mengirimkan jawaban Anda sendiri
Maarten Fabré