整数の半径rが与えられ、原点を中心とする半径rの円が通る単位平方の数を返すプログラムまたは関数を記述します。円が、隣接する単位正方形を通過するものとしてカウントされないグリッド上のポイントを正確に通過する場合。
r = 5の例を示します。
Kival Ngaokrajangによるイラスト、OEISで発見
例:
0→0
1→4
4→28
5→28
49→388
50→380
325→2540
5524→44180
5525→44020
N = 50
)。
整数の半径rが与えられ、原点を中心とする半径rの円が通る単位平方の数を返すプログラムまたは関数を記述します。円が、隣接する単位正方形を通過するものとしてカウントされないグリッド上のポイントを正確に通過する場合。
r = 5の例を示します。
Kival Ngaokrajangによるイラスト、OEISで発見
例:
0→0
1→4
4→28
5→28
49→388
50→380
325→2540
5524→44180
5525→44020
N = 50
)。
回答:
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)
、2つの正方形の合計として書く方法g(x)
の数をx
カウントします(を除くg(0)=0
)。
円が頂点を通過しなかった場合、タッチされたセルの数は、交差したエッジの数に等しくなります。円が通過する2*r
垂直グリッド線と2*r
の合計で、両方向にそれぞれを通過し、水平グリッド線8*r
。
ただし、頂点での各交差は2つのエッジ交差としてカウントされますが、新しいセルは1つしか入力されません。したがって、頂点の交差の数を引くことで補正します。これには、などの軸上の点と、のような(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)
。
lambda n:sum(0<n*n-x*x-y*y<2*(x-~y)for x in range(n)for y in range(n))*4
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
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を掛けます。非常に遅くなる可能性がありますが、機能します。
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
まで0
?
n
半径とk
反復の両方を保存する必要があり、すべての試行が同じバイトであった
k<n?...
であるn**2-k++**2
ため、バイトの並べ替えで負けていk-1
ます。方法を見つけていない限り?