靠近原点的三角格点


34

背景

三角形网格是由边长为1的等边三角形定期平铺的平面形成一个网格下面的图片是一个三角形的网格的例子。

三角晶格点是一个三角形形成三角格子的一个顶点。

原点是在平面上,这是三角晶格点中的一个固定点。

挑战

给定一个非负整数n,请找出其与原点的欧几里得距离小于或等于的三角形格点的数量n

下图是一个示例n = 7(为方便起见,仅显示60度区域,以A点为原点):

测试用例

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

提示:该序列不是 OEIS A003215

规则

适用于标准规则。提交时间最短者获胜。

请在提交的内容中包括您如何解决挑战。


7
OEIS A053416直径圆而不是半径中包含的点数的顺序,因此项的数量是所需数量的n两倍。
尼尔

相关维基百科Mathworld。包含xnor的公式而不是证明。
user202729 '18

4
它是OEIS A004016的第一n^2+1条款的总和
alephalpha '18年

Answers:


49

Python 2,43个字节

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

在线尝试!

这是黑魔法。

提供250份书面证明。有关证明和解释,请参见Lynn的答案


7
这是如何运作的?我一直想知道有30分钟的时间...看起来很简单,但是我找不到递归和圈子之间的关系...
JungHwan Min

7
@JungHwanMin我的证明是穿越平面几何,爱森斯坦整数,因数域分解,二次对等,算术级数和求和求和的史诗般的旅程-所有这些都是如此简单的表达。编写所有内容将是我目前没有时间的一项重大任务,因此我希望其他人能够提供证明,可能是一个更简单的证明,可以使连接更清晰。
xnor

14
证明。这比Lynn的更长,但是更独立:它不使用关于Eisenstein整数的因式分解的未经验证的断言。
彼得·泰勒

2
@PeterTaylor切达僧侣?像《达斯与机器人》中一样?
尼尔

3
@Neil,恭喜您成为第一个问到的人!我注册了该域,以将其用作学院一级“谈判”的筹码。
彼得·泰勒

30

Haskell,48个字节

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

在线尝试!

使用xnor的“黑魔法”公式:

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

可以在此处找到有关其正确性的证明,以及有关xnor如何设法用Python的43个字节表示它的说明。

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

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

1n2


4
当xnor说“打高尔夫球的问题背后有一些深刻的数学见解”时,我当然没想到这一点。
冒泡者

29

Wolfram语言(Mathematica)53 51 50字节

-1个字节感谢@miles

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

在线尝试!

怎么样?

而不是这样思考:

在此处输入图片说明

这样想:

在此处输入图片说明

因此,我们应用[[sqrt(3)/2, 0], [1/2, 1]]变形矩阵将第二个图形转换为第一个图形。

然后,我们必须根据笛卡尔坐标在三角形网格中找到圆。

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

因此我们发现格点x, y,使得x^2 + x y + y^2 <= r^2

例如,使用r = 3

在此处输入图片说明


1
仅供参考,该公式x^2+x y+y^2也可以从120度余弦定律得出。
Bubbler '18

3
x^2+x y+y^2-> x(x+y)+y^2保存一个字节
英里

该公式x^2 + xy + y^2也可以从Eistenstein整数(即)的范数中得出a^2 - ab + b^2。需要注意的是的符号ab无关除了在长期ab所以它有解决方案的相同。
orlp


7

CJam(24字节)

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

这是一个匿名块(函数),它在堆栈上接受一个参数,并将结果保留在堆栈上。在线测试套件。请注意,两个最大的情况太慢。

说明

Alephalpha在对以下问题的评论中指出:

它是的前n ^ 2 + 1个项的总和 OEIS A004016总和

Fñ=1个+6一种=0ñ23一种+1个-ñ23一种+2

我对该公式的正确性的证明是基于从alephalpha的OEIS链接中获得的一些信息:

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),2011年7月3日

X一种

ķ=01个-qķ+1个1个+Xqķ+1个1个+X-1个qķ=ķžqķķ+1个/2Xķ
ñžω-ñq2+ñ+ñ2=ķ=1个1个-qķ31个-q3ķ
ω
ñžq2+ñ+ñ2=1个+6ķ0q3ķ+1个1个-q3ķ+1个-q3ķ+21个-q3ķ+2

代码剖析

{          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个字节

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

在线尝试!

基于郑焕敏的 方法

说明

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

果冻 15  13 字节

多亏了丹尼斯(Dennis)-2(只需增加平方即可避免串联零;通过使用差分后的模片而不是差分前的片来避免磁头)

使用xnor在其Python答案中公开的答案上磨练“黑魔法”方法,但使用迭代而不是递归(并且计算量少一些)

²:Ѐ‘$Im3S×6C

单子链接接受非负整数并返回正整数。

在线尝试!或查看测试套件

怎么样?

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

这是@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))

在线尝试!


原始答案(ES7),70个字节

只需遍历网格并计算匹配点即可。

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

在线尝试!


移植xnor的答案更短:42个字节(如果我们也将其整数除,则输出true1; 而不是46)。而且我对JavaScript不够了解,无法理解整数除法~~(a/b),但是我敢肯定,对于这些整数除法,还有一种更短的方法。
凯文Cruijssen


1

巴黎/ GP,42字节

使用内置的qfrep

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

qfrep(q,B,{flag = 0}):向量的(一半)为整数和定二次数q的从1到B的范数的向量。如果flag为1,则计数从1到2B的偶范数的向量。

在线尝试!


0

C#(Visual C#交互式编译器),68字节

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

在线尝试!

不幸的是,和其他所有人一样。我知道可能有更好的方式编写此代码,但是在c#中同时声明和调用lambda并不是我所做的任何事情,好吧,永远。尽管为我辩护,但我想不出这样做的充分理由(当然是高尔夫之外的理由)。不过,我想,如果有人知道您该怎么做,请告诉我和/或窃取信用。



0

05AB1E,15 个字节

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

@JonathanAllan的Jelly答案的端口,它反过来又是@xnor的“黑魔法”公式的衍生形式。

在线尝试验证所有测试用例

说明:

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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.