Thiết kế một hàm tiêm giao hoán giữa bất kỳ tập hợp vô hạn (bị hạn chế) và các cặp không có thứ tự của chúng


17

Liên quan, nhưng điều này chỉ yêu cầu số nguyên dương và không phải giao hoán

Hàm ghép nối Cantor được mô tả trong bài viết Wikipedia này . Về cơ bản, đây là một hoạt động sao cho khi nó được áp dụng cho hai giá trị X và Y, người ta có thể thu được các giá trị ban đầu X và Y cho kết quả.

Nhiệm vụ của bạn là thiết kế hai chức năng: một chức năng thực hiện X, Y -> Zvà chức năng khác thực hiện Z -> X, Y. Đây là cách bắt: X, Y -> Zphải giao hoán. Điều này có nghĩa là Z -> X, Ysẽ không thể xác định xem đầu vào là X, Yhay Y, X.

Định nghĩa chính thức của thử thách này sẽ là:

Chọn một bộ S số vô hạn có thể đếm được.
Thiết kế hai chức năng thực hiện các nhiệm vụ sau:

  • Cho một cặp giá trị không có thứ tự trong S, trả về một giá trị trong S
  • Đưa ra một giá trị trả về từ hàm ban đầu, trả về cặp giá trị không có thứ tự ước tính cho số nguyên đầu vào khi được truyền qua hàm đầu tiên. Tôi không quan tâm đến hành vi của hàm nghịch đảo này nếu đầu vào không phải là giá trị trả về từ hàm đầu tiên.

Yêu cầu

  • Kết quả phải giống hệt nhau giữa các lần chạy.
  • {a, a} là một cặp không có thứ tự

Lưu ý: câu trả lời của bạn có nhiều khả năng nhận được upvote từ tôi nếu bạn cung cấp bằng chứng, nhưng tôi sẽ kiểm tra câu trả lời khi tôi nhận được nó và upvote nó một khi tôi khá chắc chắn rằng nó hoạt động.


Điều này không phù hợp hơn với puzzling.stackexchange.com ?
Jakube

2
@Jakube Không nhất thiết, vì bạn được yêu cầu viết mã.
Ông Xcoder

Tôi giả sử các cặp là duy nhất, nhưng các số được sử dụng trong các cặp đó thì không? Vậy khi nào 1,2là một trong các cặp, 1,3cũng có thể là một cặp tiềm năng (cả hai sử dụng 1)?
Kevin Cruijssen

@KevinCruijssen Tôi không chắc ý của bạn là gì
HyperNeutrino

@Giuseppe Nghịch đảo không cần phải trả lại đúng thứ tự; đó chỉ là chức năng fvà nghịch đảo của nó g, sorted((x, y))phải giống nhưsorted(g(f(x, y)))
HyperNeutrino

Câu trả lời:


13

Haskell , 65 + 30 = 95 byte

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

Hãy thử trực tuyến!

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

Hãy thử trực tuyến!


Lưu ý: Khi hai hàm có thể chia sẻ mã, đây chỉ là 75 byte:

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

Hãy thử trực tuyến! Miền là số nguyên dương. Hàm (#)thực hiện ghép nối, hàm (l!!)nghịch đảo của nó. Ví dụ sử dụng: Cả (#) 5 3(#) 3 5năng suất 12, và (l!!) 12sản lượng (5,3).

Điều này hoạt động bằng cách liệt kê rõ ràng tất cả các cặp được sắp xếp trong một danh sách vô hạn 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), ...`

Mã hóa sau đó chỉ là chỉ mục trong danh sách này.


bởi OP, mã được chia sẻ phải được tính hai lần
tự hào

5

Bình thường , 8 + 6 = 14 byte

ij\aSQ16

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

Hãy thử trực tuyến!

c.HQ\a

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

Hãy thử trực tuyến!
Tên miền: Số nguyên dương.


cách tiếp cận tốt đẹp! +1
HyperNeutrino

4
Không hoạt động cho nhiều số như 210ví dụ (có trong miền)
Emigna

Chắc chắn rồi. dụ1 ,
dụ2

Hàm thứ 2 được cho là hoạt động với bất kỳ giá trị nào trong S, không chỉ hàm được tạo với hàm đầu tiên (tôi đã mắc lỗi tương tự).
Arnauld

4

Thạch , 8 + 11 = 19 byte

Quay trở lại kể từ khi thuật toán của Rod không hoạt động.

Điều này hoạt động trên miền của các số nguyên dương.

xynhư 2 đối số, không quan trọng theo thứ tự nào, trả về z.

»’RSð+ð«

Hãy thử trực tuyến!

Nhận zvà trả lại[min(x, y), max(x, y)]

R€Ẏ,Rx`$ị@€

Hãy thử trực tuyến!


1
Tại sao các downvote? Đây không phải là thuật toán của 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]

Bản đồ từ các số nguyên không âm đến một tập hợp con của chúng.


4

C (gcc) , 36 + 39 = 75 byte

Cảm ơn @tsh vì đã lưu hai byte.

Tên miền là số nguyên không âm.

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

Mất xytrả lại z.

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

Có một intmảng hai yếu tố . Phần tử thứ hai phải được đặt thành ztrước cuộc gọi. Sau cuộc gọi rchứa xy.

Hãy thử trực tuyến!


(x+1)->-~x
tsh

3

Thạch , 13 11 byte

cặp số nguyên dương với số nguyên dương, 5 byte

Ṁc2+Ṃ

Hãy thử trực tuyến!

số nguyên dương cho cặp số nguyên dương, 6 byte

ŒċṀÞị@

Hãy thử trực tuyến!

Thuật toán

Nếu chúng ta sắp xếp tập hợp tất cả các cặp số nguyên dương không có thứ tự theo mức tối đa của chúng và sau đó theo tổng của chúng, chúng ta sẽ nhận được chuỗi sau.

{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}, khắc

Hàm đầu tiên lấy một cặp {x, y} và tìm chỉ mục của nó trong chuỗi này.

Hàm thứ hai lấy một số nguyên dương z và trả về mục thứ z của chuỗi.

Lưu ý rằng ánh xạ này giống như trong câu trả lời Jelly của @ EriktheOutgolfer .

Làm thế nào nó hoạt động

Ṁ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
Xin giải thích. Tôi không tự tin điều này là hợp lệ ...
Erik the Outgolfer

Tôi đã thêm thuật toán.
Dennis

Một cái gì đó không phù hợp với tôi ... mặc dù tôi cũng không chắc điều này có hợp lệ không. Về cơ bản, nó không tốt khi bạn sử dụng cả hai cŒċ... mặc dù tôi có thể sai. BTW đó là câu trả lời của tôi mà bạn đã vượt qua> _>
Erik the Outgolfer

Sự khác biệt là tối thiểu cho các cặp. Nếu C tính kết hợp mà không cần thay thế và Ƈ tính kết hợp với, nƇ2 = NC2 + n .
Dennis

2

Toán học (35 + 53) = 78 byte

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

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

Đây là một chức năng ghép nối bậc hai nổi tiếng cho Z <-> ZxZ kết hợp với Min và Max để làm cho nó không có trật tự.


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]}

Tôi đang cố gắng tìm cách khéo léo chọn một bộ vô hạn để làm cho việc này dễ dàng hơn, đây là cách tốt nhất tôi có được cho đến nay.

Chúng tôi xác định f (x, y) = 2 x-1 bitwise-hoặc 2 y-1 . Miền bao gồm tập hợp được định nghĩa đệ quy là chứa 1,2 và tất cả các số có thể được tạo bằng cách gọi f trên các số trong tập hợp (lưu ý rằng f (1,1) = 1 và f (2,2) = 2, nên 1 và 2 có nghịch đảo). Tất cả các số kết quả đều có một hoặc hai 1 trong phần mở rộng nhị phân của chúng, với các chỉ số của 1 tương ứng với các số trong tập hợp. Chúng ta có thể lấy cặp không có thứ tự ban đầu bằng cách lấy các chỉ số. Nếu chỉ có 1, điều đó có nghĩa là các phần tử của cặp bằng nhau.

Ví dụ: f (3,5) là 20, vì 20 là 10100 ở cơ sở 2, trong đó có 1 ở vị trí quan trọng thứ 3 và thứ 5.



Cảm ơn, S thực sự là một tập hợp con của chuỗi OEIS đó bởi vì nó chỉ bao gồm các số có số 1 có chỉ số trong S.
histocrat

à vâng, tất nhiên rồi Chà, không có trình tự nào khác phù hợp với một vài điều khoản đầu tiên (tối đa 32).
Giuseppe

Thêm 0 vào S và bạn có thể lưu một vài lần giảm.
nwellnhof

2

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

Chức năng cặp

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

Hãy thử trực tuyến!

Chức năng khởi hành

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

Hãy thử trực tuyến!


1
Bạn có thể chơi golf một vài phần. Trong hàm cặp: int i=(""+a[0]).length()có thể int i=(f+a[0]).length(); khoảng cách giữa c=0,j;i>0;có thể được loại bỏ; a[0].parseIntcó thể new Integer. Trong chức năng depair: cả ba r.parseIntcó thể được r.decode; và bạn có thể tạo một biến int cho t.length(), vì bạn sử dụng nó hai lần.
Kevin Cruijssen

1

05AB1E , 6 + 11 = 17 byte

Cổng trả lời Jelly của tôi.

Tên miền: số nguyên dương.

Lấy một danh sách [x, y]làm đầu vào, trả về z.

{`<LO+

Hãy thử trực tuyến!

Lấy một số nguyên dương zlàm đầu vào, trả về [min(x, y), max(x, y)].

L2ã€{RÙR¹<è

Hãy thử trực tuyến!

-5 cảm ơn Emigna .


Chương trình thứ hai của bạn có thể tiết kiệm 5 byte với L2ã € {RÙRI <è
Emigna

@Emigna Thủ thuật hay với 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)

Hoạt động cho số nguyên dương (về lý thuyết). Ý tưởng khá đơn giản: sắp xếp hai số theo thứ tự (ma thuật) nào đó, kết nối chúng dưới dạng chuỗi bằng một chữ cái "a", phân tích nó thành số nguyên hex.


1

MATL, 6 + 8 = 14 byte

Hàm mã hóa, có hai đầu vào n, m. Sản phẩm đầu ra của số nguyên tố thứ n và số nguyên tố thứ m.

,iYq]*

Các bước:

  • , - Làm hai lần
  • i - Đẩy đầu vào
  • Yq - Đầu vào pop, đẩy nguyên tố đầu vào
  • ]* - Kết thúc làm hai lần, bật cả số nguyên tố và sản phẩm đẩy

Hàm giải mã, mất một đầu vào m. Xuất ra số lượng các số nguyên tố bên dưới mỗi thừa số nguyên tố của n.

iYf"@Zqn

Các bước:

  • i - Đẩy đầu vào
  • Yf - Đầu vào pop, đẩy các yếu tố chính
  • " - Cho n trong mảng
  • @Zq - Đẩy mảng các số nguyên tố dưới n
  • n - Mảng pop, chiều dài đẩy của mảng

Điều này là giao hoán vì phép nhân là giao hoán và tiêm vì các thừa số nguyên tố là duy nhất. Không phải là đây không phải là số nguyên.


0

Husk , 5 + 3 = 8 byte

Tôi thực sự hy vọng tôi đã nhận được thử thách đúng, tôi thấy một số câu trả lời bị xóa có vẻ hợp lệ với tôi ...

Các cặp số nguyên dương cho một số nguyên dương duy nhất:

¤*!İp

Hãy thử trực tuyến!

Nó hoạt động bằng cách lấy các số tại các chỉ số đã cho (1-index) từ danh sách các số nguyên tố và nhân chúng.

Kết quả của hàm đầu tiên cho các cặp số nguyên dương:

mṗp

Hãy thử trực tuyến!

Chúng tôi tính hệ số đầu vào và trả về chỉ mục trong danh sách các số nguyên tố của tất cả (cả hai) các yếu tố của nó.

Ví dụ làm việc

Được đưa ra (4,1)như một cặp vợ chồng bắt đầu, chúng tôi lấy số nguyên tố thứ tư và thứ nhất (7,2)và nhân chúng → 14. Phép nhân này là những gì làm cho hàm phụ thuộc vào thứ tự của hai phần tử.

Bắt đầu từ 14, chúng tôi tính hệ số đó (2,7)và trả về các chỉ số của 27trong danh sách các số nguyên tố → (1,4).


Trên thực tế, nhìn vào câu trả lời đã bị xóa từ Arnauld, thuật toán của nó thậm chí còn tốt hơn và việc chuyển nó sang Husk sẽ dẫn đến 6 byte ... Ai đó có thể xác nhận xem giải pháp của nó (và của tôi nữa) có hợp lệ hay không?
Leo

Không hoạt động cho các số nguyên tố (nằm trong miền của các số nguyên dương)
Emigna

@Emigna chức năng thứ hai thì không, nhưng số nguyên tố không bao giờ được trả về bởi hàm thứ nhất ...
Leo

Tên miền của bạn là số nguyên dương, vì vậy cả hai phương pháp cần hoạt động cho số nguyên dương. EDIT: hoặc ít nhất đó là một yêu cầu. Các quy tắc hiện tại dường như cho phép một tập hợp con của tên miền.
Emigna

0

C # , 80 byte (38 + 42)


Dữ liệu

Mã hoá

  • Nhập Int32 l số
  • Nhập Int32 r số
  • Đầu ra Int64 Cả hai ints hợp nhất với nhau

Bộ giải mã

  • Đầu vào Int32 v Giá trị
  • Đầu ra Int32[] Một mảng với hai số nguyên gốc.

Chơi gôn

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

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

Bị đánh cắp

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

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

Ungolfed có thể đọc được

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

Mã đầy đủ

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

Phát hành

  • v1.0 - 80 bytes- Giải pháp ban đầu.

Ghi chú

  • không ai

0

Con trăn: 41 + 45 = 86

bộ mã hóa: 41

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

(11110111, 11110111)

bộ giải mã: 45

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

[4, 3]

Cố gắng cũ hơn:

Con trăn: 114: 30 + 84

bộ mã hóa: 30

chấp nhận 2 số nguyên, trả về một chuỗi

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

(432, 432)

bộ giải mã: 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

bộ giải mã2: 120

một nỗ lực khác với sự hiểu biết và tổng hợp của trình tạo

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
dựa trên nỗ lực thứ hai: e=lambda*x:10**sum(x)-10**min(x);d=lambda z:map(z .count,'09'); TIO
tsh

@tsh rất hay. Tôi sẽ điều chỉnh nó sau, hoặc bạn có thể gửi câu trả lời của riêng mình
Maarten Fabré
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.