カウント単位の正方形の円が通過する


24

整数の半径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



@Luke私はこれを探しに行ったところですが、少し異なる定義を使用しているようです(少なくとも同意していませんN = 50)。
マーティンエンダー

1
@smls境界の正方形を数えることにより。円が角だけに触れる正方形を数えないことを確認してください。OEISの数値は間違っています。現在、レビューを修正しています。
orlp

2
私は再びMinecraftの中でビルドドームへの突然の衝動を持っている...
パトリック・ロバーツ

2
あなたは仲間の3Blue1Brown視聴者ですか?
nitro2k01

回答:


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)2つの正方形の合計として書く方法g(x)数をxカウントします(を除くg(0)=0)。

円が頂点を通過しなかった場合、タッチされたセルの数は、交差したエッジの数に等しくなります。円が通過する2*r垂直グリッド線と2*rの合計で、両方向にそれぞれを通過し、水平グリッド線8*r

ただし、頂点での各交差は2つのエッジ交差としてカウントされますが、新しいセルは1つしか入力されません。したがって、頂点の交差の数を引くことで補正します。これには、などの軸上の点と、のような(r,0)ピタゴラスのトリプルが含ま(4,3)r=5ます。

我々は、単一の象限のためのポイントをカウント(x,y)してx>=0y>0してx*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を掛けます)。


もう1つの方法は8#-SquaresR[2,#^2]Sign@#&、xnorの投稿に基づいています
マイル

@マイルああすごい、手掛かり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)

あなたは、おそらくから再帰的でバイトのカップルをオフに剃ることができますnまで0
ニール

@Neil試しましたが、方法がわかりませんでした。1つの関数のみを使用したかったが、n半径とk反復の両方を保存する必要があり、すべての試行が同じバイトであった
ジョージリース

@Neil Ahあなたが言っていることはわかりますが、逆に行くと演算子の優先順位が間違っており、減算が非可換であるため、左側に常に括弧が必要であり、必要k<n?...であるn**2-k++**2ため、バイトの並べ替えで負けていk-1ます。方法を見つけていない限り?
ジョージリース

ああ、私は減算を見落としていました...多分あなたはそれを回避するために4の代わりに-4を掛けることができますか?(それでもあなたの貯蓄に食い込むかもしれませんが...)
ニール
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.