Puntos triangulares de celosía cerca del origen

34

Fondo

Una cuadrícula triangular es una cuadrícula formada al enlosar el plano regularmente con triángulos equiláteros de longitud lateral 1. La siguiente imagen es un ejemplo de una cuadrícula triangular.

Un punto reticular triangular es un vértice de un triángulo que forma la cuadrícula triangular.

los origen es un punto fijo en el plano, que es uno de los puntos reticulares triangulares.

Reto

Dado un número entero no negativo n, encuentre el número de puntos reticulares triangulares cuya distancia euclidiana desde el origen es menor o igual quen .

Ejemplo

La siguiente figura es un ejemplo para n = 7(que muestra solo un área de 60 grados por conveniencia, siendo el punto A el origen):

Casos de prueba

Input | Output
---------------
    0 |       1
    1 |       7
    2 |      19
    3 |      37
    4 |      61
    5 |      91
    6 |     127
    7 |     187
    8 |     241
    9 |     301
   10 |     367
   11 |     439
   12 |     517
   13 |     613
   14 |     721
   15 |     823
   16 |     931
   17 |    1045
   18 |    1165
   19 |    1303
   20 |    1459
   40 |    5815
   60 |   13057
   80 |   23233
  100 |   36295
  200 |  145051
  500 |  906901
 1000 | 3627559

Sugerencia : esta secuencia no es OEIS A003215 .

Reglas

Reglas estándar para el . La presentación más corta gana.

Incluya cómo resolvió el desafío en su envío.

Bubbler
fuente
77
OEIS A053416 es la secuencia del número de puntos contenidos en un círculo de diámetro en lugar de radio n, por lo que tiene el doble de términos que desee.
Neil
Wikipedia y Mathworld relevantes . Contiene la fórmula de xnor y no prueba.
user202729
44
Es la suma de los primeros n^2+1términos de OEIS A004016 .
alephalpha

Respuestas:

49

Python 2 , 43 bytes

f=lambda n,a=1:n*n<a/3or n*n/a*6-f(n,a+a%3)

Pruébalo en línea!

Esto es magia negra.

Ofreciendo 250 repeticiones para una prueba escrita. Veala respuesta de Lynnpara una prueba y explicación.

xnor
fuente
77
¿Como funciona esto? Me he estado preguntando durante unos 30 minutos ... Parece muy simple, pero no puedo encontrar una relación entre esa recursión y los círculos ...
JungHwan Min
77
@JungHwanMin Mi prueba es un viaje épico a través de la geometría plana, enteros de Eisenstein, factorización sobre campos numéricos, reciprocidad cuadrática, progresiones aritméticas y suma de intercambios, todo para una expresión tan simple. Escribirlo todo sería una tarea importante para la que no tengo tiempo por ahora, así que espero que alguien más dé una prueba, probablemente una más simple que la mía que aclare la conexión.
xnor
14
Prueba . Esto es más largo que el de Lynn pero más autónomo: no hace uso de afirmaciones no comprobadas sobre la factorización sobre los enteros de Eisenstein.
Peter Taylor
2
@PeterTaylor Monje Cheddar? Como en Darths y Droids?
Neil
3
@Neil, ¡felicidades por ser la primera persona en preguntar! Registré el dominio para usarlo como moneda de cambio para Negociación, Nivel 1 en la Academia.
Peter Taylor
30

Haskell , 48 bytes

f n=1+6*sum[(mod(i+1)3-1)*div(n^2)i|i<-[1..n^2]]

Pruébalo en línea!

Utiliza la fórmula de "magia negra" de xnor:

f(n)=1+6a=0n23a+1n23a+2

Aquí puede encontrar una prueba de su corrección y una explicación de cómo xnor logró expresarlo en 43 bytes de Python .

Larga historia corta: contamos los enteros de Eisenstein de la norma , factorizando N = ( x + y ω ) ( x + y1Nn2 ennúmeros primos de Eisensteiny contando cuántas soluciones para ( x , y ) salen de la factorización. Reconocemos que el número de soluciones es igual anorte=(X+yω)(X+yω)(X,y)

6×((# of divisors of N1 (mod 3))(# of divisors of N2 (mod 3)))

y aplique un truco inteligente para que sea realmente fácil de calcular para todos los enteros entre y n 2 a la vez. Esto produce la fórmula anterior. Finalmente, aplicamos un poco de magia de golf de Python para terminar con la solución realmente pequeña que xnor encontró.1n2

Lynn
fuente
44
Ciertamente no esperaba esto cuando Xnor dijo "hay algunas ideas matemáticas profundas detrás del problema del golf".
Bubbler
29

Wolfram Language (Mathematica) , 53 51 50 bytes

-1 byte gracias a @miles

Sum[Boole[x(x+y)+y^2<=#^2],{x,-2#,2#},{y,-2#,2#}]&

Pruébalo en línea!

¿Cómo?

En lugar de pensar en esto:

ingrese la descripción de la imagen aquí

Piensa en esto, de esta manera:

ingrese la descripción de la imagen aquí

Entonces aplicamos la matriz de transformación [[sqrt(3)/2, 0], [1/2, 1]] de transformación para transformar la segunda figura en la primera.

Luego, debemos encontrar el círculo en la cuadrícula triangular en términos de coordenadas cartesianas.

(sqrt(3)/2 x)^2 + (1/2 x + y)^2 = x^2 + x y + y^2

Entonces encontramos puntos de red x, ytales quex^2 + x y + y^2 <= r^2

Por ejemplo, con r = 3:

ingrese la descripción de la imagen aquí

JungHwan Min
fuente
1
Para su información, la fórmula x^2+x y+y^2también se puede derivar de la Ley de cosenos con 120 grados.
Bubbler
3
x^2+x y+y^2-> x(x+y)+y^2guarda un byte
millas
La fórmula x^2 + xy + y^2también se puede derivar de la norma de un entero Eistenstein, que es a^2 - ab + b^2. Tenga en cuenta que el signo de ay bes irrelevante, excepto en el término, abpor lo que tiene la misma cantidad de soluciones.
orlp
7

CJam (24 bytes)

{_*_,f{)_)3%(@@/*}1b6*)}

Este es un bloque anónimo (función) que toma un argumento en la pila y deja el resultado en la pila. Conjunto de pruebas en línea . Tenga en cuenta que los dos casos más grandes son demasiado lentos.

Explicación

alephalpha señaló en un comentario sobre la pregunta que

Es la suma de los primeros n ^ 2 + 1 términos de OEIS A004016

F(norte)=1+6 6una=0 0norte23una+1-norte23una+2

Mi prueba de exactitud de esa fórmula se basa en cierta información obtenida del enlace OEIS de alephalpha:

Gf: 1 + 6 * Suma_ {n> = 1} x ^ (3 * n-2) / (1-x ^ (3 * n-2)) - x ^ (3 * n-1) / (1- x ^ (3 * n-1)). - Paul D. Hanna, 03 jul 2011

Xuna

k=0 0(1-qk+1)(1+Xqk+1)(1+X-1qk)=kZqk(k+1)/ /2Xk
Eso luego prueba una prueba de que
metro,norteZωmetro-norteqmetro2+metronorte+norte2=k=1(1-qk)31-q3k
dónde ωes una raíz cúbica primitiva de la unidad. El gran paso final es usar esto para mostrar que
metro,norteZqmetro2+metronorte+norte2=1+6 6k0 0(q3k+11-q3k+1-q3k+21-q3k+2)

Disección de código

{          e# Define a block. Stack: ... r
  _*       e#   Square it
  _,f{     e#   Map with parameter: invokes block for (r^2, 0), (r^2, 1), ... (r^2, r^2-1)
    )      e#     Increment second parameter. Stack: ... r^2 x with 1 <= x <= r^2
    _)3%(  e#     Duplicate x and map to whichever of 0, 1, -1 is equal to it (mod 3)
    @@/*   e#     Evaluate (r^2 / x) * (x mod 3)
  }
  1b6*     e#   Sum and multiply by 6
  )        e#   Increment to count the point at the origin
}
Peter Taylor
fuente
4

J , 27 bytes

[:+/@,*:>:(*++&*:)"{~@i:@+:

Pruébalo en línea!

Basado en el método de JungHwan Min .

Explicación

[:+/@,*:>:(*++&*:)"{~@i:@+:  Input: n
                         +:  Double
                      i:     Range [-2n .. 2n]
                  "{~        For each pair (x, y)
                *:             Square both x and y
              +                Add x^2 and y^2
             +                 Plus
            *                  Product of x and y
        >:                   Less than or equal to
      *:                     Square of n
     ,                       Flatten
  +/                         Reduce by addition
millas
fuente
3

Gelatina ,  15  13 bytes

-2 gracias a Dennis (solo incremente el cuadrado para evitar la concatenación de un cero; evite la cabeza utilizando un módulo de corte posterior a la diferencia en lugar de un corte previo a la diferencia)

Utiliza el método de "magia negra" para perfeccionar la respuesta que fue expuesta por xnor en su respuesta de Python , pero usa iteración en lugar de recursión (y un poco menos de cálculo)

²:Ѐ‘$Im3S×6C

Un enlace monádico que acepta un entero no negativo y devuelve un entero positivo.

Pruébalo en línea! O vea el conjunto de pruebas .

¿Cómo?

²:Ѐ‘$Im3S×6C - Main Link: non-negative integer, n     e.g. 7
²             - square                                     49
     $        - last two links as a monad:
    ‘         -   increment                                50
  Ѐ          -   map across (implicit range of) right with:
 :            -     integer division                       [49,24,16,12,9,8,7,6,5,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0]
      I       - incremental differences                    [-25,-8,-4,-3,-1,-1,-1,-1,-1,0,0,-1,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1]
       m3     - every third element                        [-25,-3,-1,0,0,-1,0,0,0,0,0,0,0,0,0,0,-1]
         S    - sum (vectorises)                           -31
          ×6  - multiply by six                           -186
            C - complement (1-X)                           187
Jonathan Allan
fuente
2

JavaScript (ES6), 65 bytes

Este es un puerto de la solución de @ JungHwanMin .

f=(n,y=x=w=n*2)=>y-~w&&(x*x+x*y+y*y<=n*n)+f(n,y-=--x<-w&&(x=w,1))

Pruébalo en línea!


Respuesta original (ES7), 70 bytes

Simplemente camina por la cuadrícula y cuenta los puntos coincidentes.

f=(n,y=x=n*=2)=>y+n+2&&(x*x*3+(y-x%2)**2<=n*n)+f(n,y-=--x<-n&&(x=n,2))

Pruébalo en línea!

Arnauld
fuente
La respuesta de portar xnor es más corta: 42 bytes (salidas en truelugar de 1; 46 si también lo dividimos en enteros). Y no conozco JavaScript lo suficientemente bien como para jugar golf en las divisiones de enteros ~~(a/b), pero estoy seguro de que también hay un camino más corto para ellos ...
Kevin Cruijssen
1

Pari / GP , 42 bytes

Usando el incorporado qfrep.

n->1+2*vecsum(Vec(qfrep([2,1;1,2],n^2,1)))

qfrep (q, B, {flag = 0}): vector de (mitad) el número de vectores de normas de 1 a B para la forma cuadrática integral y definida q. Si el indicador es 1, cuente los vectores de la norma par de 1 a 2B.

Pruébalo en línea!

alephalpha
fuente
0

C # (compilador interactivo de Visual C #) , 68 bytes

n=>{int g(int x,int y)=>x*x<y/3?1:x*x/y*6-g(x,y+y%3);return g(n,1);}

Pruébalo en línea!

Igual que todos los demás, por desgracia. Sé que probablemente hay una mejor manera de escribir esto, pero declarar y llamar a una lambda al mismo tiempo en C # no es exactamente algo que hago, bueno, nunca. Aunque en mi defensa, no puedo pensar en una buena razón (fuera del código de golf, por supuesto) para hacerlo. Aún así, si alguien sabe cómo puede hacer esto, hágamelo saber y / o robe el crédito, supongo.

Andrew Baumher
fuente
0

05AB1E , 15 bytes

nD>L÷¥ā3%ÏO6*±Ì

Puerto de la respuesta Jelly de @JonathanAllan , que a su vez es un derivado de la fórmula de 'magia negra' de @ xnor .

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

n                # Square the (implicit) input-integer
 D>              # Duplicate it, and increase the copy by 1
   L             # Create a list in the range [1, input^2+1]
    ÷            # Integer divide input^2 by each of these integers
     ¥           # Take the deltas
      ā          # Push a list in the range [1, length] without popping the deltas itself
       3%        # Modulo each by 3
         Ï       # Only leave the values at the truthy (==1) indices
          O      # Take the sum of this list
           6*    # Multiply it by 6
             ±   # Take the bitwise NOT (-n-1)
              Ì  # And increase it by 2
                 # (after which the result is output implicitly)
Kevin Cruijssen
fuente