Mathematica, 111 105 104 Bytes
r=Floor[(1+Sqrt[(4#-1)/3])/2]&;t=Limit[Pi(#/(3x)+1-x),x->r@#]&;p=r@#*Exp[I*t@#]&;Round@Abs[p@#-p@#2]==1&
Erläuterung:
r=Floor[(1+Sqrt[(4#-1)/3])/2]&
definiert eine Funktion, r
die Eingaben entgegennimmt #
und die Entfernung (in Anzahl der Zellen) zu Zelle 0 berechnet. Hierzu wird das Muster in den letzten Zellen jeder Entfernung / jedes Rings ausgenutzt: 0 = 3 (0 ^ 2 + 0), 6 = 3 (1 ^ 2 + 1), 18 = 3 (2 ^ 2 + 2), 36 = 3 (3 ^ 2 + 3), ... und Invertieren der Formel für dieses Muster. Beachten Sie, dass für die Zelle 0 tatsächlich das Wort (1/2) + i * (sqrt (3) / 6) verwendet wird, das komponentenweise berechnet wird, um 0 + 0 * i = 0 zu erhalten.
Mit r
defined r@#
ist der Ring für cell #
(innerhalb der Definition einer anderen Funktion). #+3r@#-3(r@#)^2&
erscheint nicht genau im Code, sondern nimmt die Nummer einer Zelle und subtrahiert die höchste Nummer einer Zelle im nächsten inneren Ring, so dass die Antwort auf die Frage "Welche Zelle des aktuellen Rings ist das?" Zum Beispiel ist Zelle 9 die 3. Zelle von Ring 2, r[9]
würde also 2 ausgeben und #+3r@#-3(r@#)^2&[9]
würde 3 ausgeben.
Mit der obigen Funktion können wir den Polarwinkel und den Winkel gegen den Uhrzeigersinn vom Strahl "Zelle 0, Zelle 17, Zelle 58" zur betreffenden Zelle ermitteln. Die letzte Zelle jedes Rings befindet sich immer in einem Winkel Pi / 6, und wir gehen in Schritten von Pi / (3 * ring_number) um einen Ring herum. Theoretisch müssen wir also etwas wie Pi / 6 + (welche_Zelle_des_Current_Rings) * Pi / (3 * Ring_Nummer) berechnen. Die Drehung des Bildes hat jedoch keinen Einfluss darauf, sodass wir den Pi / 6-Teil verwerfen können (um 6 Bytes zu sparen). Wenn wir dies mit der vorherigen Formel kombinieren und vereinfachen, erhalten wirPi(#/(3r@#)+1-r@#)&
Leider ist dies für Zelle 0 undefiniert, da deren Ringnummer 0 ist. Daher müssen wir dies umgehen. Eine natürliche Lösung wäre so etwas wie t=If[#==0,0,Pi(#/(3r@#)+1-r@#)]&
. Da uns aber der Winkel für Zelle 0 egal ist und weil er r@#
wiederholt wird, können wir hier mit tatsächlich ein Byte speichernt=Limit[Pi(#/(3x)+1-x),x->r@#]&
Nun, da wir die Ringnummer und den Winkel haben, können wir die Position einer Zelle (Mitte) finden, um auf Nachbarschaft zu testen. Das Auffinden der tatsächlichen Position ist ärgerlich, da die Ringe sechseckig sind, aber wir können einfach so tun, als wären die Ringe perfekte Kreise, sodass wir die Ringnummer als den Abstand zum Zentrum von Zelle 0 behandeln. Dies ist kein Problem, da die Annäherung hübsch ist schließen. Mit der polaren Form einer komplexen Zahl können wir diese ungefähre Position in der komplexen Ebene mit einer einfachen Funktion darstellen:p = r@#*Exp[I*t@#] &;
Der Abstand zwischen zwei komplexen Zahlen auf der komplexen Ebene wird durch den absoluten Wert ihrer Differenz angegeben. Dann können wir das Ergebnis abrunden, um etwaige Fehler aus der Näherung zu beseitigen, und prüfen, ob diese gleich 1 sind. Die Funktion that finally hat diese Arbeit keinen Namen, ist aber Round@Abs[p@#-p@#2]==1&
.
Sie können es online in der Wolfram Cloud-Sandbox versuchen, indem Sie den folgenden Code einfügen und auf Zahnrad -> "Zelle auswerten" klicken oder Umschalt + Eingabetaste oder die Zifferntaste drücken:
r=Floor[(1+Sqrt[(4#-1)/3])/2]&;t=Limit[Pi(#/(3x)+1-x),x->r@#]&;p=r@#*Exp[I*t@#]&;Round@Abs[p@#-p@#2]==1&[24,45]
Oder für alle Testfälle:
r=Floor[(1+Sqrt[(4#-1)/3])/2]&;t=Limit[Pi(#/(3x)+1-x),x->r@#]&;p=r@#*Exp[I*t@#]&;Round@Abs[p@#-p@#2]==1&//MapThread[#,Transpose[{{0,1},{7,18},{8,22},{24,45},{40,64},{64,65},{6,57},{29,90},{21,38},{38,60},{40,63},{41,39},{40,40}}]]&