计数单位平方圆通过


24

写一个程序或函数给定的整数半径ř回报单元的方格数与半径的圆周ř以原点为中心穿过。如果圆正好通过网格上的一个点,该点不算作通过相邻单位正方形的点。

这是r = 5的图示:

插图 Kival Ngaokrajang的插图,可在OEIS上找到

例子:

0→0
1→4
4→28
5→28
49→388
50 →380325
→2540
5524→44180
5525→44020



@Luke我只是去寻找它,但是它似乎使用了稍微不同的定义(至少在上不一致N = 50)。
Martin Ender

1
@smls通过计算边界正方形。确保您不计算圆形仅接触角的正方形。OEIS上的数字有误,我现在要进行更正。
orlp

2
我突然渴望再次在Minecraft中建立圆顶...
Patrick Roberts

2
您是3Blue1Brown的同伴吗?
nitro2k01 '01

Answers:


12

Python 2,54个字节

f=lambda r,x=0:r-x and-~((r*r-x*x)**.5%1>0)*4+f(r,x+1)

在线尝试!

少打高尔夫球(55字节)(TIO

lambda r:8*r-4*sum((r*r-x*x)**.5%1==0for x in range(r))

这会将输出估计为8*r,然后校正顶点交叉。结果为8*r-g(r*r),其中将写入方式g(x)数量x计算为两个平方之和(除外g(0)=0)。

如果圆从不经过任何顶点,则触摸的像元数将等于交叉的边数。圆通过2*r垂直网格线和2*r水平网格线,并沿两个方向分别通过,总共为8*r

但是,在顶点处的每个交叉仅当进入一个新像元时才算作两个边缘交叉。因此,我们通过减去顶点交叉的数量来进行补偿。这包括对轴的点像(r,0)以及勾股数等(4,3)r=5

我们指望单个象限点(x,y)x>=0y>0x*x+y*y==n,然后乘以4.我们通过计数NUMER做到这一点sqrt(r*r-x*x),对于在整数x的区间[0,r)


5

Mathematica,48个字节

4Count[Range@#~Tuples~2,l_/;Norm[l-1]<#<Norm@l]&

查看第一个象限,并计算输入落在该单元的左下角和右上角的范式之间的网格单元数(当然,将结果乘以4)。


另一种方法8#-SquaresR[2,#^2]Sign@#&基于xnor的帖子
英里

@miles哇,我没有任何线索SquaresR。随意自己张贴(或让xnor发布)。
马丁·恩德


3

果冻21 13 12 11字节

R²ạ²Æ²SạḤ×4

在线尝试!

怎么运行的

R²ạ²Æ²SạḤ×4  Main link. Argument: r

R            Range; yield [1, 2, ..., r].
 ²           Square; yield [1², 2², ..., r²].
   ²         Square; yield r².
  ạ          Absolute difference; yield [r²-1², r²-2², ..., r²-r²].
    Ʋ       Test if each of the differences is a perfect square.
      S      Sum, counting the number of perfect squares and thus the integer
             solutions of the equation x² + y² = r² with x > 0 and y ≥ 0.
        Ḥ    Un-halve; yield 2r.
       ạ     Subtract the result to the left from the result to the right.
         ×4  Multiply by 4.

2

Perl 6,61位元组

->\r{4*grep {my &n={[+] $_»²};n(1 X+$_)>r²>.&n},(^r X ^r)}

怎么运行的

->\r{                                                    } # Lambda (accepts the radius).
                                                (^r X ^r)  # Pairs from (0,0) to (r-1,r-1),
                                                           #   representing the bottom-left
                                                           #   corners of all squares in
                                                           #   the top-right quadrant.
       grep {                                 }            # Filter the ones matching:
             my &n={[+] $_»²};                             #   Lambda to calculate the norm.
                              n(1 X+$_)>r²                 #   Top-right corner is outside,
                                          >.&n             #   and bottom-left is inside.
     4*                                                    # Return length of list times 4.

1

AWK,90个字节

{z=$1*$1
for(x=$1;x>=0;x--)for(y=0;y<=$1;y++){d=z-x*x-y*y
if(d>0&&d<2*(x+y)+2)c++}$0=4*c}1

用法:

awk '{z=$1*$1
    for(x=$1;x>=0;x--)for(y=0;y<=$1;y++){d=z-x*x-y*y
    if(d>0&&d<2*(x+y)+2)c++}$0=4*c}1' <<< 5525

只需通过象限1进行简单搜索,即可找到将与圆相交的所有框。对称性允许乘以4。可以从开始-$1 to $1,但是会占用更多字节,效率更低。显然,这并不是算法最省时的方法,但是在我的计算机上运行5525案例仅花费大约16秒。


1

Haskell,74个字节

f n=sum[4|x<-[0..n],y<-[0..n],(1+n-x)^2+(1+n-y)^2>n^2,(n-x)^2+(n-y)^2<n^2]

非常简单,计算(0,0)和(n,n)之间的平方数,其中左下角在圆内,右上角在圆外,然后乘以4。


0

Pyth,29个字节

Lsm*ddb*4lf}*QQrhyTym+1dT^UQ2

试试吧!

说明

Lsm*ddb*4lf}*QQrhyTym+1dT^UQ2  # implicit input: Q
Lsm*ddb                        # define norm function
 s                             # sum
  m   b                        #     map each coordinate to
   *dd                         #                            its square
                         ^UQ2  # cartesian square of [0, 1, ..., Q - 1]
                               #     -> list of coordinates of all relevant grid points
          f                    # filter the list of coordinates T where:
           }*QQ                # square of Q is in
               r               #     the range [
                hyT            #         1 + norm(T),
                               #                  ^ coordinate of lower left corner
                   ym+1dT      #         norm(map({add 1}, T))
                               #              ^^^^^^^^^^^^^^^ coordinate of upper right corner
                               #     ) <- half-open range
         l                     # size of the filtered list
                               #     -> number of passed-through squares in the first quadrant
       *4                      # multiply by 4
                               # implicit print

0

批次,147个字节

@set/an=0,r=%1*%1
@for /l %%i in (0,1,%1)do @for /l %%j in (0,1,%1)do @set/a"i=%%i,j=%%j,a=i*i+j*j-r,i+=1,j+=1,a&=r-i*i-j*j,n-=a>>31<<2
@echo %n%

受到AWK和Haskell答案的启发。


很高兴我可以启发某人:)
罗伯特·本森

0

Bash + Unix实用程序,127字节

c()(d=$[(n/r+$1)**2+(n%r+$1)**2-r*r];((d))&&echo -n $[d<0])
r=$1
bc<<<`for((n=0;n<r*r;n++));{ c 0;c 1;echo;}|egrep -c 01\|10`*4

在线尝试!

只需遍历第一象限中的所有点,对它们进行计数,然后乘以4。这可能很慢,但是可以。


0

JavaScript(ES7),76个字节

n=>4*(G=k=>k<n?Math.ceil((n**2-k++**2)**0.5)-(0|(n**2-k**2)**0.5)+G(k):0)(0)

您是否可以通过从ndown 递归到来减少几个字节0
尼尔

@Neil我确实尝试过,但看不到办法。想要只使用一个函数,但仍然需要存储n半径和k迭代,并且所有尝试都出自相同的字节
George Reith,2017年

@Neil啊,我明白您在说什么,k<n?...但是我失去了那些字节的重新排序,n**2-k++**2因为在进行反向运算时运算符优先级是错误的,并且减法是不可交换的,因此左侧总是需要有k-1括号。除非您找到方法?
乔治·里斯

啊,我忽略了减法...也许您可以将整个数乘以-4而不是4来解决这个问题?(尽管那可能仍会累死您的储蓄...)
Neil
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.