J , 40 Bytes
2%~[:+/^:_]<:[:+/&.:*:"1[:-"1/~#~#:i.@^~
Probieren Sie es online aus!
Wird bei TIO für 5 eine Zeitüberschreitung auftreten, wenn Sie eine erweiterte Genauigkeit verwenden ( 5x
anstelle von 5
). Ich werde mich nicht die Mühe machen, es mit 6 auf meinem Computer zu versuchen, da dies den Interpreter zweifellos zum Absturz bringen wird.
Auf der Suche nach Ratschlägen zum Golfen, insbesondere nach dem Teil nach der Generierung der Koordinaten. Ich denke, es sollte eine Möglichkeit geben, einige der Kappen zu entfernen.
]<:[:+/&.:*:"1
kann äquivalent ersetzt werden durch *:<:[:+/"1[:*:
.
Erläuterung
Diese Erklärung erfolgt auf der REPL (drei Leerzeichen geben einen Befehl an, keine Leerzeichen geben eine Ausgabe an). Ich werde auf die Antwort aufbauen.
Koordinaten generieren
#~ #: i.@^~
gibt alle Koordinaten an, die uns auf dem Gitter wichtig sind.
^~
ist eine zu sich selbst erhobene Zahl und i.
gibt den Bereich [0, n) an, wobei n seine Eingabe ist. @
komponiert diese Funktionen.
i.@^~ 2
0 1 2 3
#~
kopiert eine Nummer selbst, z
#~ 3
3 3 3
#:
konvertiert sein rechtes Argument in die Basis, die durch das als linkes Argument angegebene Array angegeben wird. Die Anzahl der Stellen im Array entspricht der Anzahl der Stellen in dieser Basisausgabe (und Sie können eine gemischte Basis haben).
3 3 3 #: 0
0 0 0
5 5 #: 120
4 0
NB. If you want 120 base 5 use #.inv
#.inv 120
4 4 0
Alles in allem heißt das also, durch alle Wertebasis n (wobei n die Eingabe ist) bis n ^ n aufzählen und uns effektiv unsere Koordinaten geben.
(#~ #: i.@^~) 2
0 0
0 1
1 0
1 1
Ermitteln der Abstände zwischen jedem Paar
Zuerst nehmen wir die Differenz jeder Koordinate mit allen anderen unter Verwendung der /
Dyadentabelle und ~
-reflexiv. Beachten Sie, dass dies nicht die Tatsache berücksichtigt, dass die Reihenfolge für die Paare keine Rolle spielt: Dies erzeugt doppelte Abstände.
NB. 2 {. takes the first two elements (I'm omitting the rest).
2 {. -"1/~ (#~ #: i.@^~) 2
0 0
0 _1
_1 0
_1 _1
0 1
0 0
_1 1
_1 0
Dann verwenden wir dieses Verb +/&.:*:
für jede Koordinate (bei "1
, auch bekannt als Rang eins). Dieses Verb ist sum ( +/
) under ( &.:
) square ( *:
). Unter wendet das rechte Verb (Quadrat) an, sammelt dann seine Ergebnisse und gibt es als Argument für das linke Verb (Summe) an. Es wird dann die Umkehrung des rechten Verbs (das wäre Quadratwurzel) angewendet.
+/&.:*: 3 4
5
+/&.:*:"1 ([: -"1/~ #~ #: i.@^~) 2
0 1 1 1.41421
1 0 1.41421 1
1 1.41421 0 1
1.41421 1 1 0
Es überrascht nicht, dass viele Entfernungen gleich sind.
Zählen der Abstände, die größer oder gleich dem Eingang sind
Im letzten Teil wird geprüft, ob der Abstand größer oder gleich dem eingegebenen Wert ist ]<:
. Dann werden alle Ergebnisse mit +/^:_
(Summe bis Konvergenz) summiert , wobei die Anzahl der Wahrheitswerte gezählt wird. Dann wird dieser Wert durch 2 geteilt ( bedeutet 2%~
hier ~
, die Reihenfolge der Argumente zu vertauschen %
). Der Grund, warum wir durch 2 teilen können, ist, dass es für jede wahrheitsgemäße Paarung eine andere für die gespiegelte Reihenfolge gibt, außer für Paarungen, die eine Koordinate mit sich selbst sind. Das ist jedoch in Ordnung, da dies zu einem Abstand von 0 führt.