Створіть комутативну інжекційну функцію між будь-яким (обмеженим) нескінченним набором та невпорядкованими парами


18

Пов’язано, але для цього потрібні лише додатні цілі числа і не повинні бути комутативними

Функція сполучення кантора описана в цій статті Вікіпедії . По суті, це така операція, що при застосуванні до двох значень 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 ?
Якубе

2
@Jakube Не обов'язково, оскільки вам потрібно написати код.
Містер Xcoder

Я припускаю, що пари унікальні, але чисел, які використовуються в цих парах, немає? Тож коли 1,2одна з пар 1,3може також бути потенційною парою (обидві використовують 1)?
Kevin Cruijssen

@KevinCruijssen Я не впевнений, що ти маєш на увазі
HyperNeutrino

@Giuseppe Зворотній не потрібно мати можливість повертати правильний порядок; це просто , що для функції fі її зворотній g, sorted((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]]!!)

Спробуйте в Інтернеті!


Примітка. Коли дві функції можуть ділитися кодом, це лише 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), ...`

Кодування - це лише індекс у цьому списку.


ОП, загальний код потрібно рахувати двічі
гордий 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


2-я функція повинна працювати для будь-якого значення в S, а не тільки для того, яке було сформовано з першою функцією (я зробив ту саму помилку).
Арнольд

4

Желе , 8 + 11 = 19 байт

Відкотився назад, оскільки алгоритм Рода не працював.

Це працює над областю натуральних чисел.

Бере xі yяк два аргументи, не має значення в якому порядку, повертається z.

»’RSð+ð«

Спробуйте в Інтернеті!

Бере zі повертає[min(x, y), max(x, y)]

R€Ẏ,Rx`$ị@€

Спробуйте в Інтернеті!


1
Чому голоси? Це не алгоритм Рода.
Erik the Outgolfer

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 байт

Дякуємо @tsh за збереження двох байтів.

Домен невід'ємних цілих чисел.

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

Бере xі y, повертає z.

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

Займає двоелементний 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 .

Як це працює

Ṁ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

Математика (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

Рубін, 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 мають звороти). Усі результуючі числа мають один або два 1s у своєму бінарному розширенні, причому індекси 1s відповідають числам у наборі. Ми можемо вивести оригінальну не упорядковану пару, взявши індекси. Якщо є лише один 1, це означає, що елементи пари рівні.

Наприклад, f (3,5) - 20, тому що 20 - 10100 в базі 2, що має 1s у 3-му та 5-му найменш значущих місцях.



Дякую, S - насправді підмножина цієї послідовності OEIS, хоча тому, що вона включає лише числа, у 1-х яких є індекси у S.
гістократ

ах, звичайно. Ну, жодна інша послідовність не відповідає першим кільком термінам (до 32).
Джузеппе

Додайте 0 до S, і ви можете зберегти кілька декрементів.
nwellnhof

2

Java 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
You can golf a few parts. In the pair function: int i=(""+a[0]).length() can be int i=(f+a[0]).length(); the space between c=0,j;i>0; can be removed; a[0].parseInt can be new Integer. In the depair function: all three r.parseInt can be r.decode; and you could make an int variable for t.length(), since you use it twice.
Kevin Cruijssen


1

JavaScript, 72 bytes

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

Works for positive integers (in theory). Quite simple idea: sort two number in some (magic) order, connect them as string by a letter "a", parse it as hex integer.


1

MATL, 6+8=14 bytes

Encoding function, takes two inputs n, m. Outputs product of nth prime and mth prime.

,iYq]*

Steps:

  • , - Do twice
  • i - Push input
  • Yq - Pop input, push input'th prime
  • ]* - End do twice, pop both primes and push product

Decoding function, takes one input m. Outputs the number of primes below each of the prime factors of n.

iYf"@Zqn

Steps:

  • i - Push input
  • 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 друга функція не працює, але перші ніколи не повертаються першою ...
Лев

Ваш домен має натуральні цілі числа, тому обидва методи повинні працювати для натуральних чисел. EDIT: або принаймні те, що раніше було вимогою. Поточні правила, здається, дозволяють підмножину домену.
Емінья

0

C # , 80 байт (38 + 42)


Дані

Енкодер

  • Вхідні дані Int32 l число
  • Вхідні дані Int32 r число
  • Вихідні дані Int64 Обидва вбудовані злиті разом

Дешифратор

  • Вхідні дані Int32 v Значення
  • Вихідний Int32[] масив з двома оригінальними входами.

Гольф

// 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 дуже приємно. Я його
адаптую
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.