खुल के सोचो


16

आप 5-पक्षीय बॉक्स में एक गोले को फिट करने की कोशिश कर रहे हैं, लेकिन कभी-कभी यह पूरी तरह से फिट नहीं होता है। बॉक्स के बाहर (क्षेत्र के रिम के ऊपर) कितना गणना करने के लिए एक फ़ंक्शन लिखें।

3 संभावित स्थितियां हैं:

  • गोला पूरी तरह से बॉक्स में फिट बैठता है। उत्तर 0 होगा।
  • गोला बॉक्स के रिम पर बैठता है। इसका उत्तर कुल आयतन के आधे से अधिक होगा।
  • क्षेत्र बॉक्स के नीचे बैठता है।

आप यहां प्रत्येक स्थिति देख सकते हैं:

छवि

आपको इस मान को कम से कम 4 महत्वपूर्ण अंकों में गणना करने के लिए एक प्रोग्राम या फ़ंक्शन लिखना होगा।

इनपुट: जो भी प्रारूप में 4 गैर-नकारात्मक वास्तविक संख्याएं सुविधाजनक हैं * - चौड़ाई, लंबाई, बॉक्स की गहराई (आंतरिक माप), और गोले का व्यास।

आउटपुट: प्रयोग करने योग्य प्रारूप में 1 गैर-नकारात्मक वास्तविक संख्या * - बॉक्स के बाहर गोले का कुल आयतन (प्रतिशत नहीं)।

* दशमलव स्ट्रिंग से / के लिए परिवर्तनीय होना चाहिए

आपको त्रिकोणमिति के अपने उपयोग को यथासंभव सीमित करने के लिए प्रोत्साहित किया जाता है।

यह एक लोकप्रियता प्रतियोगिता है, इसलिए बॉक्स के बाहर सोचें!


किसी भी उदाहरण के मामलों कृपया?
मन्नीप

1
क्या हम मान सकते हैं कि या तो बॉक्स की दीवारें अनंत पतली हैं या दिए गए आयाम आंतरिक आयाम हैं? :)
डैरेन स्टोन

इनपुट के लिए अधिकतम मान क्या हैं?
ब्लेंडर

@DarrenStone मुझे लगता है कि दीवारों की मोटाई एकतरफा है। आप इसे अनंत भी मान सकते हैं, इसलिए बॉक्स एक इन्फिनिटी ब्लॉक में एक आयताकार छेद होगा। परिणाम दीवार की मोटाई के लिए किसी भी अन्य मूल्य के समान होगा। सिवाय अगर आप शारीरिक रूप से टूटने, विकृत करने या स्लाइसिंग करके या बॉक्स या गोले से नियमों को मोड़ना / धोखा देना चाहते हैं, या वास्तव में कुछ अजीब है।
विक्टर स्टैफुसा

3
@DarrenStone बक्से में केवल एक अच्छी तस्वीर के प्रयोजनों के लिए मोटाई होती है। समस्या आंतरिक आयामों से संबंधित है।
केंडल फ्रे

जवाबों:


21

आगे

कृपया नीचे, बॉक्स के बाहर एक गोला खोजें।

"क्षेत्र" वॉल्यूम-कंप्यूटिंग फ़ंक्शन है f। संदर्भ परीक्षण मामले "बॉक्स" की रचना करते हैं।

                     ( 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

आउटपुट:

0. 
0.523598775598299 
0.261799387799149 
0.279345334323962 
0.0654299441440212 

5

जावा - पूर्णांक आधारित

यह कार्यक्रम पीआई का उपयोग नहीं करता है और किसी भी बाहरी फ़ंक्शन को कॉल नहीं करता है - यहां तक ​​कि sqrt भी नहीं। यह केवल साधारण अंकगणित का उपयोग करता है - +, -, *और /। इसके अलावा, एक स्केलिंग कदम के अलावा, यह विशेष रूप से पूर्णांक के साथ काम करता है। यह मूल रूप से गोले को छोटे क्यूब्स में विभाजित करता है और उन लोगों को गिनता है जो बॉक्स के बाहर हैं।

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));
    }
}

आउटपुट:

0.0
0.5235867850933005
0.26178140856157484
0.27938608275528054
0.06542839088004015

इस रूप में, प्रोग्राम को 2GB से अधिक मेमोरी ( -Xmx2300mयहां काम करता है) की आवश्यकता होती है और यह धीमा है। यह वर्गमूल (अंकगणित) के एक समूह का पूर्वसूचक करने के लिए मेमोरी का उपयोग करता है; यह वास्तव में आवश्यक नहीं है, लेकिन इसके बिना यह बहुत धीमा होगा। मेमोरी की जरूरतों और गति दोनों को बेहतर बनाने के लिए, MINस्थिरांक का मान कम करें (हालांकि सटीकता में कमी आएगी)।


2

पायथन 2 (ऐरे-आधारित दृष्टिकोण)

यह सत्य-मूल्यों के साथ सरणियों की एक सरणी बनाता है यदि उस ग्रिड में एक विशिष्ट वर्ग सर्कल के अंदर या सर्कल के बाहर है। यह अधिक सटीक होना चाहिए जितना बड़ा वृत्त आप ड्रा करेंगे। यह तब या तो एक निश्चित पंक्ति के नीचे या ऊपर के क्षेत्र का चयन करता है और उस वर्ग की मात्रा को गिनता है जो सर्कल से संबंधित होता है और विभाजित करता है जो कि पूरे सर्कल में हैं।

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

पायथन 2.7, गोलाकार कैप सूत्र

यह संस्करण कुछ मामलों में रनटाइम चेतावनी फेंक देगा, लेकिन फिर भी सही उत्तर का आउटपुट देता है।

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))

11 पात्रों के लिए, मैं चेतावनी से छुटकारा पा सकता हूं।

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))

यहाँ संस्करण 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

हालांकि यह कोड गोल्फ नहीं है, आप अपने कोड में सभी import numpy as nको छोटा from numpy import*और दूर कर सकते हैं n.
तैमुक

@Timtech सिर और सुझाव के लिए धन्यवाद।
user2487951

1

मेथेमेटिका

उचित सीमा के साथ संख्यात्मक एकीकरण का उपयोग करना।

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

संदर्भ कार्यान्वयन - 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);
        }
    }
}

आउटपुट:

0
0.523598775598299
0.261799387799149
0.279345334323962
0.0654299441440212

मुझे इन परिणामों की समझ नहीं है। पहला एक स्पष्ट रूप से है 0. दूसरे में कोई ऊंचाई नहीं है, ताकि एक होना चाहिए। तीसरा एक गेंद को घर कर सकता है, और इसका आधा हिस्सा इसके ऊपर है (उत्तर 0.5 होना चाहिए)। बॉक्स 4 के मामले में बस थोड़ा सा छोटा है, इसलिए यह बॉक्स के शीर्ष पर टिकी हुई है। उत्तर 0.5 से थोड़ा अधिक होना चाहिए। अंतिम के लिए उत्तर> 0.5 होना चाहिए, क्योंकि गेंद को अंदर फिट करने के लिए चौड़ाई / लंबाई पर्याप्त नहीं है।
सुमुरि

@ Sumurai8 "आउटपुट: बॉक्स के बाहर गोले का कुल आयतन ( प्रतिशत नहीं )।"
केंडल फ्रे

0

माणिक

चलो देखते हैं ...
यदि बॉक्स पूरी तरह से अंदर है, तो चौड़ाई> व्यास; लंबाई> व्यास और ऊंचाई> व्यास।
इसे चलाने के लिए 1 चेक होना चाहिए।

यदि यह सबसे नीचे बैठा है, तो w> d; l> d और h V=(pi*h^2 /3)*(3r-h)तो उस स्थिति में, हम केवल ऊंचाई प्राप्त करते हैं और उसी के माध्यम से इसे चलाते हैं।

यदि यह अटक गया है, तो हम एक समान सूत्र ( V=(pi*h/6)*(3a^2 + h^2)) का उपयोग करते हैं । वास्तव में हमारा पहले वाला फॉर्मूला इसी पर आधारित है! अनिवार्य रूप से, हम उस का उपयोग करते हैं, और ए बस डब्ल्यू और एल में से एक छोटा है। (संकेत, हम करके ऊंचाई प्राप्त कर सकते हैं h=r-a)

अब कोड!

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

नोट ** मैंने इसे बहुत अधिक परीक्षण नहीं किया है, इसलिए कोई त्रुटि सामने आ सकती है, यदि कोई इसे नोटिस करता है, तो बताएं!
गणित हालांकि ठोस है।
छोटा संस्करण:

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)])}

(अब मुझे पता है कि v2 के लिए h प्राप्त करना अलग तरीके से किया जाता है, लेकिन मैं इसे बाद में ठीक करूंगा।


अच्छा लगा। वह कोड स्पष्ट रूप से पढ़ता है। लेकिन क्या आप निम्नलिखित कथन के बारे में निश्चित हैं? "हम ऊंचाई प्राप्त कर सकते हैं h=r-a" मैं सिर्फ गोलाकार टोपी के फार्मूले पर पढ़ रहा था , और आरेख किसी रिश्ते को इतना सरल नहीं बताता है। मैं इसे एक और पढ़ा दूँगा।
डैरेन स्टोन

@DarrenStone अब जब मैं पीछे मुड़कर देखूंगा तो मुझे यकीन नहीं होगा। मैं असाधारण रूप से नीचे / थका हुआ हूं, लेकिन किसी भी तरह, यह पैच करना बहुत आसान है!

मुझे यकीन है कि a = wi > le ? le : wiकाम करना चाहिए। अन्यथा, आपके पास एक बग है।
कोनराड बोरोस्की

a = wi>le?le:wiकाम नहीं किया। मैं यह अनुमान लगा रहा हूं क्योंकि मैं गिट रूबी (2.2 डेवलपर) चला रहा हूं, हो सकता है कि यह असंतुलन कहा हो।

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;
}

मेरे कोड में आधे-वृत्त के कुछ हिस्से के ग्राफ के घूमने के ठोस के आयतन का पता चलता है। pdbdगोले की सतह पर एक बिंदु के प्रक्षेपण की रैखिक दूरी को रखता है जो बॉक्स के होंठ को गोले के व्यास तक छूता है, जिसे अगर बढ़ाया जाता है, तो बॉक्स के निचले हिस्से के लिए सामान्य होगा। जिन दो अभिव्यक्तियों M_PIमें मूल रूप pi * -(x^2)+2rxसे x के संबंध में अभिन्नता के विरोधी व्युत्पन्न हैं (जहां x गोला के माध्यम से उपर्युक्त व्यास के साथ लंबाई का माप है और जहां r क्षेत्र के त्रिज्या है) का मूल्यांकन pdbdया तो अलग-अलग आयामों के साथ होने वाले विशेष मामले के आधार पर गोले के व्यास और बॉक्स की गहराई का अंतर।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.