(제한된) 무한 세트와 그 순서가없는 쌍 사이에 정류 주입 기능을 설계하십시오


18

관련이 있지만 양의 정수 만 필요하며 정식 일 필요는 없습니다.

Cantor 페어링 기능은 이 Wikipedia 기사에 설명되어 있습니다. 본질적으로, 그것은 두 개의 값 X와 Y에 적용될 때, 결과가 주어진 원래의 값 X와 Y를 얻을 수있는 연산입니다.

당신의 임무는 두 가지 기능, 즉 수행하는 기능 X, Y -> Z과 수행하는 기능을 설계 하는 것 Z -> X, Y입니다. 캐치 X, Y -> Z가 있습니다 : 반드시 정류해야합니다. 즉 Z -> X, Y, 입력이 X, Y또는 인지 여부를 확인할 수 없습니다 Y, X.

이 과제의 공식적인 정의는 다음과 같습니다.

셀 수있는 무한 세트의 숫자 S를 선택하십시오.
다음 작업을 수행하는 두 가지 기능을 설계하십시오.

  • S에 정렬되지 않은 값 쌍이 주어지면 S에 값을 반환
  • 초기 함수의 반환 값이 주어지면 첫 번째 함수를 통과 할 때 입력 정수로 평가되는 정렬되지 않은 값 쌍을 반환합니다. 입력이 첫 번째 함수의 반환 값이 아닌 경우이 역 함수의 동작에 신경 쓰지 않습니다.

요구 사항

  • 결과는 런간에 동일해야합니다.
  • {a, a} 순서가없는 쌍입니다

참고 : 증거를 제공하면 귀하의 답변이 나에게서 투표를받을 가능성이 높지만, 그것이 도착하면 답변을 테스트하고 제대로 작동한다고 확신하면 투표합니다.


puzzling.stackexchange.com 에 더 적합하지 않습니까?
Jakube

2
@Jakube 반드시 코드를 작성해야하는 것은 아닙니다.
Mr. Xcoder

나는 쌍이 유일하다고 가정하지만 그 쌍에 사용 된 숫자는 그렇지 않습니까? 따라서 1,2쌍 중 하나가 언제 1,3잠재적 쌍이 될 수 1있습니까?
Kevin Cruijssen

@KevinCruijssen 무슨 말인지 잘 모르겠습니다
HyperNeutrino

@Giuseppe 역수가 올바른 순서를 반환 할 필요는 없습니다. 이는 함수 뿐이다 f그 역 g, sorted((x, y))동일해야sorted(g(f(x, y)))
HyperNeutrino

답변:


13

하스켈 , 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]]!!)

온라인으로 사용해보십시오!


참고 : 두 함수가 코드를 공유 할 수있는 경우 이는 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 5수율 12(l!!) 12수율 (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에 의해, 공유 코드는 두 번 계산되어야한다
자랑스러운 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
같은 번호의 많은 작동하지 않습니다 210(도메인에있는) 예를 들어
Emigna

확실한. 1 , 예 2
Emigna

두 번째 함수는 첫 번째 함수로 생성 된 것이 아니라 S의 모든 값에 대해 작동해야 합니다 (나는 같은 실수를했습니다).
Arnauld

4

젤리 , 8 + 11 = 19 바이트

Rod의 알고리즘이 작동하지 않아 롤백되었습니다.

이것은 양의 정수 영역에서 작동합니다.

소요 xy2 인자로, 어떤 순서로, 반환에 문제가되지 않습니다 z.

»’RSð+ð«

온라인으로 사용해보십시오!

가져와 z반환[min(x, y), max(x, y)]

R€Ẏ,Rx`$ị@€

온라인으로 사용해보십시오!


1
왜 다운 보트인가? 이것은 Rod의 알고리즘이 아닙니다.
Outgolfer Erik

4

자바 스크립트 (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배열을받습니다. 두 번째 요소는 z통화 전에 로 설정해야합니다 . 호출 후 r포함 x하고 y.

온라인으로 사용해보십시오!


(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} 쌍을 취하여이 시퀀스에서 인덱스를 찾습니다.

두 번째 함수는 양의 정수 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
설명 해주세요 나는이 ... 유효 확신 아니에요
에릭 Outgolfer

알고리즘을 추가했습니다.
Dennis

나에게 잘 붙어 있지 않습니다 ... 이것이 유효하지 않은지 확실하지 않습니다. 기본적으로 그것은 종류의 당신이 모두를 사용하는 것이 아니라 충실하지 않습니다 cŒċ내가 잘못 될 수도 있지만 .... BTW 당신이> _> outgolfed 내 대답이었다
Outgolfer Erik

쌍의 차이는 최소화됩니다. 경우 C는 교체없이 조합을 계산하고, ■ 카메라 와의 조합 계산 nƇ2 = NC2 + N을 .
Dennis

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가 Min 및 Max와 결합되어 순서가없는 것으로 알려진 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 비트 단위 또는 2를 정의합니다 y-1을 정의 합니다. 도메인은 1,2를 포함하는 것으로 재귀 적으로 정의 된 집합과 집합의 숫자에서 f를 호출하여 생성 할 수있는 모든 숫자로 구성됩니다 (f (1,1) = 1 및 f (2,2) = 2, 그래서 1과 2는 역수가 있습니다). 결과 숫자는 모두 이진 확장에서 하나 또는 두 개의 1을 가지며, 1의 색인은 세트의 숫자에 해당합니다. 인덱스를 가져 와서 정렬되지 않은 원래 쌍을 가져올 수 있습니다. 1이 하나만 있으면 쌍의 요소가 동일하다는 것을 의미합니다.

예를 들어, f (3,5)는 20입니다. 20은 밑이 2 일 때 10100이며 이는 3 번째와 5 번째로 중요도가 낮은 곳에서 1입니다.



고맙게도 S는 실제로 OEIS 시퀀스의 하위 집합이지만 1은 S에 인덱스가있는 숫자 만 포함하기 때문입니다.
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. 실망 할 기능에서 다음 세 가지가 r.parseInt될 수있다 r.decode; int 변수를 t.length()두 번 사용할 수 있기 때문에 int 변수를 만들 수 있습니다.
케빈 크루이 센

1

05AB1E , 6 + 11 = 17 바이트

내 젤리 포트

도메인 : 양의 정수

리스트 [x, y]를 입력으로 받아서를 반환합니다 z.

{`<LO+

온라인으로 사용해보십시오!

양의 정수 z를 입력으로 받아서를 반환합니다 [min(x, y), max(x, y)].

L2ã€{RÙR¹<è

온라인으로 사용해보십시오!

Emigna 에게 -5 감사합니다 .


와 5 바이트를 저장할 수 있습니다 귀하의 두 번째 프로그램 L2A € {루리 <è
Emigna

@Emigna 멋진 트릭 2ã€{RÙR!
Outgolfer Erik

1

자바 스크립트, 72 바이트

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

양의 정수 (이론적으로)에 작동합니다. 아주 간단한 아이디어 : 두 개의 숫자를 (매직) 순서로 정렬하고 문자로 문자열로 연결하고 "a"16 진수 정수로 구문 분석하십시오.


1

MATL, 6 + 8 = 14 바이트

인코딩 기능은 두 개의 입력 n, m을 취합니다. n 번째 소수와 m 번째 소수의 곱을 출력합니다.

,iYq]*

단계 :

  • , -두 번 해
  • i -푸시 입력
  • Yq -팝 입력, 푸시 입력의 소수
  • ]* -두 번 끝내고, 프라임을 팝하고 제품을 푸시하십시오.

디코딩 기능, 하나의 입력 m을 취합니다. 각 소수 n 이하의 소수를 출력합니다.

iYf"@Zqn

단계 :

  • i -푸시 입력
  • Yf -팝 입력, 주요 요소의 푸시 배열
  • " -배열의 n
  • @Zq -n 이하의 소수 배열을 푸시
  • n -팝 어레이, 푸시 길이

곱셈은 ​​정식 적이며, 소인수 분해가 독특하기 때문에 주입 형이기 때문에 이것은 정식 적입니다. 이것이 정수에 있지는 않습니다.


0

껍질 , 5 + 3 = 8 바이트

나는 도전을 올바르게하기를 희망하며, 나에게 유효한 것으로 보이는 삭제 된 답변을 봅니다.

양의 정수를 단일 양의 정수에 결합 :

¤*!İp

온라인으로 사용해보십시오!

소수 목록에서 주어진 인덱스 (1 인덱스)의 숫자를 가져 와서 곱하면 작동합니다.

양의 정수를 결합한 첫 번째 함수의 결과 :

mṗp

온라인으로 사용해보십시오!

우리는 입력 숫자를 인수 분해하고 모든 요소의 소수 (prim) 목록에 색인을 반환합니다.

작동 예

(4,1)시작 커플로 주어지면 , 우리는 네 번째와 첫 번째 소수를 취하고 (7,2)곱합니다 →14 . 이 곱셈은 두 요소의 순서에 따라 함수를 독립적으로 만듭니다.

에서 시작 14, 우리는 그것을 인수 분해 (2,7)와의 인덱스를 반환 2하고 7소수 → 목록에 (1,4).


실제로 Arnauld에서 삭제 된 답변을 보면 알고리즘이 더 좋으며 Husk로 이식하면 6 바이트가됩니다 ... 누군가 솔루션이 유효한지 여부를 확인할 수 있습니까?
Leo

소수 (정수의 도메인에있는) 소수에 대해서는 작동하지 않음
Emigna

@Emigna 두 번째 함수는 그렇지 않지만 첫 번째 함수는 소수를 반환하지 않습니다.
Leo

귀하의 도메인은 양의 정수이므로 두 방법 모두 양의 정수에 대해 작동해야합니다. 편집 : 또는 적어도 요구 사항이었던 것. 현재 규칙은 도메인의 하위 집합을 허용하는 것으로 보입니다.
Emigna

0

C # , 80 바이트 (38 + 42)


데이터

엔코더

  • 입력 Int32 l A 번호
  • 입력 Int32 r A 번호
  • 출력 Int64 두 정수가 함께 융합

디코더

  • 입력 Int32 v
  • 출력 Int32[] 원래 정수가 2 개인 배열입니다.

골프

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

파이썬 : 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]

이전 시도 :

파이썬 : 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
두 번째 시도에 기반 : e=lambda*x:10**sum(x)-10**min(x);d=lambda z:map(z .count,'09'); TIO
tsh

@ tsh 아주 좋은. 나중에 적용하거나 직접 답변을 제출할 수 있습니다
Maarten Fabré
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.