Suy nghĩ sáng tạo


16

Bạn đang cố gắng lắp một quả cầu vào hộp 5 mặt, nhưng đôi khi nó không khớp hoàn toàn. Viết hàm để tính bao nhiêu hình cầu bên ngoài (phía trên vành của) hộp.

Có 3 tình huống có thể xảy ra:

  • Hình cầu phù hợp hoàn toàn trong hộp. Câu trả lời sẽ là 0.
  • Quả cầu nằm trên vành hộp. Câu trả lời sẽ là hơn một nửa tổng khối lượng.
  • Quả cầu nằm dưới đáy hộp.

Bạn có thể xem từng tình huống ở đây:

Hình ảnh

Bạn phải viết một chương trình hoặc hàm để tính giá trị này thành ít nhất 4 chữ số có nghĩa.

Đầu vào: 4 số thực không âm ở bất kỳ định dạng nào đều thuận tiện * - chiều rộng, chiều dài, chiều sâu của hộp (số đo bên trong) và đường kính của hình cầu.

Đầu ra: 1 số thực không âm trong định dạng có thể sử dụng * - tổng khối lượng (không phải tỷ lệ phần trăm) của hình cầu bên ngoài hộp.

* phải được chuyển đổi thành / từ một chuỗi thập phân

Bạn được khuyến khích hạn chế sử dụng lượng giác càng nhiều càng tốt.

Đây là một cuộc thi phổ biến, vì vậy hãy suy nghĩ ra khỏi hộp!


bất kỳ trường hợp ví dụ xin vui lòng?
mniip

1
Chúng ta có thể giả sử hoặc các bức tường của hộp là vô cùng mỏng hoặc kích thước được đưa ra là kích thước bên trong? :)
Darren Stone

Các giá trị tối đa cho các đầu vào là gì?
Máy xay sinh tố

@DarrenStone Tôi nghĩ rằng độ dày của tường là không quan trọng. Bạn cũng có thể xem xét nó là vô hạn, vì vậy hộp sẽ là một lỗ hình chữ nhật trong một khối infinte. Kết quả sẽ giống như bất kỳ giá trị nào khác cho độ dày của tường. Ngoại trừ nếu bạn đang có ý định bẻ cong / gian lận các quy tắc bằng cách phá vỡ vật lý, bóp méo hoặc cắt hộp hoặc hình cầu, hoặc làm điều gì đó thực sự kỳ lạ.
Victor Stafusa

3
@DarrenStone Các hộp chỉ có độ dày cho mục đích của một hình ảnh đẹp. Các vấn đề liên quan đến kích thước nội thất.
Kendall Frey

Câu trả lời:


21

Forth

Xin vui lòng tìm, bên dưới, một quả cầu bên ngoài hộp.

"Hình cầu" là chức năng tính toán âm lượng f. Các trường hợp kiểm tra tham chiếu soạn "hộp".

                     ( x y z d -- v )
                 : f { F: z F: d } d f2/ 
              { F: r } fmin { F: m } m f2/ {
             F: b } d m f<= d z f<= and if 0e
             else r r r f* b b f* f- fsqrt f-
              { F: t } d m f<= t z f> or if d 
               z f- else d t f- then r 3e f* 
                  fover f- pi f* fover f*
                      f* 3e f/ then ;

                     1e                 1e      
                     1e                 1e 
                     f                  f. 
            cr       1e        1e       0e      
            1e       f         f.       cr 
            1e       1e 0.5e 1e f f. cr 1e 
            0.999e 1e          1e     f  
            f.  cr            0.1e 1e   
            1.000e 0.500e f f. cr

Đầu ra:

0. 
0.523598775598299 
0.261799387799149 
0.279345334323962 
0.0654299441440212 

5

Java - dựa trên số nguyên

Chương trình này không sử dụng pi và không gọi bất kỳ chức năng bên ngoài nào - thậm chí không phải là sqrt. Nó chỉ sử dụng số học đơn giản - +, -, */. Hơn nữa, ngoài một bước chia tỷ lệ, nó chỉ hoạt động với các số nguyên. Về cơ bản, nó chia quả cầu thành các khối nhỏ và đếm những cái nằm ngoài hộp.

public class Box {
    private static final int MIN = 10000;
    private static final int MAX = MIN * 2;

    private static final int[] SQ = new int[MAX * MAX + 1];

    static {
        int t = 1;
        for (int i = 1; i <= MAX; ++i) {
            while (t < i * i) SQ[t++] = i - 1;
        }
        SQ[MAX * MAX] = MAX;
    }

    public static long outsideInt(int r, int w, int z) {
        int r2 = r * r;
        int o = z - r + 1;
        if (w < r * 2) {
            int t = 1 - SQ[r2 - w * w / 4];
            if (t < o) o = t;
        }
        long v = 0;
        for (int i = o; i <= r; ++i) {
            int d = r2 - i * i;
            int j0 = SQ[d];
            v += 1 + 3 * j0;
            for (int j = 1; j <= j0; ++j)
                v += 4 * SQ[d - j * j];
        }
        return v;
    }

    public static double outside(double x, double y, double z, double d) {
        double f = 1;
        double w = x < y ? x : y;
        double r = d / 2;
        while (r < MIN) {
            f *= 8;
            r *= 2;
            w *= 2;
            z *= 2;
        }
        while (r > MAX) {
            f /= 8;
            r /= 2;
            w /= 2;
            z /= 2;
        }
        return outsideInt((int) r, (int) w, (int) z) / f;
    }

    public static void main(final String... args) {
        System.out.println(outside(1, 1, 1, 1));
        System.out.println(outside(1, 1, 0, 1));
        System.out.println(outside(1, 1, 0.5, 1));
        System.out.println(outside(1, 0.999, 1, 1));
        System.out.println(outside(0.1, 1, 1, 0.5));
    }
}

Đầu ra:

0.0
0.5235867850933005
0.26178140856157484
0.27938608275528054
0.06542839088004015

Trong hình thức này, chương trình yêu cầu bộ nhớ hơn 2GB (hoạt động với -Xmx2300mở đây) và rất chậm. Nó sử dụng bộ nhớ để xác định trước một loạt các căn bậc hai (một cách hợp lý); nó không thực sự cần thiết, nhưng nếu không có nó thì nó sẽ chậm hơn rất nhiều. Để cải thiện cả nhu cầu và tốc độ bộ nhớ, hãy giảm giá trị của MINhằng số (điều đó sẽ làm giảm độ chính xác).


2

Python 2 (Cách tiếp cận dựa trên mảng)

Nó tạo ra một mảng các mảng có giá trị thật nếu một hình vuông cụ thể trong lưới đó nằm bên trong vòng tròn hoặc bên ngoài vòng tròn. Nó sẽ nhận được chính xác hơn vòng tròn lớn hơn là bạn vẽ. Sau đó, nó chọn một khu vực bên dưới hoặc bên trên một hàng nhất định và đếm số lượng hình vuông thuộc về vòng tròn và chia cho số lượng hình vuông trong toàn bộ hình tròn.

import math as magic
magic.more = magic.pow
magic.less = magic.sqrt

def a( width, length, depth, diameter ):
  precision = 350 #Crank this up to higher values, such as 20000

  circle = []
  for x in xrange(-precision,precision):
    row = []
    for y in xrange(-precision,precision):
      if magic.less(magic.more(x, 2.0)+magic.more(y, 2.0)) <= precision:
        row.append(True)
      else:
        row.append(False)
    circle.append(row)

  if min(width,length,depth) >= diameter:
    return 0
  elif min(width,length) >= diameter:
    row = precision*2-int(precision*2*float(depth)/float(diameter))
    total = len([x for y in circle for x in y if x])
    ammo = len([x for y in circle[:row] for x in y if x])
    return float(ammo)/float(total)
  else:
    #Why try to fit a sphere in a box if you can try to fit a box on a sphere
    maxwidth = int(float(precision*2)*float(min(width,length))/float(diameter))
    for row in xrange(0,precision*2):
      rowwidth = len([x for x in circle[row] if x])
      if rowwidth > maxwidth:
        total = len([x for y in circle for x in y if x])
        ammo = len([x for y in circle[row:] for x in y if x])
        return float(ammo)/float(total)

2

Python 2.7, Công thức nắp hình cầu

Phiên bản này sẽ đưa ra cảnh báo thời gian chạy trong một số trường hợp, nhưng vẫn đưa ra câu trả lời đúng.

import numpy as n
x,y,z,d=(float(i) for i in raw_input().split(' '))
r=d/2
V=4*n.pi*r**3/3
a=n.sqrt((d-z)*z)
b=min(x,y)/2
h=r-n.sqrt(r**2-b**2)
c=lambda A,H: (3*A**2+H**2)*n.pi*H/6
print(0 if d<=z and r<=b else c(a,d-z) if r<=b and z>r else V-c(a,z) if r<=b or z<h else V-c(b,h))

Đối với 11 ký tự nhiều hơn, tôi có thể thoát khỏi cảnh báo.

import math as m
x,y,z,d=(float(i) for i in raw_input().split(' '))
r=d/2
V=4*m.pi*r**3/3
if d>z:
    a=m.sqrt((d-z)*z)
b=min(x,y)/2
h=r-m.sqrt(r**2-b**2)
c=lambda A,H: (3*A**2+H**2)*m.pi*H/6
print(0 if d<=z and r<=b else c(a,d-z) if r<=b and z>r else V-c(a,z) if r<=b or z<h else V-c(b,h))

Dưới đây là các trường hợp thử nghiệm chạy trên phiên bản 1:

$ python spherevolume.py
1 1 1 1
0
$ python spherevolume.py
1 1 0 1
0.523598775598
$ python spherevolume.py
1 1 .5 1
0.261799387799
$ python spherevolume.py
1 .999 1 1        
0.279345334324
$ python spherevolume.py
.1 1 1 0.5
spherevolume.py:65: RuntimeWarning: invalid value encountered in sqrt
  a=n.sqrt((d-z)*z) or b
0.065429944144

Mặc dù đây không phải là mã golf, bạn có thể rút ngắn import numpy as nđến from numpy import*và lấy đi tất cả các n.trong mã của bạn.
TimTech

@Timtech Cảm ơn những người đứng đầu và đề nghị.
dùng2487951

1

Toán học

Sử dụng tích hợp số với các giới hạn thích hợp.

f[width_, length_, height_, diam_] := 
 With[{r = diam/2, size = Min[width, length]/2},
  Re@NIntegrate[
    Boole[x^2 + y^2 + z^2 < r^2], {x, -r, r}, {y, -r, r}, 
      {z, -r, Max[-r, If[size >= r, r - height, Sqrt[r^2 - size^2]]]}]
  ]

0

Tham khảo thực hiện - C #

using System;

namespace thinkoutsidethebox
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(OutsideTheBox(1, 1, 1, 1));
            Console.WriteLine(OutsideTheBox(1, 1, 0, 1));
            Console.WriteLine(OutsideTheBox(1, 1, 0.5, 1));
            Console.WriteLine(OutsideTheBox(1, 0.999, 1, 1));
            Console.WriteLine(OutsideTheBox(0.1, 1, 1, 0.5));
        }

        static double OutsideTheBox(double x, double y, double z, double d)
        {
            x = Math.Min(x, y);
            double r = d / 2; // radius
            double xr = x / 2; // box 'radius'
            double inside = 0; // distance the sphere sits inside the box
            if (d <= x && d <= z) // it fits
            {
                return 0;
            }
            else if (d <= x || r - Math.Sqrt(r * r - xr * xr) > z) // it sits on the bottom
            {
                inside = z;
            }
            else // it sits on the rim
            {
                inside = r - Math.Sqrt(r * r - xr * xr);
            }
            // now use the formula from Wikipedia
            double h = d - inside;
            return (Math.PI * h * h / 3) * (3 * r - h);
        }
    }
}

Đầu ra:

0
0.523598775598299
0.261799387799149
0.279345334323962
0.0654299441440212

Tôi không hiểu những kết quả này. Cái thứ nhất rõ ràng là 0. Cái thứ hai không có chiều cao, vì vậy cái thứ nhất phải là 1. Cái thứ ba có thể đặt bóng và chính xác một nửa của nó nằm trên nó (câu trả lời phải là 0,5). Hộp trong trường hợp 4 chỉ là một chút đến nhỏ, vì vậy nó nằm trên đỉnh của hộp. Câu trả lời nên nhiều hơn 0,5 một chút. Câu trả lời cho câu hỏi cuối cùng phải là> 0,5, vì chiều rộng / chiều dài không đủ để lắp bóng vào trong.
Sumurai8

@ Sumurai8 "Đầu ra: tổng khối lượng ( không phải tỷ lệ phần trăm ) của hình cầu bên ngoài hộp."
Kendall Frey

0

Hồng ngọc

Hãy xem ...
Nếu hộp nằm hoàn toàn bên trong, thì chiều rộng> đường kính; chiều dài> đường kính và chiều cao> đường kính.
Đó phải là kiểm tra đầu tiên để chạy.

Nếu nó ngồi ở phía dưới, thì w> d; l> d và h V=(pi*h^2 /3)*(3r-h)Vì vậy, trong trường hợp đó, chúng ta chỉ cần lấy chiều cao và chạy qua đó.

Nếu nó bị kẹt, chúng tôi sử dụng một công thức tương tự ( V=(pi*h/6)*(3a^2 + h^2)). Trong thực tế công thức trước đây của chúng tôi dựa trên cái này! Về cơ bản, chúng tôi sử dụng điều đó, và a chỉ đơn giản là một nhỏ hơn của w và l. (gợi ý, chúng ta có thể tăng chiều cao bằng cách làm h=r-a)

Bây giờ là mã!

def TOTB(wi,le,hi,di)
  if wi>=di and le>=di and hi>=di
    res = 0
  elsif wi>=di and le>=di
    r = di/2
    res = 3*r
    res -= hi
    res *= Math::PI
    res *= hi*hi
    res /= 3
  else
    r = di/2
    if wi>le
      a=le
    else
      a=wi
    end #had issues with the Ternary operator on ruby 2.2dev
    h = r-a
    res = 3*a*a
    res += h*h
    res *= Math::PI
    res *= h
    res /= 6
  end
  res
end

Lưu ý ** Tôi đã không kiểm tra nó quá nhiều, vì vậy một lỗi có thể đã xuất hiện, nếu có ai thông báo, hãy nói!
Toán học là vững chắc mặc dù.
Phiên bản ngắn hơn:

v1 = ->r,h{(3*r -h)*Math::PI*h*h/3}
v2 = ->r,a{h=r-a;((3*a*a)+(h*h))*h*Math::PI/6}
TOTB = ->wi,le,hi,di{(di<wi&&di<le&&di<hi)?0:((di<wi&&di<le)?v1[di/2,hi]:v2[di/2,((wi>le)?le:wi)])}

(Bây giờ tôi biết chắc chắn rằng việc lấy h cho v2 được thực hiện khác đi, nhưng tôi sẽ sửa nó sau.


Đẹp. Mã đó đọc rõ ràng. Nhưng bạn có chắc chắn về tuyên bố sau? "Chúng ta có thể tăng chiều cao bằng cách thực hiện h=r-a" Tôi vừa đọc các công thức nắp hình cầu , và sơ đồ không cho thấy mối quan hệ quá đơn giản. Tôi sẽ đọc lại.
Darren Stone

@DarrenStone Bây giờ tôi nhìn lại tôi không chắc. Tôi cực kỳ suy sụp / kiệt sức, nhưng dù sao đi nữa, nó rất dễ vá!

Tôi gần như chắc chắn a = wi > le ? le : wisẽ làm việc. Nếu không, bạn có một lỗi.
Konrad Borowski

a = wi>le?le:wiđã không làm việc. Tôi đoán đó là vì tôi đang chạy git ruby ​​(nhà phát triển 2.2), nó có thể đã nói mất cân bằng.

0

c ++

#define _USE_MATH_DEFINES   //so I can use M_PI
#include <math.h>           //so I can use sqrt()
#include <iostream>
#include <algorithm>

using namespace std;


int main()
{
    double w;
    double l;
    double d;
    double sd;
    double min_wl;
    double pdbd;
    double sl;
    cin >> w >> l >> d >> sd;

    min_wl = min(w, l);
    if(sd <= min_wl)
    {
        pdbd = 0.0;
    } else
    {
        pdbd = (sqrt((((sd/2)*(sd/2))-((min_wl/2)*(min_wl/2)))) + (sd/2));
    }
    sl = sd - d;

    if(sd <= min(min_wl, d))
    {
        cout << 0;
        return 0;
    } else if((sl < pdbd) && (pdbd > 0.0))    //sits on lip of box
    {
        cout << (M_PI * (((sd/2) * pdbd * pdbd) - ((pdbd * pdbd * pdbd)/(3))));
        return 0;
    } else                  //sits on bottom of box
    {
        cout << (M_PI * (((sd/2) * sl * sl)-((sl * sl * sl)/(3))));
        return 0;
    }
    return 0;
}

Mã của tôi tìm thấy khối lượng của khối quay của đồ thị của một phần của một nửa vòng tròn. pdbdgiữ khoảng cách tuyến tính của hình chiếu của một điểm trên bề mặt của quả cầu chạm vào môi của hộp với đường kính của quả cầu, nếu mở rộng, sẽ bình thường đến đáy hộp. Hai biểu thức chứa M_PIvề cơ bản là tính đạo hàm của tích phân pi * -(x^2)+2rxđối với x (trong đó x là số đo chiều dài dọc theo đường kính đã đề cập ở trên qua hình cầu và trong đó r là bán kính của hình cầu) được đánh giá ở một trong hai pdbdhoặc sự khác biệt của đường kính hình cầu và độ sâu hộp tùy thuộc vào trường hợp cụ thể xảy ra với các kích thước khác nhau.

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.