J , 40 octets
2%~[:+/^:_]<:[:+/&.:*:"1[:-"1/~#~#:i.@^~
Essayez-le en ligne!
Expirera sur TIO pendant 5 si vous utilisez une précision étendue ( 5x
au lieu de 5
). Je ne vais pas prendre la peine d'essayer avec 6 sur mon ordinateur car cela va sans doute planter l'interprète.
Vous cherchez des conseils sur le golf, en particulier la partie après la génération des coordonnées. Je pense qu'il devrait y avoir un moyen de retirer certains des bouchons.
]<:[:+/&.:*:"1
peut être remplacé de manière équivalente par *:<:[:+/"1[:*:
.
Explication
Cette explication se fait sur le REPL (trois espaces indiquent une commande, aucun espace n'indique une sortie). Je vais construire la réponse.
Génération des coordonnées
#~ #: i.@^~
donne toutes les coordonnées qui nous intéressent sur le réseau.
^~
est un nombre élevé à lui-même et i.
donne la plage [0, n) où n est son entrée. @
compose ces fonctions.
i.@^~ 2
0 1 2 3
#~
copie un numéro seul, par exemple
#~ 3
3 3 3
#:
convertit son argument droit en la base spécifiée par le tableau donné comme argument gauche. Le nombre de chiffres du tableau correspond au nombre de chiffres de cette sortie de base (et vous pouvez avoir une base mixte). Par exemple,
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
Donc, tous ensemble, cela dit énumérer à travers toutes les valeurs de base n (où n est l'entrée) jusqu'à n ^ n, nous donnant effectivement nos coordonnées.
(#~ #: i.@^~) 2
0 0
0 1
1 0
1 1
Obtention des distances entre chaque paire
D'abord, nous prenons la différence de chaque coordonnée avec toutes les autres en utilisant la dyade /
-table et ~
-reflexive. Notez que cela ne tient pas compte du fait que l'ordre n'a pas d'importance pour les paires: cela génère des distances en double.
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
Ensuite, nous utilisons ce verbe +/&.:*:
sur chaque coordonnée (at "1
, aka rang un). Ce verbe est sum ( +/
) sous ( &.:
) square ( *:
). Under applique le verbe droit (carré) puis recueille ses résultats et le donne comme argument au verbe gauche (somme). Il applique ensuite l'inverse du verbe droit (qui serait racine carrée).
+/&.:*: 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
Sans surprise, de nombreuses distances sont les mêmes.
Comptage des distances supérieures ou égales à l'entrée
La dernière partie consiste à voir si la distance est supérieure ou égale à l'entrée utilisant ]<:
. Ensuite, tous les résultats sont additionnés à l'aide de +/^:_
(somme jusqu'à convergence), en comptant le nombre de valeurs véridiques. Ensuite, cette valeur est divisée par 2 ( 2%~
, ici ~
signifie échanger l'ordre des arguments fournis à %
). La raison pour laquelle nous pouvons diviser par 2 est parce que pour chaque appariement véridique, il y en aura un autre pour l'ordre inversé, sauf pour les appariements qui sont une coordonnée avec lui-même. C'est ok, cependant, car ceux-ci entraîneront une distance de 0.