Punti reticolari triangolari vicini all'origine


34

sfondo

Una griglia triangolare è una griglia formata piastrellando regolarmente il piano con triangoli equilateri di lunghezza laterale 1. L'immagine sotto è un esempio di griglia triangolare.

Un punto reticolare triangolare è un vertice di un triangolo che forma la griglia triangolare.

L' origine è un punto fisso sul piano, che è uno dei punti reticolari triangolari.

Sfida

Dato un numero intero non negativo n, trova il numero di punti reticolari triangolari la cui distanza euclidea dall'origine è minore o uguale a n.

Esempio

La seguente figura è un esempio di n = 7(mostrando per comodità solo un'area di 60 gradi, con l'origine del punto A):

Casi test

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

Suggerimento : questa sequenza non è OEIS A003215 .

Regole

Si applicano le regole standard per il . Vince l'invio più breve.

Ti preghiamo di includere come hai risolto la sfida nel tuo invio.


7
OEIS A053416 è la sequenza del numero di punti contenuti in un cerchio di diametro anziché in raggio n, quindi ha il doppio dei termini che desideri.
Neil,

Rilevanti Wikipedia e Mathworld . Contiene la formula di xnor e non la prova.
user202729

4
È la somma dei primi n^2+1termini di OEIS A004016 .
alephalpha,

Risposte:


49

Python 2 , 43 byte

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

Provalo online!

Questa è magia nera.

Offrendo 250 rappresentanti per una prova scritta. Vedila risposta di Lynnper una prova e una spiegazione.


7
Come funziona? Mi chiedo da 30 minuti ... Sembra così semplice ma non riesco a trovare una relazione tra quella ricorsione e gli ambienti ...
JungHwan Min

7
@JungHwanMin La mia dimostrazione è un viaggio epico attraverso la geometria piana, numeri interi di Eisenstein, fattorizzazione su campi numerici, reciprocità quadratica, progressioni aritmetiche e sommazioni intercambiabili, tutto per un'espressione così semplice. Scrivere tutto sarebbe una grande impresa che per il momento non ho tempo, quindi spero che qualcun altro ne dia una prova, probabilmente una più semplice della mia che chiarisca la connessione.
xnor

14
Prova . È più lungo di quello di Lynn ma più autonomo: non fa uso di affermazioni non comprovate sulla fattorizzazione sugli interi di Eisenstein.
Peter Taylor,

2
@PeterTaylor Cheddar Monk? Come in Darth e Droids?
Neil

3
@Neil, congratulazioni per essere la prima persona a chiedere! Ho registrato il dominio per usarlo come chip di contrattazione per Negoziazione, Livello 1 nell'Accademia.
Peter Taylor,

30

Haskell , 48 byte

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

Provalo online!

Utilizza la formula "magia nera" di xnor:

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

È possibile trovare una prova della sua correttezza e una spiegazione di come xnor è riuscito a esprimerlo in 43 byte di Python qui .

1Nn2N=(x+yω)(x+yω)(x,y)

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

1n2


4
Certamente non me l'aspettavo quando xnor ha detto "ci sono alcune profonde intuizioni matematiche dietro il golf del problema".
Bubbler,

29

Wolfram Language (Mathematica) , 53 51 50 byte

-1 byte grazie a @miles

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

Provalo online!

Come?

Invece di pensare in questo:

enter image description here

Pensalo in questo modo:

enter image description here

Quindi applichiamo la matrice [[sqrt(3)/2, 0], [1/2, 1]]di trasformazione per trasformare la seconda figura nella prima.

Quindi, dobbiamo trovare il cerchio nella griglia triangolare in termini di coordinate cartesiane.

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

Quindi troviamo punti reticolari x, ytali chex^2 + x y + y^2 <= r^2

Ad esempio, con r = 3:

enter image description here


1
Cordiali saluti, la formula x^2+x y+y^2può anche essere derivata dalla Legge dei Coseni con 120 gradi.
Bubbler,

3
x^2+x y+y^2-> x(x+y)+y^2salva un byte
miglia il

La formula x^2 + xy + y^2può anche essere derivata dalla norma di un intero di Eistenstein, che è a^2 - ab + b^2. Si noti che il segno di aed bè irrilevante tranne nel termine, abquindi ha la stessa quantità di soluzioni.
orlp,


7

CJam (24 byte)

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

Questo è un blocco (funzione) anonimo che accetta un argomento nello stack e lascia il risultato nello stack. Suite di test online . Si noti che i due casi più grandi sono troppo lenti.

Spiegazione

alephalpha notato in un commento sulla domanda che

È la somma dei primi n ^ 2 + 1 termini di OEIS A004016

e la risposta di xnor implementa questa somma (anche se non sono sicuro che la loro prova non pubblicata la usi esplicitamente) come

f(n)=1+6Σun'=0n23un'+1-n23un'+2

La mia prova di correttezza di quella formula si basa su alcune informazioni raccolte dal link OEIS di alephalpha:

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

per il quale il riferimento rilevante è l'articolo di Hirschhorn. Una dimostrazione elementare è possibile utilizzando nient'altro che una comprensione di base di numeri complessi (radici cubiche di unità, grandezza), il concetto di generazione di funzioni, la derivata diXun'e la regola a catena della differenziazione. In sintesi, proviamo innanzitutto dai primi principi l'identità del triplo prodotto Jacobi

k=0(1qk+1)(1+xqk+1)(1+x1qk)=kZqk(k+1)/2xk
That then bootstraps a proof that
m,nZωmnqm2+mn+n2=k=1(1qk)31q3k
where ω is a primitive cube root of unity. The final big step is to use this to show that
m,nZqm2+mn+n2=1+6k0(q3k+11q3k+1q3k+21q3k+2)

Code dissection

{          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
}

4

J, 27 bytes

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

Try it online!

Based on JungHwan Min's method.

Explanation

[:+/@,*:>:(*++&*:)"{~@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



3

Jelly,  15  13 bytes

-2 thanks to Dennis (just increment the square to avoid concatenation of a zero; avoid head by using a post-difference modulo-slice rather than a pre-difference slice)

Uses the "black magic" method of honing in on the answer that was exposed by xnor in their Python answer, but uses iteration rather than recursion (and a little less calculation)

²:Ѐ‘$Im3S×6C

A monadic link accepting a non-negative integer and returning a positive integer.

Try it online! Or see the test-suite.

How?

²:Ѐ‘$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

2

JavaScript (ES6), 65 bytes

This is a port of @JungHwanMin's solution.

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))

Try it online!


Original answer (ES7), 70 bytes

Simply walks through the grid and counts the matching points.

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))

Try it online!


Porting xnor's answer is shorter: 42 bytes (outputs true instead of 1; 46 if we also integer-divide it). And I don't know JavaScript well enough to golf the integer-divisions ~~(a/b), but I'm sure there is a shorter way for those as well..
Kevin Cruijssen


1

Pari/GP, 42 bytes

Using the built-in qfrep.

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

qfrep(q,B,{flag=0}): vector of (half) the number of vectors of norms from 1 to B for the integral and definite quadratic form q. If flag is 1, count vectors of even norm from 1 to 2B.

Try it online!


0

C# (Visual C# Interactive Compiler), 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);}

Try it online!

Same as everyone else, unfortunately. I know there's probably a better way of writing this, but declaring and calling a lambda at the same time in c# is not exactly something I do, well, ever. Though in my defense, I can't think of a good reason (outside code golf, of course) to do so. Still, if someone knows how you can do this, let me know and/or steal the credit, I guess.



0

05AB1E, 15 bytes

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

Port of @JonathanAllans Jelly answer, which in turn is a derivative from @xnor's 'black magic' formula.

Try it online or verify all test cases.

Explanation:

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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.