형용사 기능 ℤ → ℤⁿ


23

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

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

나선

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

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

에프케이(엑스):지→지케이

도전

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

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

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

명세서

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

그것의 스트링 버전 취할 괜찮 k및 x대신 정수를?
— 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의 설계 원칙이며,이 두 가지 의미는 어떻게 든 관련이 있어야합니다. 카디널 및 서수 모드는 사물이 동일하지만 다른 미러 우주라는 느낌입니다. 그리고 자주 추가하고 싶은 두 가지 모드 중 하나에 대한 명령이 있었고 다른 명령과 쌍을 이룰 수 있는지 알아 내야했습니다.

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

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


항상 좋은 설명
— Luis Mendo

찾기 Y와 Z앨리스 워드 프로세서에서 것은 (나는 잠시 동안 그것에 대해 생각하고 있었다, 그러나 이것은 나에게 상기시켰다)이 도전을 게시 내게 묻는 메시지가 무엇인지 사실이다.
— 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.