형용사 기능 ℤ → ℤⁿ


23

Z (모든 정수 세트)에서 Z (예 : 항등 함수)에 이르는 형용사 함수 를 만드는 것이 간단 합니다 .

에서 Z 2 (2 개의 정수의 모든 쌍 세트; ZZ데카르트 곱) 의 이항 함수를 생성 할 수도 있습니다 . 예를 들어, 2D 평면에서 정수 점을 나타내는 격자를 취하여 0에서 바깥쪽으로 나선을 그린 다음 해당 점과 교차 할 때 나선을 따라 거리로 정수 쌍을 인코딩 할 수 있습니다.2

나선

(자연수로이를 수행하는 기능을 페어링 기능 이라고 합니다 .)

실제로,이 bijective 기능의 패밀리가 있습니다 :

에프케이(엑스):케이

도전

함수 정의 가족 ( k는 그 속성으로 양의 정수)를 F K ( x는 ) bijectively하는 정수 매핑 k는 정수를 -tuples.에프케이(엑스)케이에프케이(엑스)케이

입력 x가 주어진 경우 제출은 f k ( x )를 반환 해야합니다 .케이엑스에프케이(엑스)

이것은 이므로 가장 짧은 유효한 답변 (바이트 단위로 측정)이 이깁니다.

명세서

  • 상관 가족 만큼이 위의 기준을 충족로서 사용될 수있다.에프케이(엑스)
  • 함수 패밀리의 작동 방식에 대한 설명과 함수의 역수를 계산하는 스 니펫 (바이트 수에는 포함되지 않음)을 추가하는 것이 좋습니다.
  • 역함수를 계산할 수 없다면, 함수가 형용사라는 것을 증명할 수있는 한 괜찮습니다.
  • 언어에 대한 부호있는 정수 및 부호있는 정수 목록에 적합한 표현을 사용할 수 있지만 함수에 대한 입력이 제한되지 않도록해야합니다.
  • 값을 최대 127까지만 지원하면됩니다 .케이

그것의 스트링 버전 취할 괜찮 kx대신 정수를?
JungHwan Min

@JungHwanMin 입력 숫자를 나타내는 문자열이 정상입니다.
Esolanging 과일

답변:


19

Alice , 14 12 바이트

/O
\i@/t&Yd&

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

역함수 (골프 아님) :

/o     Q
\i@/~~\ /dt&Z

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

설명

Alice는 2 사이에 빌트인 bijection을 가지고 있으며, Y(unpack)과 그 역 Z (pack) 으로 계산할 수 있습니다 . 다음은 bijection을 설명하는 문서에서 발췌 한 것입니다.

bijection의 세부 사항은 대부분의 사용 사례와 관련이 없습니다. 요점은 사용자가 두 정수를 하나로 인코딩하고 나중에 두 정수를 추출 할 수 있다는 것입니다. pack 명령을 반복해서 적용하면 전체 목록 또는 정수 트리를 단일 번호로 저장할 수 있습니다 (특히 메모리 효율적인 방식은 아님). 팩 연산에 의해 계산 된 매핑은 궤적 함수 2 → ℤ (즉, 일대일 매핑)입니다. 먼저 정수 {..., -2, -1, 0, 1, 2, ...}{..., 3, 1, 0, 2, 4 와 같은 자연수 (0 포함)에 매핑됩니다. , ...}즉, 음의 정수는 홀수 내츄럴에 매핑되고 음이 아닌 정수는 짝수 내츄럴에 매핑됩니다. 그런 다음 두 자연수는 Cantor pairing 함수 를 통해 하나에 매핑됩니다.이 함수 는 정수 그리드의 1 사분면의 대각선을 따라 자연 을 씁니다. 구체적으로, {(0,0), (1,0), (0,1), (2,0), (1,1), (0,2), (3,0), ...}{0, 1, 2, 3, 4, 5, 6, ...}에 매핑되었습니다 . 그런 다음 결과 자연 수는 이전 bijection의 역수를 사용하여 정수로 다시 매핑됩니다. unpack 명령은이 매핑의 역수를 정확하게 계산합니다.

위에서 언급했듯이,이 언팩 작업을 사용하여 k 로 매핑 할 수도 있습니다 . 초기 정수에 적용한 후 결과의 두 번째 정수를 다시 압축 해제하여 세 개의 정수 목록을 제공합니다. 그래서 K-1 의 응용 프로그램을 Y주고 우리는 케이 결과로 정수를.

리스트를 Z끝까지 묶어 역수를 계산할 수 있습니다 .

따라서 프로그램 자체는 다음과 같은 구조를 갖습니다.

/O
\i@/...d&

이것은 변수의 십진 정수를 입력으로 읽고 변수 번호를 결과로 인쇄하는 프로그램의 기본 템플릿입니다. 실제 코드는 다음과 같습니다.

t   Decrement k.
&   Repeat the next command k-1 times.
Y   Unpack.

제가 말씀 드리고 싶은 한 가지는 "Alice가 왜 bi → bi 2 궤적 을 위해 내장되어 있을까요, 골프 언어 영역이 아닌가?"입니다. Alice의 이상한 내장 기능이 대부분인 것처럼, 주된 이유는 모든 명령이 두 가지 의미, 즉 카디널 (정수) 모드와 서수 (문자열) 모드에 대한 두 가지 의미를 갖는 Alice의 설계 원칙이며,이 두 가지 의미는 어떻게 든 관련이 있어야합니다. 카디널 및 서수 모드는 사물이 동일하지만 다른 미러 우주라는 느낌입니다. 그리고 자주 추가하고 싶은 두 가지 모드 중 하나에 대한 명령이 있었고 다른 명령과 쌍을 이룰 수 있는지 알아 내야했습니다.

의 경우 YZ서수 모드 처음 온 : 나는 두 문자열 (지퍼) 인터리브 다시 (압축 해제)를 구분하는 기능을 갖고 싶었다. 카디널 모드에서 캡처하고 싶었던 이것의 품질은 2에서 하나의 정수를 형성하고 나중에 2 개의 정수를 다시 추출 할 수있게 되었기 때문에 그러한 거부를 자연스럽게 선택했습니다.

또한 이것이 골프 밖에서 실제로 매우 유용 할 것이라고 생각했습니다. 단일 목록의 메모리 (스택 요소, 테이프 셀 또는 그리드 셀)에 전체 목록 또는 정수 트리를 저장할 수 있기 때문입니다.


항상 좋은 설명
Luis Mendo

찾기 YZ앨리스 워드 프로세서에서 것은 (나는 잠시 동안 그것에 대해 생각하고 있었다, 그러나 이것은 나에게 상기시켰다)이 도전을 게시 내게 묻는 메시지가 무엇인지 사실이다.
Esolanging 과일 23

11

파이썬, 96 93 바이트

def f(k,x):
 c=[0]*k;i=0
 while x:v=(x+1)%3-1;x=x//3+(v<0);c[i%k]+=v*3**(i//k);i+=1
 return c

이것은 원칙적으로 입력 수 x균형이 잡힌 삼항 으로 변환 한 다음 다른 좌표 사이에서 가장 중요하지 않은 삼 자릿수 (삼항 자릿수)를 라운드 로빈 방식으로 먼저 분배함으로써 작동합니다. 그래서에 대한 k=2예를 들어, 모든 심지어 위치 trit이 (가)에 기여할 x좌표, 모든 홀수 위치 지정된 trit은에 기여할 y좌표입니다. 의 경우 k=3에는, 제 1 내지 제 4 및 일곱 trits (등)에 기여하고있는 것 x번째, 다섯 번째 및 여덟 번째는 기여하지만, y여섯 번째 및 아홉 번째에 기여하고, 세번째 z.

예를 들어 with k=2를 사용하여을 살펴 보겠습니다 x=35. 균형이 잡힌 삼항에서는 35입니다 110T( 숫자를 T나타내는 Wikipedia 기사의 표기법 사용 -1). Trit를 나누면 좌표에 1T대해 오른쪽에서 계산하여 첫 번째와 세 번째 Trit을 제공하고 x좌표에 대해 10두 번째 및 네 번째 Trit을 제공합니다 y. 각 좌표를 다시 십진수로 변환하면을 얻습니다 2, 3.

물론 골프 코드에서 실제로 정수를 균형 잡힌 삼항으로 한 번에 변환하지는 않습니다. 나는 한 번에 한 v변수를 변수로 계산 하고 그 값을 적절한 좌표에 직접 추가하고 있습니다.

다음은 좌표 목록을 가져와 숫자를 반환하는 ungolfed 역함수입니다.

def inverse_f(coords):
    x = 0
    i = 0
    while any(coords):
        v = (coords[i%3]+1) % 3 - 1
        coords[i%3] = coords[i%3] // 3 + (v==-1)
        x += v * 3**i
        i += 1
    return x

f기능은 아마도 그 성능으로 유명 할 것입니다. O(k)메모리 만 사용 O(k) + O(log(x))하고 결과를 찾는 데 시간이 걸리므 로 매우 큰 입력 값으로 작업 할 수 있습니다. 보십시오 f(10000, 10**10000)예를 들어, 당신은 (그래서 지수에 추가 제로를 추가 거의 즉시 답변을 얻을 것 x입니다 10**100000내 오래된 PC에 30 초 정도 걸릴 만든다). 역함수는 빠르지 않습니다. 대부분 완료된 시점을 알기가 어렵 기 때문에 (각 변경 후 모든 좌표를 스캔하므로 O(k*log(x))시간 과 같은 시간 이 걸립니다 ). 아마도 더 빠를 수 있도록 최적화되었을 수도 있지만 이미 일반 매개 변수에 대해서는 충분히 빠를 것입니다.


while 루프 내부 의 공백 (개행)을 제거 할 수 있습니다
Mr. Xcoder

고맙게도, 실수로 루프와 ;한 줄로 명령문을 연결 하는 데 약간의 충돌이 있다고 생각했습니다 .
Blckknght

9

껍질 , 10 바이트

§~!oΠR€Θݱ

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

역함수도 10 바이트입니다.

§o!ȯ€ΠRΘݱ

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

설명

앞으로 방향 :

§~!oΠR€Θݱ  Implicit inputs, say k=3 and x=-48
        ݱ  The infinite list [1,-1,2,-2,3,-3,4,-4,..
       Θ    Prepend 0: [0,1,-1,2,-2,3,-3,4,-4,..
 ~    €     Index of x in this sequence: 97
§    R      Repeat the sequence k times: [[0,1,-1,..],[0,1,-1,..],[0,1,-1,..]]
   oΠ       Cartesian product: [[0,0,0],[1,0,0],[0,1,0],[1,1,0],[-1,0,0],[0,0,1],..
  !         Index into this list using the index computed from x: [-6,1,0]

반대 방향 :

§o!ȯ€ΠRΘݱ  Implicit inputs, say k=3 and y=[-6,1,0]
     ΠRΘݱ  As above, k-wise Cartesian product of [0,1,-1,2,-2,..
   ȯ€       Index of y in this sequence: 97
§o!         Index into the sequence [0,1,-1,2,-2,.. : -48

Cartesian 제품 내장 Π은 무한리스트에 대해 훌륭하게 작동하여 각 k 튜플을 정확히 한 번 열거합니다 .


[[0,1,-1,..],[[0,1,-1,..],[[0,1,-1,..]]이 부분은 [[0,1,-1,..],[0,1,-1,..],[0,1,-1,..]]무엇입니까?
아웃 골퍼 Erik

@EriktheOutgolfer 음 음, 이제 수정되었습니다.
Zgarb

이것은 아름답다. J 프로그래머로서 이와 같은 게으른 목록 솔루션을 지원하지 않는 J로 변환하는 좋은 방법이 있는지 알고 있습니까? ^:^:_형 솔루션은 일반적으로 ... 훨씬 더 복잡를 끝낼
요나

@Jonah 확실하지 않습니다. 항목 을 사용하여 모든 k- 튜플 의 배열을 계산하여 i: x절대 값의 합계로 정렬 한 다음 색인을 생성 할 수 있습니다. 아이디어는 이러한 배열이 모든 k- 튜플 을 포함하는 하나의 "무한 배열"의 접두사라는 것입니다 .
Zgarb

7

Wolfram Language (Mathematica) , 61 바이트

SortBy[Range[-(x=2Abs@#+Boole[#>=0]),x]~Tuples~#2,#.#&][[x]]&

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

(정수를 입력 한 다음 튜플의 길이를 입력으로 사용합니다.)

역:

If[OddQ[#],#-1,-#]/2&@Tr@Position[SortBy[Range[-(x=Ceiling@Norm@#),x]~Tuples~Length@#,#.#&],#]&

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

작동 원리

아이디어는 간단합니다. 정수 입력을 양의 정수로 변환합니다 (0,1,2,3, ...을 1,3,5,7, ... 및 -1, -2, -3, ...에서 2,4,6, ...)로 이동 한 다음 모든 k- 튜플에 색인을 생성 하고 원점에서 거리를 기준으로 정렬 한 다음 Mathematica의 기본 타이 브레이킹으로 정렬합니다.

그러나 무한 목록을 사용할 수 없으므로 n 번째 k 튜플을 찾을 때 { -n , ..., n } 범위의 정수 k- 튜플 만 생성 합니다. 때문이 충분히 보장되는 N 번째 최소 k 값 의 기준과 -tuple 미만 놈을 갖는다 N 및 규범 모든 투플은 N 이하의리스트에 포함된다.

반대로, 우리는 단지 충분히 긴 k- 튜플 리스트를 생성하고 , 그리스트에서 주어진 k- 튜플 의 위치를 ​​찾은 다음 "양의 정수로 폴드"연산을 뒤집습니다.


2
입력으로 실행하면 [15, 5]내 PC가 다운되었습니다 ...
JungHwan Min

2
일어날거야. 원칙적으로, 알고리즘은 어떤 것이 든 작동하지만, 귀하의 경우 {-31, .., 31} 범위에서 5 개의 튜플을 모두 생성 한 다음 31 번째를 사용하여 작동하므로 메모리를 많이 사용합니다.
Misha Lavrov

3

J, 7 바이트

#.,|:#:

이것을 매우 간단하게하는 J 코드

매우 간단한 페어링 기능 (또는 튜플 링 기능)은 단순히 각 숫자의 이진 확장 자릿수를 인터리브하는 것입니다. 예를 들어 (47, 79)다음과 같이 쌍을 이룹니다.

1_0_0_1_1_1_1
 1_0_1_1_1_1
-------------
1100011111111

또는, 6399. 분명히, 우리는 어떤 n- 튜플에도 사소하게 일반화 할 수 있습니다.

이것이 동사에 의해 동사가 어떻게 작동하는지 살펴 봅시다.

#:안티베이스 2이며, 모노로 사용하면 숫자의 이진 확장을 반환합니다. #: 47 79결과를 제공합니다.

0 1 0 1 1 1 1
1 0 0 1 1 1 1

|:전치 연산자는 단순히 배열을 회전시킵니다. 회전 결과 #: 47 79는 다음과 같습니다.

0 1
1 0
0 0
1 1
1 1
1 1
1 1

모나 딕 방식으로 사용하면 라벨 ,연산자가 테이블에서 1 차원 목록을 생성합니다.

0 1 1 0 0 0 1 1 1 1 1 1 1 1

마지막으로 #.이진 확장을 다시 변환하여 결과를 얻습니다 6339.

이 솔루션은 모든 정수 문자열에 대해 작동합니다.


7
음수에서는 어떻게 작동합니까?

2

펄 6 , 148 바이트

my@s=map ->\n{|grep {n==abs any |$_},(-n..n X -n..n)},^Inf;my&f={$_==1??+*!!do {my&g=f $_-1;my@v=map {.[0],|g .[1]},@s;->\n{@v[n>=0??2*n!!-1-2*n]}}}

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

언 골프 드 :

sub rect($n) {
    grep ->[$x,$y] { abs($x|$y) == $n }, (-$n..$n X -$n..$n);
}

my @spiral = map { |rect($_) }, ^Inf;

sub f($k) {
    if ($k == 1) {
        -> $_ { $_ }
    } else {
        my &g = f($k-1);
        my @v = map -> [$x, $y] { $x, |g($y) }, @spiral;
        -> $_ { $_ >= 0 ?? @v[2*$_] !! @v[-1-2*$_] }
    }
}

설명:

  • rect($n)좌표로부터 직사각형의 가장자리에 일체로 점의 좌표를 생성하는 도우미 함수 (-$n,$n)로는 ($n, $n).

  • @spiral 0부터 시작하여 크기가 커지는 사각형의 가장자리에있는 적분 점의 게으른 무한 목록입니다.

  • f($k)정수에서 정수 $k-tuples 까지의 bijection 인 함수를 리턴합니다 .

경우 $k이며 1, f신원의 매핑을 돌려줍니다 -> $_ { $_ }.

그렇지 않으면, &g정수에서 정수의- $k-1튜플로 재귀 적으로 얻은 맵핑입니다 .

그런 다음 우리 @spiral는 원점에서 $k나와 X 좌표와 gY 좌표 로 호출 한 평평한 결과를 취하여 각 지점에서 튜플을 형성합니다 . 이 지연 생성 된 매핑은 배열에 저장됩니다 @v.

@v$k인덱스 0으로 시작하는 모든 튜플을 포함 하므로 인덱스를 음수로 확장하려면 양수 입력을 짝수로, 음수 입력을 홀수로 매핑하십시오. @v이런 방식으로 요소를 찾는 함수 (클로저)가 반환 됩니다.


2

자바 스크립트, 155 바이트

f=k=>x=>(t=x<0?1+2*~x:2*x,h=y=>(g=(v,p=[])=>1/p[k-1]?v||t--?0:p.map(v=>v&1?~(v/2):v/2):[...Array(1+v)].map((_,i)=>g(v-i,[...p,i])).find(u=>u))(y)||h(y+1))(0)

Prettify 버전 :

k => x => {
  // Map input to non-negative integer
  if (x > 0) t = 2 * x; else t = 2 * -x - 1;
  // we try to generate all triples with sum of v
  g = (v, p = []) => {
    if (p.length === k) {
      if (v) return null;
      if (t--) return null;
      // if this is the t-th one we generate then we got it
      return p;
    }
    for (var i = 0; i <= v; i++) {
      var r = g(v-i, [...p, i]);
      if (r) return r;
    }
  }
  // try sum from 0 to infinity
  h = x => g(x) || h(x + 1);
  // map tuple of non-negative integers back
  return h(0).map(v => {
    if (v % 2) return -(v + 1) / 2
    else return v / 2;
  });
}
  • 먼저 모든 정수를 음이 아닌 모든 정수에 하나씩 매핑합니다.
    • n> 0이면 결과 = n * 2
    • 그렇지 않으면 결과 = -n * 2-1
  • 둘째, k 길이의 음이 아닌 정수를 가진 모든 튜플에 순서를 제공합니다.
    • 모든 요소의 합을 계산하면 작은 것이 먼저 나온다
    • 합계가 같으면 왼쪽에서 오른쪽으로 비교하면 작은 것이 먼저 나옵니다.
    • 결과적으로, 음이 아닌 모든 정수에 대한 맵을 음이 아닌 k 개의 튜플에 매핑했습니다.
  • 마지막으로, 두 번째 단계에서 주어진 튜플의 음이 아닌 정수를 첫 번째 단계에서 비슷한 공식의 모든 정수에 매핑하십시오

x<0?~x-x:x+x2 바이트를 절약 한다고 생각 합니다.
Neil

2

Wolfram Language (Mathematica) , 107 바이트

(-1)^#⌈#/2⌉&@Nest[{w=⌊(√(8#+1)-1)/2⌋;x=#-w(w+1)/2,w-x}~Join~{##2}&@@#&,{2Abs@#-Boole[#<0]},#2-1]&

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

역, 60 바이트

(-1)^#⌈#/2⌉&@Fold[+##(1+##)/2+#&,2Abs@#-Boole[#<0]&/@#]&

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

설명:

통해 Z-> N0 f(n) = 2n if n>=0 and -2n-1 if n<0

페어링 기능의 역을 통한 N0-> N0 ^ 2

N0-> N0 ^ k 우리가 길이를 얻을 때까지 위의 가장 왼쪽 숫자에 반복해서 적용 k

f(n) = (-1)^n * ceil(n/2)요소 별을 통한 N0 ^ k-> Z ^ k


Mathematica, 101 바이트

(-1)^#⌈#/2⌉&@Nest[{a=#~IntegerExponent~2+1,#/2^a+1/2}~Join~{##2}&@@#&,{2Abs@#+Boole[#<=0]},#2-1]&

위와 유사하지만 (N0 대신 N을 사용함) bijection f의 역수를 사용합니다. N ^ 2-> N via f(a, b) = 2^(a - 1)(2b - 1)


그러니까 ... Mathematica가 내장되어 있지 않습니다 (Alice가있을 때)? 나는 말이 없습니다.
JayCe

1

자바 스크립트, 112 바이트

k=>x=>(r=Array(k).fill(''),[...`${x<0?2*~x+1:2*x}`].map((c,i,s)=>r[(s.length-i)%k]+=c),r.map(v=>v&1?~(v/2):v/2))
  1. 음수가 아닌 것으로 변환
  2. (n * k + i) 번째 숫자부터 i 번째 숫자까지
  3. 다시 변환

@HermanLauenstein을 되돌릴 필요가 없습니까?
tsh

x<0?~x-x:x+x2 바이트를 절약 한다고 생각 합니다.
Neil

[...BT${x<0?~x-x:x+x}BT].reverse().map((c,i)=>r[i%k]+=c),(를 위해 @Neil에 신용을 사용하여) -5 바이트 x<0?~x-x:x+x. 첫 번째에 추가 매개 변수 가 필요하지 않기 때문에 .reverse()대신 사용됩니다 . 임시 배열을 다시 사용하지 않기 때문에 되돌릴 필요가 없습니다. (나는 그것을 테스트하지는 않았지만 아마도 작동해야 할 것입니다)(s.length-i)s.map
Herman L

다른 바이트 대체하여 저장할 수 .fill('').fill(0)선두 제로 (적어도 사파리 시험하지 않을 때)에는 차이가 없으므로,
허만 L을

@HermanLauenstein 시도 했습니까 .fill`` ? 다른 몇 바이트를 절약 할 수 있습니다.
Neil


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.