Birim kareler sayıyor daire geçiyor


24

Verilen bir tamsayıdır yarıçapı bir program ya da işlev Yazın r döner birim kare sayısı yarıçapı ile daire r orijinde merkezli geçer. Daire tam olarak ızgaradaki, bitişik birim karelerden geçen sayılmayan bir noktadan geçerse.

R = 5 için örnek :

örnekleme Çizim OEIS bulunan Kival Ngaokrajang tarafından

Örnekler:

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



@Luke Sadece bunu aramaya başladım, fakat biraz farklı bir tanım kullanıyor gibi görünüyor (en azından aynı fikirde değil N = 50).
Martin Ender

1
@smls Sınırlayıcı karede sayarak. Dairenin yalnızca bir köşeye temas ettiği kareleri saymadığınızdan emin olun. OEIS üzerindeki rakamlar yanlış, şu anda incelemede bir düzeltmem var.
orlp

2
Tekrar Minecraft'ta kubbeler inşa etmek için ani bir dürtü duyuyorum ...
Patrick Roberts

2
Bir arkadaş 3Blue1Brown izleyici misiniz?
nitro2k01

Yanıtlar:


12

Python 2 , 54 bayt

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

Çevrimiçi deneyin!

Daha az golf oynadı (55 bayt) ( TIO )

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

Bu, çıktıyı şu şekilde tahmin eder 8*r, sonra köşe geçişlerini düzeltir. Sonucudur 8*r-g(r*r)nerede, g(x)sayar yollardan sayısı yazmak için xiki kare toplamı olarak (hariç g(0)=0).

Daire hiç bir tepe noktasından geçmediyse, dokunulan hücre sayısı, geçen kenarların sayısına eşittir. Daire , her biri her iki yönde de toplam olarak geçen 2*rdikey kılavuz çizgileri ve 2*ryatay kılavuz çizgileri arasından geçer 8*r.

Ancak, bir köşedeki her geçiş sadece bir yeni hücreye girerken iki kenar geçişi olarak sayılır. Bu nedenle, köşe geçişlerinin sayısını çıkararak telafi ediyoruz. Bu eksenler üzerinde noktalar gibi içermektedir (r,0)Pisagor gibi üç katına yanı sıra (4,3)için r=5.

Tek bir kadran için noktaları (x,y)ile x>=0ve y>0ile x*x+y*y==n, sonra da 4 ile çarpın. Sayıları , aralıktaki sqrt(r*r-x*x)sayının tam sayısını sayarak yaparız .x[0,r)


5

Mathematica, 48 bayt

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

İlk çeyreğe bakar ve girişin hücrenin sol alt ve sağ üst köşelerinin normları arasına girdiği ızgara hücrelerinin sayısını sayar (sonucu 4 ile çarpılır).


Başka bir yöntem de 8#-SquaresR[2,#^2]Sign@#&xnor'ın mesajına dayanmaktadır
mil

@miles Oh vay, hiçbir fikrim yoktu SquaresR. Kendiniz yayınlamaktan çekinmeyin (veya xnor'ın göndermesine izin verin).
Martin Ender


3

Jelly , 21 13 12 11 bayt

R²ạ²Æ²SạḤ×4

Çevrimiçi deneyin!

Nasıl çalışır

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 bayt

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

Nasıl çalışı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 bayt

{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

Kullanımı:

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

Çember kesişecek tüm kutuları bulmak için sadece 1. kadran arasında basit bir arama. Simetri, 4'le çarpmaya izin verir. Bundan kaynaklanabilir -$1 to $1, ancak bu daha fazla bayt alır ve daha az verimli olur. Açıkçası, bu algoritmalar için en verimli zaman değil, ancak 5525 kasasını makinemde çalıştırmak yaklaşık 16 saniye sürüyor.


1

Haskell, 74 bayt

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]

Oldukça basit, sol alt dairenin içinde ve sağ üst dairenin dışında olduğu yerde (0,0) ve (n, n) arasındaki kareleri sayın, ardından 4 ile çarpın.


0

Pyth , 29 bayt

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

Dene!

açıklama

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

Toplu iş, 147 bayt

@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 ve Haskell cevaplarından biraz esinlendi.


Birine ilham verebildiğime sevindim :)
Robert Benson

0

Bash + Unix yardımcı programları, 127 bayt

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

Çevrimiçi deneyin!

Sadece ilk kadrandaki tüm noktaları gözden geçirin, sayın ve 4 ile çarpın. Çok yavaş olabilir, ama işe yarıyor.


0

JavaScript (ES7), 76 bayt

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)

Belki bir kaç bayttan naşağıya doğru özyinleştirerek tıraş olabilir misiniz 0?
Neil

@Neil Denedim ama bir yol göremedim. Sadece bir işlev kullanmak istedi, ancak yine de nyarıçapı ve kyinelemeyi saklamak gerekiyor ve tüm denemeler aynı byte çıktı
George Reith,

@Neil Ah Ne hakkında konuştuğunuzu anlıyorum k<n?...ama yeniden sıralayan baytları kaybediyorum, n**2-k++**2çünkü operatör önceliği tersten giderken yanlıştır ve çıkarma değişmezdir, böylece sol tarafın her zaman k-1parantez içinde olması gerekir. Bir yol bulamadıkça?
George Reith,

Ah, çıkarma işlemini göz ardı ettim ... belki de bunun üzerinde çalışmak için her şeyi 4 yerine -4 ile çarpabilirsiniz? (Her ne kadar bu hala tasarrufunuzda
Neil,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.