J , 40 bytes
2%~[:+/^:_]<:[:+/&.:*:"1[:-"1/~#~#:i.@^~
Experimente online!
O TIO atingirá o tempo limite de 5 se você usar precisão estendida (em 5x
vez de 5
). Não vou me incomodar em tentar com 6 no meu computador, pois isso sem dúvida trará o intérprete.
Procurando conselhos sobre golfe, especificamente a parte que passou após a geração das coordenadas. Eu sinto que deveria haver uma maneira de remover algumas das tampas.
]<:[:+/&.:*:"1
pode ser substituído equivalentemente por *:<:[:+/"1[:*:
.
Explicação
Esta explicação é feita no REPL (três espaços indicam um comando, nenhum espaço indica uma saída). Eu estarei construindo a resposta.
Gerando as coordenadas
#~ #: i.@^~
fornece todas as coordenadas com as quais nos preocupamos na treliça.
^~
é um número elevado a si mesmo e i.
fornece o intervalo [0, n) onde n é sua entrada. @
compõe essas funções.
i.@^~ 2
0 1 2 3
#~
copia um número sozinho, por exemplo
#~ 3
3 3 3
#:
converte seu argumento da direita na base especificada pela matriz fornecida como argumento da esquerda. O número de dígitos na matriz corresponde ao número de dígitos na saída base (e você pode ter uma base mista). Por exemplo,
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
Então, todos juntos, isso diz enumerar todos os valores base n (onde n é a entrada) até n ^ n, efetivamente fornecendo nossas coordenadas.
(#~ #: i.@^~) 2
0 0
0 1
1 0
1 1
Obtendo as distâncias entre cada par
Primeiro, tomamos a diferença de cada coordenada com todas as outras usando a díade /
-table e ~
-reflexive. Observe que isso não explica o fato de que a ordem não importa para os pares: isso gera distâncias 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
Em seguida, usamos esse verbo +/&.:*:
em cada coordenada (em "1
, também conhecido como um). Este verbo é soma ( +/
) sob ( &.:
) quadrado ( *:
). Sob aplica o verbo da direita (quadrado), em seguida, coleta seus resultados e o fornece como argumento para o verbo da esquerda (soma). Em seguida, aplica o inverso do verbo certo (que seria a raiz quadrada).
+/&.:*: 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
Sem surpresa, muitas distâncias são as mesmas.
Contando as distâncias maiores ou iguais à entrada
A última parte é ver se a distância é maior ou igual à entrada usada ]<:
. Em seguida, todos os resultados são somados usando +/^:_
(soma até convergir), contando o número de valores verdadeiros. Então esse valor é dividido por 2 ( 2%~
, aqui ~
significa trocar a ordem dos argumentos fornecidos %
). A razão pela qual podemos dividir por 2 é porque, para cada pareamento de verdade, haverá outro para a ordem invertida, exceto para os pares que são coordenados consigo. Tudo bem, porém, já que esses resultam em uma distância de 0.