아이젠 슈타인 가우스


18

가우스 정수 , 여기서 , 는 정수이고 는 허수 단위입니다. 가장 가까운 값 (유클리드 거리까지) Eisenstein integer 여기서 , 은 정수이고 입니다.a+biabi=exp(πi/2)k+lωklω=exp(2πi/3)=(1+i3)/2

배경

모든 가우시안 정수는 , 정수를 사용 로 고유하게 작성 될 수 있습니다 . 그렇게 분명하지는 않지만 사실입니다. 모든 아이젠 슈타인 정수는 , 정수를 가진 로 고유하게 쓸 수 있습니다 . 그것들 은 복소수 내에서 -모듈을 형성하며 , 각각 또는 대한 번째 사이클로 톰 정수 이다. 참고a+biabk+lωklZp=233+2i3+2ω

출처 : commons.wikimedia.org

세부

  • 주어진 복소수에 2 개 또는 3 개의 가장 가까운 점이있는 경우 그 중 하나를 반환 할 수 있습니다.

  • 복소수는 직사각형 좌표 (기준 ) 로 주어 지지만 or 또는 기타 와 같은 편리한 형식의 것 이외의 것입니다 .(1,i)(A,B)A+BiA+B*1j

  • 아이젠 슈타인 정수가 기준 좌표로서 리턴한다 과 같은 임의의 편리한 포맷이지만보다 다른 하거나 또는 기타(1,ω)(K,L)K+LωK+L*1ω

모든 실수는 분명히 실수로 다시 매핑되어야합니다.

  6,14 -> 14,16
  7,16 -> 16,18
-18,-2 ->-19,-2
 -2, 2 -> -1, 2
 -1, 3 -> 1, 4




a와 b에 반대 부호가있는 테스트 사례도 포함해야합니다.
SmileAndNod

@SmileAndNod 하나를 추가했습니다. 그러나 실제 축과 관련하여 대칭을 사용하고로 대체 할 수도 (1,w)있습니다 (-1,1+w). 또한이 섹션의 이름을 예제 로 변경 하여 이러한 경우에 적합한 결과를 제공하는 것만으로는 충분하지 않음을 분명히했습니다.
flawr

답변:


7

APL (Dyalog Extended) , 16 바이트 SBCS

0+⌈3÷⍨1 2×⌊⎕×√3

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

걸리는 전체 프로그램 yx표준 입력과 정수의 2 요소 벡터를 출력한다.

작동 방식 : 수학

우선 가우시안 정수는 다이아몬드의 수직 대각선에 위치하며 는 에 정수 됩니다.Z(x,3y)x,y

      + W
     /|\
    / | \
   /  |  \
  /   + X \
 /    |    \
+-----|-----+V
 \    |    /
  \   + Y /
   \  |  /
    \ | /
     \|/
      + Z

그림에서 및 . 따라서 점의 수직 위치를 고려하면 가장 가까운 아이젠 슈타인 점을 다음과 같이 식별 할 수 있습니다.WZ¯=3WX¯=XY¯=YZ¯=XV¯=YV¯=13

Given a point PWZ¯,{PWX¯the nearest point is WPXY¯the nearest point is VPYZ¯the nearest point is Z

가우스 점을 감안할 때 , 우리는 먼저 어떤 다이아몬드 결정 , 얼마나 많은 다이아몬드 (표시에 의해 측정 속한 ) 거리로부터PPhZx

h=P.y÷3

Z

Z.xE=P.x+h,Z.yE=2h

WX¯,XY¯,YZ¯ Pw

w=P.y×3%3

w=0,1,2YZ¯,XY¯,WX¯PZVX

PE.xE=P.x+h+w2,PE.yE=2h+w

hw

y=P.y×3,PE.xE=P.x+y÷3,PE.yE=2y÷3

작동 방식 : 코드

0+⌈3÷⍨1 2×⌊⎕×√3
           ⌊⎕×√3   Take the first input (P.y) and calculate y'
   ⌈3÷⍨1 2×       ⍝ Calculate [ceil(y'/3), ceil(2y'/3)]
⎕0+  ⍝ Take the second input(P.x) and calculate [P.x+ceil(y'/3), ceil(2y'/3)]

2

자바 스크립트 (ES6), 112 바이트

(a,b,l=b/Math.pow(.75,.5),k=a+l/2,f=Math.floor,x=k-(k=f(k)),y=l-(l=f(l)),z=x+y>1)=>[k+(y+y+z>x+1),l+(x+x+z>y+1)]

ES7은 분명히 9 바이트를 트리밍 할 수 있습니다. 설명 : k그리고 l처음에 부동 소수점 솔루션을 나타냅니다 k+ωl=a+ib. 그러나 좌표는 유클리드 거리만큼 가장 가까운 정수로 반올림되어야했습니다. 따라서 k및 의 바닥을 차지한 l다음 분수 부분에 대한 테스트를 수행하여 점진적으로에 가까운 점이 발생하는지 확인합니다 a+ib.


나는 x는 항상 0.2887 또는 0.577and y는 항상 하나 0.1547 또는 0.577이라는 소수 부분에 당신의 테스트는 사실을 활용하는 것 같아요
SmileAndNod

@SmileAndNod 3 년 전? 나는 정말로 기억할 수 없지만, 그것이 그렇게 복잡하다고 생각하지는 않습니다. 다이아몬드의 가장 가까운 구석에있는 운동 중입니다.
Neil

2

MATL , 39 38 35 바이트

t|Ekt_w&:2Z^tl2jYP3/*Zeh*!sbw6#YkY)

입력 형식은 6 + 14*1j공백입니다 (선택 사항). 출력 형식은 14 16입니다.

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

설명

코드는 먼저 입력을 복소수로 취합니다. 그런 다음 복잡한 평면에서 충분히 큰 육각형 격자를 생성하고 입력에 가장 가까운 점을 찾은 다음 아이젠 슈타인의 "좌표"를 반환합니다.

t         % Take input implicitly. This is the Gauss number, say A. Duplicate
|Ek       % Absolute value times two, rounded down
t_        % Duplicate and negate
w&:       % Range. This is one axis of Eisenstein coordinates. This will generate
          % the hexagonal grid big enough
2Z^       % Cartesian power with exponent 2. This gives 2-col 2D array, say B
t         % Duplicate
l         % Push 1
2jYP3/*   % Push 2*j*pi/3
Ze        % Exponential
h         % Concatenate. Gives [1, exp(2*j*pi/3)]
*         % Multiply by B, with broadcast.
!s        % Sum of each row. This is the hexagonal grid as a flattened array, say C
bw        % Bubble up, swap. Stack contains now, bottom to top: B, A, C
6#Yk      % Index of number in C that is closest to A
Y)        % Use as row index into B. Implicitly display

2

하스켈 , 128 바이트

i=fromIntegral;r=[floor,ceiling];a!k=(i a-k)**2;c(a,b)|l<-2*i b/sqrt 3,k<-i a+l/2=snd$minimum[(x k!k+y l!l,(x k,y l))|x<-r,y<-r]

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

입력 가우시안 정수 (a, b)의 경우,이를 아이젠 슈타인 좌표로 변환하고, 두 성분을 모두 바닥에 놓고 가장 가까운 아이젠 슈타인 정수에 대한 4 개의 후보를 구하고, 최소 거리를 가진 후보를 찾아 반환합니다.


1

TCL , 124 (116) 106 바이트

{{a b f\ int(floor(2*$b/3**.5)) {l "[expr $f+(1-$f%2<($b-$f)*3**.5)]"}} {subst [expr $l+$a-($f+1)/2]\ $l}}

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

이것은 @Neil의 3 살짜리 게시물에서 다소 영감을 얻었습니다.

ω

"대각선 d의 교차 곱 vxd 부호를 오른쪽 아래 모서리에 연결하는 벡터 v와 (a, b)"를 사용하여 대각선의 어느 쪽이 점인지에 대한 테스트로 10 바이트를 절약했습니다.


1

해 학적 인 , 24 바이트

pe@3r@2././J2./x/.+CL)R_

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

이것이 더 짧을 수 있음을 확신하십시오. 입력을 다음과 같이 읽습니다.a b

pe      # Parse input to two ints
@3r@2./ # sqrt(3)/2
./      # Divide b by sqrt(3)/2
J2./    # Duplicate and divide by 2
x/.+    # swap stack around and add to a
CL      # Collect the stack to a list
)R_     # Round to ints

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