Gauss do Eisenstein

18

Biorąc pod uwagę liczbę całkowitą Gaussa gdzie , są liczbami całkowitymi, a jest jednostką urojoną, zwraca najbliższą (wrt na odległość euklidesową) liczbę całkowitą Eisensteina gdzie , są liczbami całkowitymi, a .a+biabi=exp(πi/2)k+lωklω=exp(2πi/3)=(1+i3)/2

tło

Jest prawdopodobnie całkiem oczywiste, że każdą liczbę całkowitą Gaussa można jednoznacznie zapisać jako z liczbami całkowitymi , . Nie jest to tak oczywiste, ale mimo to prawdziwe: każda liczba całkowita Eisensteina może być jednoznacznie zapisana jako z liczbami całkowitymi , . Oba tworzą moduł w obrębie liczb zespolonych i oba są p-tymi cyklotomicznymi liczbami całkowitymi odpowiednio dla lub . Zauważ, żea+biabk+lωklZp=233+2i3+2ω

Źródło: commons.wikimedia.org

Detale

  • W przypadku, gdy podana liczba zespolona ma dwa lub trzy najbliższe punkty, dowolny z nich można zwrócić.

  • Kompleks numer znajduje się w układzie współrzędnych prostokątnych (podstawa ), ale poza tym w dowolnej dogodnej postaci, jak i albo itp(1,i)(A,B)A+BiA+B*1j

  • Eisenstein całkowitą musi być zwrócony w współrzędnych podstawy , ale poza tym w każdej dogodnej postaci, jak i albo itp(1,ω)(K,L)K+LωK+L*1ω

Przykłady

Wszystkie prawdziwe liczby całkowite powinny oczywiście zostać ponownie zmapowane na rzeczywiste liczby całkowite.

  6,14 -> 14,16
  7,16 -> 16,18
-18,-2 ->-19,-2
 -2, 2 -> -1, 2
 -1, 3 -> 1, 4
wada
źródło
Fajnie, nie pamiętam, żeby widziałem sześciokątną siatkę od codegolf.stackexchange.com/q/70017/17602
Neil
Powiązane
Lynn,
Powinieneś również uwzględnić przypadki testowe, gdy aib mają przeciwne znaki.
SmileAndNod
@SmileAndNod Dodano jeden. Ale można również użyć symetrii w stosunku do osi rzeczywistej i po prostu zastąpić (1,w)(-1,1+w). Zmieniłem też nazwę tej sekcji na Przykłady, aby wyjaśnić, że nie wystarczy podać właściwe wyniki dla tych przypadków.
flawr

Odpowiedzi:

7

APL (Dyalog Extended) , 16 bajtów SBCS

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

Wypróbuj online!

Pełny program, który pobiera ynastępnie xze standardowego wejścia i drukuje 2-elementowy wektor liczb całkowitych.

Jak to działa: matematyka

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

Jak to działa: kod

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)]
Bubbler
źródło
2

JavaScript (ES6), 112 bajtów

(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 może oczywiście przyciąć 9 bajtów. Objaśnienie: ki lpoczątkowo reprezentuje rozwiązanie zmiennoprzecinkowe dla k+ωl=a+ib. Jednak współrzędne musiały zostać zaokrąglone do najbliższej liczby całkowitej o odległość euklidesową. I w związku z tym podjąć podłogę ki l, a następnie wykonać kilka testów na częściach ułamkowych do określenia, czy je zwiększając doprowadziłoby do punktu bliżej a+ib.

Neil
źródło
Chyba twoje testy na częściach ułamkowych wykorzystują faktów, że x jest zawsze 0,2887 lub 0.577and y jest zawsze albo 0,1547 lub 0,577
SmileAndNod
@SmileAndNod 3 lata temu? Naprawdę nie pamiętam, ale nie sądzę, żeby to było tak skomplikowane, po prostu pracuję, który jest najbliższym rogiem diamentu.
Neil,
2

MATL , 39 38 35 bajtów

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

Format wejściowy to 6 + 14*1j(spacja jest opcjonalna). Format wyjściowy to 14 16.

Wypróbuj online!

Wyjaśnienie

Kod najpierw przyjmuje dane wejściowe jako liczbę zespoloną. Następnie generuje wystarczająco dużą siatkę heksagonalną w złożonej płaszczyźnie, znajduje punkt najbliższy wejściowi i zwraca „współrzędne” Eisensteina.

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
Luis Mendo
źródło
2

Haskell , 128 bajtów

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]

Wypróbuj online!

Aby wprowadzić liczbę całkowitą Gaussa (a, b), przekonwertuj ją na współrzędne Eisensteina, podłogę i sufit obu komponentów, aby uzyskać czterech kandydatów na najbliższą liczbę całkowitą Eisensteina, znajdź tę z minimalną odległością i zwróć ją.

Sacchan
źródło
1

Tcl , 124 116 106 bajtów

{{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}}

Wypróbuj online!

Jest to nieco inspirowane trzyletnim postem z @Neil

ω

Zaoszczędzono 10 bajtów, używając „znaku iloczynu krzyżowego vxd przekątnej d z wektorem v łączącym prawy dolny róg i (a, b)” jako testu, po której stronie przekątnej leży punkt.

SmileAndNod
źródło
1

Burleska , 24 bajty

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

Wypróbuj online!

Jestem pewien, że może to być krótsze. Dane wejściowe czytane jakoa 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
DeathIncarnate
źródło