J , 40 bytes
2%~[:+/^:_]<:[:+/&.:*:"1[:-"1/~#~#:i.@^~
Pruébalo en línea!
Se agota el tiempo de espera en TIO por 5 si usa precisión extendida (en 5x
lugar de 5
). No me voy a molestar en probar con 6 en mi computadora, ya que eso sin duda bloqueará al intérprete.
Buscando consejos sobre golf, específicamente la parte pasada la generación de las coordenadas. Siento que debería haber una manera de eliminar algunas de las tapas.
]<:[:+/&.:*:"1
puede ser reemplazado de manera equivalente por *:<:[:+/"1[:*:
.
Explicación
Esta explicación se realiza en REPL (tres espacios indican un comando, ningún espacio indica una salida). Estaré preparando la respuesta.
Generando las coordenadas
#~ #: i.@^~
da todas las coordenadas que nos interesan en la red.
^~
es un número elevado a sí mismo y i.
da el rango [0, n) donde n es su entrada. @
compone esas funciones.
i.@^~ 2
0 1 2 3
#~
copia un número por sí mismo, p. ej.
#~ 3
3 3 3
#:
convierte su argumento derecho en la base especificada por la matriz dada como argumento izquierdo. El número de dígitos en la matriz corresponde al número de dígitos en esa salida base (y puede tener una base mixta) Por ejemplo,
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
Entonces, en conjunto, esto dice enumerar a través de todos los valores base n (donde n es la entrada) hasta n ^ n, dándonos efectivamente nuestras coordenadas.
(#~ #: i.@^~) 2
0 0
0 1
1 0
1 1
Obtener las distancias entre cada par
Primero tomamos la diferencia de cada coordenada con todas las demás usando la tabla de díadas /
y el ~
reflejo. Tenga en cuenta que esto no explica el hecho de que el orden no importa para los pares: esto genera distancias duplicadas.
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
Luego usamos este verbo +/&.:*:
en cada coordenada (en "1
, también conocido como rango uno). Este verbo es sum ( +/
) bajo ( &.:
) cuadrado ( *:
). Under aplica el verbo derecho (cuadrado), luego recoge sus resultados y lo da como argumento del verbo izquierdo (suma). Luego aplica el inverso del verbo derecho (que sería la raíz cuadrada).
+/&.:*: 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
Como era de esperar, muchas distancias son iguales.
Contando las distancias mayores o iguales a la entrada
La última parte es ver si la distancia es mayor o igual que la entrada usando ]<:
. Luego, todos los resultados se suman usando +/^:_
(suma hasta converger), contando el número de valores verdaderos. Luego, este valor se divide por 2 ( 2%~
aquí ~
significa intercambiar el orden de los argumentos suministrados %
). La razón por la que podemos dividir entre 2 es porque para cada emparejamiento verdadero, habrá otro para el orden invertido, excepto para los emparejamientos que son una coordenada consigo mismo. Sin embargo, está bien, ya que darán como resultado una distancia de 0.