写一个程序或函数给定的整数半径ř回报单元的方格数与半径的圆周ř以原点为中心穿过。如果圆正好通过网格上的一个点,该点不算作通过相邻单位正方形的点。
这是r = 5的图示:
Kival Ngaokrajang的插图,可在OEIS上找到
例子:
0→0
1→4
4→28
5→28
49→388
50 →380325
→2540
5524→44180
5525→44020
N = 50
)。
写一个程序或函数给定的整数半径ř回报单元的方格数与半径的圆周ř以原点为中心穿过。如果圆正好通过网格上的一个点,该点不算作通过相邻单位正方形的点。
这是r = 5的图示:
Kival Ngaokrajang的插图,可在OEIS上找到
例子:
0→0
1→4
4→28
5→28
49→388
50 →380325
→2540
5524→44180
5525→44020
N = 50
)。
Answers:
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>=0
和y>0
带x*x+y*y==n
,然后乘以4.我们通过计数NUMER做到这一点sqrt(r*r-x*x)
,对于在整数x
的区间[0,r)
。
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.
->\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.
{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秒。
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。
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
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)
n
down 递归到来减少几个字节0
?
n
半径和k
迭代,并且所有尝试都出自相同的字节
k<n?...
但是我失去了那些字节的重新排序,n**2-k++**2
因为在进行反向运算时运算符优先级是错误的,并且减法是不可交换的,因此左侧总是需要有k-1
括号。除非您找到方法?