高斯飞往爱森斯坦


18

给定一个高斯整数,其中,是整数,并且是虚数单位,返回最接近的(爱荷华氏距离的wrt)爱森斯坦整数其中,是整数,。a+biabi=exp(πi/2)k+lωklω=exp(2πi/3)=(1+i3)/2

背景

很明显,每个高斯整数可以唯一地用,整数表示为。它不是那么明显,但仍然如此:任何艾森斯坦整数能唯一被写为与,整数。它们都形成复数内的 -模数,并且分别是或的第p个环原子整数。注意a+biabk+lωklZp=233+2i3+2ω

资料来源:commons.wikimedia.org

细节

  • 如果给定的复数具有两个或三个最接近的点,则可以返回任何一个。

  • 复数以直角坐标(bass)给出,但不是以任何方便的格式(例如或或类似形式)给出。(1,i)(A,B)A+BiA+B*1j

  • 爱森斯坦整数必须作为基数坐标返回但不是以任何方便的格式(如or 或etc)返回。(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



@Neil从那时起已经有三个人了。;)
马丁·恩德

当a和b的符号相反时,还应包括测试用例。
SmileAndNod

@SmileAndNod添加了一个。但是,也可以只使用相对于实轴的对称性,并替换(1,w)(-1,1+w)。并且我还将本节重命名为“ 示例”,以表明仅为这些情况提供正确的结果是不够的。
瑕疵的

Answers:


7

APL(Dyalog扩展),16字节SBCS

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

在线尝试!

一个完整的程序,y然后x从标准输入中获取并打印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

JavaScript(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。但是,需要将坐标四舍五入到欧几里德距离。因此,我对kl进行了讨论,然后对小数部分执行一些测试,以确定增加它们是否会导致更接近a+ib


我猜想您对小数部分的测试将利用x始终为.2887或0.577而y始终为.1547或.577的事实
SmileAndNod

@SmileAndNod 3年前?我真的不记得了,但是我不认为这那么复杂,我只是在计算哪个是钻石的最近角。
尼尔,

2

MATL39 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

Haskell,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),将其转换为Eisenstein坐标,floor和ceil两个分量,以获得四个最接近Eisenstein整数的候选,找到距离最小的整数并将其返回。


1

TCL124个 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三年来的启发

floor函数返回菱形的角,其边缘是向量1和。关于此菱形,高斯整数位于顶部(如果l为偶数)或底部(如果l为奇数)的垂直双扇区上。这很重要,因为这意味着左下角或右上角都是可接受的解决方案。我计算左下角的k,然后做一个测试,看高斯整数是位于分隔两个角的对角线的上方还是下方。当对角线上方时,我将k加1,对l同样如此。ω

通过使用“对角线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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.