Code-Golf: Lưới điểm trong một vòng tròn


15

Hình ảnh sau đây cho thấy vấn đề:

nhập mô tả hình ảnh ở đây

Viết hàm, cho một số nguyên là bán kính vòng tròn, tính toán số điểm lưới bên trong vòng tròn trung tâm (bao gồm cả đường biên).

Hình ảnh cho thấy:

f[1] = 5  (blue points)
f[2] = 13 (blue + red points)  

các giá trị khác để kiểm tra / gỡ lỗi của bạn:

f[3]    = 29
f[10]   = 317
f[1000] = 3,141,549
f[2000] = 12,566,345  

Nên có hiệu suất hợp lý. Hãy nói ít hơn một phút cho f [1000].

Mã ngắn nhất sẽ thắng. Quy tắc thông thường-Golf áp dụng.

Vui lòng gửi tính toán và thời gian của f [1001] làm ví dụ.



Câu trả lời:


9

J, 21 19 18

+/@,@(>:|@j./~@i:)

Xây dựng các phức từ -x-xj đến x + xj và có độ lớn.

Chỉnh sửa: Với >:

Chỉnh sửa 2: Với hook và monadic ~. Chạy chậm hơn một vài lần vì một số lý do, nhưng vẫn là 10 giây trong f (1000).


Ôi, tôi không biết nữa i:, tôi rất ăn cắp điều đó, cảm ơn!
JB

@JB: Vâng, tôi ... tôi đang ăn cắp >:. derp
Jesse Millikan

Tôi ước gì tôi hiểu mũ cũng đủ để ăn cắp những quá O :-)
JB

Câu trả lời này ngắn một cách chán nản (với một người không bao giờ bận tâm để học một lang ngắn và / hoặc chơi gôn) >:. Nhưng này, đó là một câu trả lời tuyệt vời! :)
Vụ kiện của Quỹ Monica

5

J, 27 21

3 :'+/,y>:%:+/~*:i:y'

Rất tàn bạo: Tính toán sqrt (x² + y²) qua [-n, n] phạm vi và số lượng mặt hàng ≤n . Vẫn còn rất nhiều lần chấp nhận cho 1000.

Chỉnh sửa : i:ylà khá ngắn hơn một chút y-i.>:+:y. Cảm ơn Jesse Millikan !


Hà! Đó là ý tưởng đằng sau yêu cầu một hiệu suất tốt! Chỉ tò mò: thời gian cho 1000 là gì?
Tiến sĩ belisarius

1
@ Belisarius: 0,86s. Trên phần cứng 10 năm tuổi. 3,26s cho năm 2000.
JB

4

Ruby 1.9, 62 58 54 ký tự

f=->r{1+4*eval((0..r).map{|i|"%d"%(r*r-i*i)**0.5}*?+)}

Thí dụ:

f[1001]
=> 3147833

t=Time.now;f[1001];Time.now-t
=> 0.003361411

4

Python 55 Chars

f=lambda n:1+4*sum(int((n*n-i*i)**.5)for i in range(n))

f=lambda n:1+4*sum(int((n*n-i*i)**.5)for i in range(n))ngắn hơn 17 ký tự.
Ventero

3

Haskell, 41 byte

f n=1+4*sum[floor$sqrt$n*n-x*x|x<-[0..n]]

Đếm số điểm trong góc phần tư x>=0, y>0, nhân 4, cộng 1 cho điểm trung tâm.


2

Haskell, 44 byte

f n|w<-[-n..n]=sum[1|x<-w,y<-w,x*x+y*y<=n*n]

Tôi mới biết về Haskell: Làm thế nào bạn có thể viết w<-[-n..n]ở đâu (thường) có giá trị boolean?
flawr

1
@flawr Đây là những người bảo vệ mẫu , thành công nếu một mẫu phù hợp, nhưng có thể được sử dụng trong việc chơi golf như một cách ngắn hơn. Xem mẹo này .
xnor

Cảm ơn, tôi đã không nhận thức được chủ đề này!
flawr

1

JavaScript (ES6), 80 byte (không cạnh tranh vì ES6 quá mới)

n=>(a=[...Array(n+n+1)].map(_=>i--,i=n)).map(x=>a.map(y=>r+=x*x+y*y<=n*n),r=0)|r

Phiên bản thay thế, cũng 80 byte:

n=>[...Array(n+n+1)].map((_,x,a)=>a.map((_,y)=>r+=x*x+(y-=n)*y<=n*n,x-=n),r=0)|r

Phiên bản ES7, cũng 80 byte:

n=>[...Array(n+n+1)].map((_,x,a)=>a.map((_,y)=>r+=(x-n)**2+(y-n)**2<=n*n),r=0)|r

1

Python 2, 48 byte

f=lambda n,i=0:i>n or(n*n-i*i)**.5//1*4+f(n,i+1)

Giống như giải pháp của fR0DDY , nhưng đệ quy và trả về một float. Trả về một int là 51 byte:

f=lambda n,i=0:i>n or 4*int((n*n-i*i)**.5)+f(n,i+1)

1

C (gcc) , 60 byte

r,a;f(x){for(a=r=x*x;a--;)r-=hypot(a%x+1,a/x)>x;x=4*r+1;}

Hãy thử trực tuyến!

Vòng lặp trên góc phần tư thứ nhất, nhân kết quả với 4 và thêm một. Hơi ít chơi golf

r,a;
f(x){
  for(a=r=x*x;a--;)
    r-=hypot(a%x+1,a/x)>x;
  x=4*r+1;
}

1

APL (Dyalog mở rộng) , 14 byte

{≢⍸⍵≥|⌾⍀⍨⍵…-⍵}

Hãy thử trực tuyến!

Mặc dù thiếu phần tích hợp i:(bao gồm từ -n đến n) của J, APL Extended có cú pháp ngắn hơn trong các lĩnh vực khác.

{≢⍸⍵≥|⌾⍀⍨⍵…-⍵}            Monadic function taking an argument n.
           ⍵…-⍵             n, n-1, ..., -n
      ⌾⍀                   Make a table of complex numbers
                            (equivalent to ∘.{⍺+1J×⍵} in Dyalog APL)
                           with both real and imaginary parts from that list.
      |                       Take their magnitudes.
    ⍵≥                        1 where a magnitude are is at most n, and 0 elsewhere.
                            Get all indices of truthy values.
                            Find the length of the resulting list.

1

Japt -x , 12 byte

òUn)ï Ëx²§U²

Hãy thử trực tuyến!

Giải trình:

òUn)            #Get the range [-input ... input]
    ï           #Get each pair of numbers in that range
      Ë         #For each pair:
       x        # Get the sum...
        ²       # Of the squares
         §      # Check if that sum is less than or equal to...
          U²    # The input squared
                #Output the number of pairs that passed the check


1

PHP, 85 83 byte

Mật mã:

function f($n){for($x=$n;$x;$c+=$x,$y++)for(;$n*$n<$x*$x+$y*$y;$x--);return$c*4+1;}

Kết quả của nó (kiểm tra https://3v4l.org/bC0cY để biết nhiều phiên bản PHP):

f(1001)=3147833
time=0.000236 seconds.

Mã không mã hóa:

/**
 * Count all the points having x > 0, y >= 0 (a quarter of the circle)
 * then multiply by 4 and add the origin.
 *
 * Walk the lattice points in zig-zag starting at ($n,0) towards (0,$n), in the
 * neighbourhood of the circle. While outside the circle, go left.
 * Go one line up and repeat until $x == 0.
 * This way it checks about 2*$n points (i.e. its complexity is linear, O(n))
 *
 * @param int $n
 * @return int
 */
function countLatticePoints2($n)
{
    $count = 0;
    // Start on the topmost right point of the circle ($n,0), go towards the topmost point (0,$n)
    // Stop when reach it (but don't count it)
    for ($y = 0, $x = $n; $x > 0; $y ++) {
        // While outside the circle, go left;
        for (; $n * $n < $x * $x + $y * $y; $x --) {
            // Nothing here
        }
        // ($x,$y) is the rightmost lattice point on row $y that is inside the circle
        // There are exactly $x lattice points on the row $y that have x > 0
        $count += $x;
    }
    // Four quarters plus the center
    return 4 * $count + 1;
}

Một triển khai ngây thơ kiểm tra $n*($n+1)các điểm (và chạy 1000 chậm hơn nhưng vẫn tính toán f(1001)trong chưa đầy 0,5 giây) và bộ kiểm tra (sử dụng dữ liệu mẫu được cung cấp trong câu hỏi) có thể được tìm thấy trên github .


0

Clojure / ClojureScript, 85 ký tự

#(apply + 1(for[m[(inc %)]x(range 1 m)y(range m):when(<=(+(* x x)(* y y))(* % %))]4))

Brute buộc góc phần tư thứ nhất, bao gồm trục y nhưng không phải trục x. Tạo số 4 cho mỗi điểm, sau đó thêm chúng cùng với 1 cho điểm gốc. Chạy trong dưới 2 giây cho đầu vào 1000.

Lạm dụng địa ngục forđể xác định một biến và lưu một vài ký tự. Làm tương tự để tạo bí danh cho việc rangekhông lưu bất kỳ ký tự nào (và làm cho nó chạy chậm hơn đáng kể) và có vẻ như bạn sẽ không lưu bất cứ thứ gì bằng cách tạo một hàm vuông.


Đây là một câu hỏi khá cũ, bạn có chắc câu trả lời này sẽ có hiệu quả vào thời điểm đó không?
Màu xanh

@muddyfish Tôi không để ý tuổi, chỉ thấy nó ở gần đỉnh. Clojure có trước câu hỏi, nhưng tôi không biết lịch sử của nó đủ để biết về sự thay đổi ngôn ngữ.
MattPutnam


0

Toán học, 35 ký tự

f[n_]:=Sum[SquaresR[2,k],{k,0,n^2}]

Được nâng lên từ https://oeis.org/A000328

https://reference.wolfram.com/lingu/ref/SquaresR.html

SquaresR[2,k]là số cách biểu diễn k là tổng của hai hình vuông, giống như số điểm của mạng tinh thể trên một vòng tròn bán kính k ^ 2. Tổng từ k = 0 đến k = n ^ 2 để tìm tất cả các điểm trên hoặc bên trong một vòng tròn bán kính n.


1
2~SquaresR~k~Sum~{k,0,#^2}&để làm cho nó ngắn hơn
jaeyong hát

0

Tcl, 111 byte

lassign {1001 0 -1} r R x
while {[incr x]<$r} {set R [expr {$R+floor(sqrt($r*$r-$x*$x))}]}
puts [expr {4*$R+1}]

Đơn giản rời rạc xVòng lặp trên góc phần tư I, tính y lớn nhất bằng Định lý Pythagore ở mỗi bước. Kết quả là 4 lần tổng cộng một (cho điểm trung tâm).

Kích thước của chương trình phụ thuộc vào giá trị của r . Thay thế {1001 0 -1}bằng"$argv 0 -1" và bạn có thể chạy nó với bất kỳ giá trị đối số dòng lệnh nào cho r .

Tính toán f (1001) → 3147833.0trong khoảng 1030 micro giây, bộ xử lý AMD Sempron 130 2.6GHz 64 bit, Windows 7.

Rõ ràng, bán kính càng lớn, phép tính gần đúng với PI: f (10000001) càng gần trong khoảng 30 giây tạo ra giá trị 15 chữ số, tương đương với độ chính xác của một nhân đôi của IEEE.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.