Triângulos inteiros com perímetro menor que n

13

Definição

Um "triângulo inteiro" é aquele com coordenadas inteiras. Por exemplo, o triângulo a seguir é um triângulo inteiro:

(0, 0), (0, 1), (1, 2) with perimeter 1 + sqrt(2) + sqrt(5) ≈ 4.650.

Tarefa

O objetivo deste desafio é contar todos os triângulos inteiros (até congruência) com perímetro menor que n.

Entrada e saída

O argumento será fornecido como um número inteiro e a saída deve ser o número de triângulos com perímetro estritamente menor que o argumento.

Exemplos

O menor triângulo inteiro por perímetro é congruente para

(0, 0), (0, 1), (1, 0) which has perimeter 2 + sqrt(2) ≈ 3.414

Os próximos menores são:

(0, 0), (0, 1), (1, 2) with perimeter 1 + sqrt(2) + sqrt(5) ≈ 4.650,
(0, 0), (0, 2), (1, 1) with perimeter 2 + 2sqrt(2)          ≈ 4.828,
(0, 0), (0, 2), (1, 0) with perimeter 3 + sqrt(5)           ≈ 5.236, and
(0, 0), (1, 2), (2, 1) with perimeter sqrt(2) + 2sqrt(5)    ≈ 5.886

Casos de teste:

a(1) = 0
a(2) = 0
a(3) = 0
a(4) = 1
a(5) = 3
a(6) = 5
a(7) = 11
a(8) = 18
a(9) = 29
a(10) = 44
a(12) = 94
a(20) = 738
a(30) = 3756
a(40) = 11875

Eu tenho coordenadas para cada um dos triângulos nesta Gist .

Advertências

Observe que dois triângulos não congruentes podem ter o mesmo perímetro:

(0, 0), (0, 3), (3, 0) and (0, 0), (0, 1), (3, 4) both have perimeter 6 + 3sqrt(2).

Também tenha em mente que a desigualdade é estrita ; o triângulo pitagórico 3-4-5 deve ser contado por um (13), não um (12).

Pontuação

Isto é - o código mais curto vence!

Peter Kagey
fonte
4
Parabéns por encontrar uma sequência de fácil descrição que não está no OEIS.
AdmBorkBork 12/01
1
Eu tenho um rascunho para uma sequência relacionada enviada ao OEIS.
Peter Kagey 12/01/19
1
(0, 0), (0, 1), (1, 0) tem perímetro 2 + sqrt (2) ≈ 3,14
gggg
1
Sim, triângulos degenerados como (0,0), (1,1), (2,2) não são contados.
Peter Kagey
1
A entrada pode ser um valor inteiro em um tipo de ponto flutuante ou também deve ser do tipo integral?
Οurous

Respostas:

7

Geléia , 28 27 25 23 bytes

pḶŒcÆḊÐfḅı;I$€AṢ€QS€<¹S

Experimente online!

Como funciona

pḶŒcÆḊÐfḅı;I$€AṢ€QS€<¹S  Main link. Argument: n

 Ḷ                       Unlength; yield [0,...,n-1].
p                        Take the Cartesian product of [1,...,n] and [0,...,n-1].
  Œc                     Take all combinations of the resulting pairs.
                         The result are of the form [[a, b], [c, d]].
    ÆḊÐf                 Filter by determinant; keep only pairs of pairs for which
                         the determinant (ad - bc) is non-zero, i.e., those such
                         that [0, 0], [a, b], and [c, d] are not collinear.
        ḅı               Convert each pair [a, b] from base i (imaginary unit) to
                         integer, mapping it to ai + b.
             €           For each pair of complex numbers [p, q]: 
          ;I$              append their forward differences, yielding [p, q, p-q].
              A          Take the absolute value of each resulting complex number.
               Ṣ€        Sort each resulting array of side lengths.
                 Q       Unique; remove duplicates.
                  S€     Take the sum of each array, computing the perimeters.
                    <¹   Compare them with n.
                      S  Take the sum of the resulting Booleans.
Dennis
fonte
4

Geléia ,  38  33 bytes

-1 graças a Erik the Outgolfer (inverter SP¬+÷/E$usando SẠ>÷/E$e usar em ÇÐfvez de ÇÐḟ) -1 graças ao Sr. Xcoder (não há necessidade de achatar antes da classificação)
-2 graças ao Sr. Xcoder ( S<¥Ðf³L-> S€<³S)
-1 roubando um truque de uma revisão anterior da resposta de Dennis ( ṗ2’Œc-> p`⁺’- casos mais redundantes, mas mais golfista!)

SẠ>÷/E$
p`⁺’ÇÐfµ_/ṭ⁸²S€Ṣµ€Q½S€<³S

Um programa completo que pega um número inteiro e imprime o resultado.

Experimente online!(muito lento para concluir os casos de teste acima de 20 anos abaixo dos 60 anos)

Quão?

SẠ>÷/E$ - Link 1, straightLineFromOrigin?: coordinates       i.e. [[a,b],[c,d]]
S       - sum                                                     [a+c,b+d]
 Ạ       - all? (0 if either of a+c or b+d are 0 otherwise 1)      all([a+c,b+d])
      $ - last two links as a monad:
   ÷/   -   reduce by division                                    [a÷c,b÷d]
     E  -   all equal?  (i.e. 1 if on a non-axial straight line)  a÷c==b÷d 
  >     - greater than? (i.e. 1 if not on any line, 0 otherwise)  all([a+c,b+d])>(a÷c==b÷d)

p`⁺’ÇÐḟµ_/ṭ⁸²S€Ṣµ€Q½S€<³S - Main link: integer, n
p`                        - Cartesian product of implicit range(n) with itself
  ⁺                       - repeat (Cartesian product of that result with itself)
   ’                      - decrement (vectorises)
                          -  - i.e. all non-negative lattice point pairs up to x,y=n-1
     Ðf                   - filter keep only if:
    Ç                     -   call last link (1) as a monad
       µ         µ€       - monadic chain for €ach:
        _/                -   reduce with subtraction i.e. [a-c,b-d]
           ⁸              -   chain's left argument, [[a,b],[c,d]]
          ṭ               -   tack                   [[a,b],[c,d],[c-a,d-b]]
            ²             -   square (vectorises)    [[a²,b²],[c²,d²],[(c-a)²,(d-b)²]]
             S€           -   sum €ach               [[a²+b²],[c²+d²],[(c-a)²+(d-b)²]]
                          -    - i.e. the squares of the triangle's edge lengths
               Ṣ          -   sort
                  Q       - de-duplicate (get one of each congruent set of triangles)
                   ½      - square root (vectorises)  - get sides from squares of sides
                    S€    - sum €ach
                       ³  - program's 3rd argument, n
                      <   - less than?
                        S -   sum (number of such triangles)
                          - implicit print
Jonathan Allan
fonte
Correções de explicações: [(a+c)×(b+d)]-> (a+c)×(b+d), [c÷a,d÷b]-> [a÷c,b÷d],c÷a==d÷b -> a÷c==b÷d, " c÷a==d÷b-> " a÷c==b÷d. Função .
Erik the Outgolfer
Além disso, bom abuso de nan.
Erik the Outgolfer
Obrigado. Infelizmente, ele ainda precisa SP¬e não abusa realmente da divisão por zero resultados (acho que isso pode ser explícito com um valor real ou) #
9136 Jonathan Allan
1
Na verdade, você pode substituir ¬+por< . (EDIT: você não precisa substituí-lo Ppor , como você está usando apenas coordenadas não-negativas.)
Erik the Outgolfer
Isso não funciona ( 7retornos 21por exemplo)
Jonathan Allan
3

JavaScript (ES7), 157 bytes

f=(n,i=n**4,o={})=>i--&&([p,P,q,Q]=[0,1,2,3].map(k=>i/n**k%n|0),!o[k=[a=(H=Math.hypot)(p,P),b=H(p-q,P-Q),c=H(q,Q)].sort()]&a+b+c<n&&(o[k]=P*q!=p*Q))+f(n,i,o)

Casos de teste

Somente valores pequenos podem ser calculados com o tamanho da pilha padrão da maioria dos mecanismos JS.


Versão não recursiva, 165 bytes

n=>[...Array(n**4)].reduce((x,_,i,o)=>x+=!o[[p,P,q,Q]=[0,1,2,3].map(k=>i/n**k%n|0),k=[a=(H=Math.hypot)(p,P),b=H(p-q,P-Q),c=H(q,Q)].sort()]&(o[k]=P*q!=p*Q)&a+b+c<n,0)

Casos de teste

Essa versão também funciona para um (30) e um (40) , mas isso levaria muito tempo para o snippet.

Arnauld
fonte
2

Julia 0.6 , 135 bytes

Faça uma iteração sobre possíveis pontos não originários para formar o triângulo, represente-os como números complexos, classifique os comprimentos dos quadrados e mantenha-os em um conjunto para verificar se há congruência. Evita pontos colineares, verificando se o ângulo entre seus números complexos é diferente de zero. Em seguida, ele retorna o comprimento do conjunto. É mais curto usar os comprimentos diretamente, mas você obtém a resposta errada paraa(40) . A solução é lenta demais para ser executada a(40)devido a um aviso de descontinuação, por isso também tenho um link para uma versão mais rápida.

n->(q=Set();for x=0:n,y=1:n,a=1:n,b=0:n
r=x+y*im
t=a+b*im
g=sort(abs2.([r,t,r-t]))
sum(√g)<n&&angle(r/t)>0&&push!(q,g)
end;length(q))

Experimente online!

Versão mais rápida e mais longa, com obsoleta evitação. Experimente online! Usa sqrt.(g)no lugar de obsoleto √gpara raiz quadrada elementar.

gggg
fonte
1

Limpo , 227 ... 143 bytes

import StdEnv
@n#l=[0.0..n]
=sum[1\\p<-removeDup[sort(map(sqrt o\[u,v]=u*u+v*v)[[a-i,b-j],[a,b],[i,j]])\\a<-l,b<-l,i<-l,j<-l|a*j<>i*b]|sum p<n]

Experimente online!

Detecta triângulos congruentes comparando os três valores que somam para formar o perímetro e pontos colineares, verificando se os dois menores valores não somam ao terceiro.

Aqui está uma versão que usa uma abordagem mais rápida e com mais memória: Experimente online!

Furioso
fonte
Se eu mudar para Start = @ 12.0Não recebo saída, estou fazendo algo errado?
precisa saber é
1
Teste agora o conteúdo do seu coração
@gggg