Dreieckige Gitterpunkte in der Nähe des Ursprungs


34

Hintergrund

Ein Dreiecksgitter ist ein Gitter, bei dem die Ebene regelmäßig mit gleichseitigen Dreiecken der Seitenlänge 1 gekachelt wird. Das folgende Bild zeigt ein Beispiel für ein Dreiecksgitter.

Ein dreieckiger Gitterpunkt ist ein Eckpunkt eines Dreiecks, das das Dreiecksgitter bildet.

Der Ursprung ist ein fester Punkt in der Ebene, der einer der dreieckigen Gitterpunkte ist.

Herausforderung

Bestimmen Sie bei einer nicht negativen ganzen Zahl ndie Anzahl der dreieckigen Gitterpunkte, deren euklidischer Abstand vom Ursprung kleiner oder gleich ist n.

Beispiel

Die folgende Abbildung ist ein Beispiel dafür n = 7(sie zeigt der Einfachheit halber nur einen 60-Grad-Bereich, wobei Punkt A der Ursprung ist):

Testfälle

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

Hinweis : Diese Sequenz ist nicht OEIS A003215 .

Regeln

Es gelten die Standardregeln für . Die kürzeste Einsendung gewinnt.

Bitte geben Sie an, wie Sie die Herausforderung gelöst haben.


7
OEIS A053416 ist die Folge der Anzahl von Punkten, die in einem Kreis mit Durchmesser und nicht mit Radius enthalten nsind. Sie enthält also doppelt so viele Begriffe wie Sie möchten.
Neil

Relevante Wikipedia und Mathworld . Enthält die Formel von xnor und keinen Beweis.
user202729

4
Es ist die Summe der ersten n^2+1Begriffe von OEIS A004016 .
Alephalpha

Antworten:


49

Python 2 , 43 Bytes

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

Probieren Sie es online!

Das ist schwarze Magie.

Bietet 250 Wiederholungen für einen schriftlichen Nachweis. SieheLynns Antwortfür einen Beweis und eine Erklärung.


7
Wie funktioniert das? Ich frage mich seit gut 30 Minuten ... Es sieht so einfach aus, aber ich kann keine Beziehung zwischen dieser Rekursion und Kreisen finden ...
JungHwan Min

7
@JungHwanMin Mein Beweis ist eine epische Reise durch Ebenengeometrie, Eisenstein-Ganzzahlen, Faktorisierung über Zahlenfelder, quadratische Reziprozität, arithmetische Progressionen und vertauschende Summierungen - alles für einen so einfachen Ausdruck. Das alles zu schreiben, wäre ein großes Unterfangen, für das ich momentan keine Zeit habe, also hoffe ich, dass jemand anderes einen Beweis liefert, wahrscheinlich einen einfacheren, der die Verbindung klarer macht.
xnor

14
Beweis . Dies ist länger als bei Lynn, aber in sich geschlossener: Es werden keine unbewiesenen Aussagen über die Faktorisierung über die Eisenstein-Ganzzahlen verwendet.
Peter Taylor

2
@PeterTaylor Cheddar Monk? Wie bei Darths & Droids?
Neil

3
@Neil, herzlichen Glückwunsch zu deiner ersten Frage! Ich habe die Domain registriert, um sie als Verhandlungschip für Level 1 der Akademie zu verwenden.
Peter Taylor

30

Haskell , 48 Bytes

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

Probieren Sie es online!

Verwendet die "schwarze Magie" -Formel von xnor:

f(n)=1+6ein=0n23ein+1-n23ein+2

Ein Beweis für seine Richtigkeit und eine Erklärung, wie xnor es geschafft hat, es in 43 Bytes Python auszudrücken, finden Sie hier .

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

6×((Anzahl der Teiler von N1 (mod 3))-(Anzahl der Teiler von N2 (mod 3)))

1n2


4
Ich habe das sicherlich nicht erwartet, als xnor sagte "es gibt einige tiefe mathematische Einsichten hinter dem Golfspielen des Problems".
Bubbler

29

Wolfram Language (Mathematica) , 53 51 50 Bytes

-1 Byte dank @miles

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

Probieren Sie es online!

Wie?

Anstatt daran zu denken:

Bildbeschreibung hier eingeben

Stellen Sie es sich so vor:

Bildbeschreibung hier eingeben

Wir wenden also die Transformationsmatrix [[sqrt(3)/2, 0], [1/2, 1]]an, um die zweite Figur in die erste zu transformieren.

Dann müssen wir den Kreis im Dreiecksgitter in kartesischen Koordinaten finden.

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

Also finden wir Gitterpunkte x, yso, dassx^2 + x y + y^2 <= r^2

Zum Beispiel mit r = 3:

Bildbeschreibung hier eingeben


1
FYI, die Formel x^2+x y+y^2kann auch aus dem Kosinussatz mit 120 Grad abgeleitet werden.
Bubbler

3
x^2+x y+y^2-> x(x+y)+y^2spart ein Byte
Meilen

Die Formel x^2 + xy + y^2kann auch aus der Norm einer Eistenstein-Ganzzahl abgeleitet werden a^2 - ab + b^2. Beachten Sie, dass das Vorzeichen von aund baußer im Begriff irrelevant ist, absodass es die gleiche Anzahl von Lösungen gibt.
Orlp


7

CJam (24 Bytes)

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

Dies ist ein anonymer Block (eine Funktion), der ein Argument auf dem Stapel nimmt und das Ergebnis auf dem Stapel belässt. Online-Testsuite . Beachten Sie, dass die beiden größten Fälle zu langsam sind.

Erläuterung

alephalpha stellte in einem Kommentar zur Frage fest, dass

Es ist die Summe der ersten n ^ 2 + 1 Terme von OEIS A004016

f(n)=1+6ein=0n23ein+1-n23ein+2

Mein Beweis für die Richtigkeit dieser Formel basiert auf einigen Informationen, die ich über den OEIS-Link von alephalpha erhalten habe:

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

xein

k=0(1-qk+1)(1+xqk+1)(1+x-1qk)=kZqk(k+1)/2xk
m,nZωm-nqm2+mn+n2=k=1(1-qk)31-q3k
ω
m,nZqm2+mn+n2=1+6k0(q3k+11-q3k+1-q3k+21-q3k+2)

Code-Zerlegung

{          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:@+:

Probieren Sie es online!

Basierend auf der Methode von JungHwan Min .

Erläuterung

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

-2 dank Dennis (erhöhe einfach das Quadrat, um die Verkettung einer Null zu vermeiden; vermeide den Kopf, indem du ein Post-Differenz-Modulo-Slice anstelle eines Pre-Differenz-Slice verwendest)

Verwendet die "schwarze Magie" -Methode, um die von xnor in ihrer Python-Antwort offen gelegte Antwort zu verfeinern , verwendet jedoch Iteration anstelle von Rekursion (und etwas weniger Berechnung).

²:Ѐ‘$Im3S×6C

Eine monadische Verknüpfung, die eine nicht negative Ganzzahl akzeptiert und eine positive Ganzzahl zurückgibt.

Probieren Sie es online! Oder schauen Sie sich die Testsuite an .

Wie?

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

Dies ist ein Port der @ JungHwanMin-Lösung .

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

Probieren Sie es online!


Ursprüngliche Antwort (ES7), 70 Bytes

Geht einfach durch das Gitter und zählt die passenden Punkte.

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

Probieren Sie es online!


Die Antwort von xnor ist kürzer: 42 Bytes (Ausgaben truestatt 1; 46, wenn wir es auch ganzzahlig teilen). Und ich kenne JavaScript nicht gut genug, um die Integer-Divisionen zu spielen ~~(a/b), aber ich bin sicher, dass es auch für diese einen kürzeren Weg gibt.
Kevin Cruijssen


1

Pari / GP , 42 Bytes

Verwendung des eingebauten qfrep.

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

qfrep (q, B, {flag = 0}): Vektor der (halben) Anzahl von Vektoren der Normen von 1 bis B für die ganzzahlige und bestimmte quadratische Form q. Wenn flag 1 ist, werden Vektoren mit gerader Norm von 1 bis 2B gezählt.

Probieren Sie es online!


0

C # (Visual C # Interactive Compiler) , 68 Byte

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

Probieren Sie es online!

Wie alle anderen auch, leider. Ich weiß, dass es wahrscheinlich eine bessere Möglichkeit gibt, dies zu schreiben, aber das gleichzeitige Deklarieren und Aufrufen eines Lambda in c # ist nicht genau das, was ich tue, naja, jemals. Obwohl mir zu meiner Verteidigung kein guter Grund einfällt (natürlich außerhalb von Code Golf), dies zu tun. Wenn dennoch jemand weiß, wie Sie dies tun können, lassen Sie es mich wissen und / oder stehlen Sie das Guthaben, denke ich.



0

05AB1E , 15 Bytes

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

Port of @JonathanAllans Jelly-Antwort , die wiederum eine Ableitung von @ xnors 'black magic'-Formel ist .

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

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)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.