Intersecting Circles - an area problem.

Geometry Level 3

In the drawing above the circles all have a radius of 5 units. What is the area shaded in blue? Give your answer to 1/100th.


The answer is 12.78.

This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try refreshing the page, (b) enabling javascript if it is disabled on your browser and, finally, (c) loading the non-javascript version of this page . We're sorry about the hassle.

2 solutions

The required area is 8 ( 5 2 5 10 x x 2 d x 5 2 5 2 25 x 2 d x 1 2 ( 5 + 5 2 ) ( 5 5 2 ) ) = 25 ( π 3 + 2 3 4 ) 12.782479 8\left (\displaystyle \int_{\frac{5}{2}}^5 \sqrt {10x-x^2}dx-\displaystyle \int_{\frac{5}{2}}^{\frac{5}{\sqrt 2}} \sqrt {25-x^2}dx-\dfrac{1}{2}\left (5+\dfrac{5}{\sqrt 2}\right ) \left (5-\dfrac{5}{\sqrt 2}\right )\right ) =25\left (\dfrac{π}{3}+2\sqrt 3-4\right )\approx \boxed {12.782479} .

Piotr Idzik
Jun 5, 2020

If you have a hammer everything looks like a nail . Below is my hammer. Due to the symmetry, I made the Monte-Carlo simulation only on the first quadrant. Furthermore, one can bound the region of simulation to the square ( 5 2 , 5 ) 2 \left(\frac{5}{2}, 5\right)^2 . I got the value 12.78 12.78 with 200000000 trials.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#include <iostream>
#include <cmath>
#include <random>
#include <vector>
#include <chrono>
#include <thread>
#include <ctime>
#include <algorithm>

template<std::size_t Dimension, typename ValueType, typename RandomEngineType, typename IsInsideType>
class McWorker
{
    private:
        const IsInsideType isInside;
        const std::uintmax_t localIter;
        std::array<std::uniform_real_distribution<ValueType>, Dimension> pointGenerator;
        RandomEngineType randomEngine;
        ValueType amountInside;

    public:
        explicit McWorker(const std::array<std::pair<ValueType, ValueType>, Dimension>& _limitBox,
                          const IsInsideType& _isInside,
                          const std::uintmax_t _localIter,
                          const int _seed) :
        isInside(_isInside),
        localIter(_localIter),
        pointGenerator(),
        randomEngine(_seed),
        amountInside()
        {
            for(std::size_t curDim = 0; curDim < Dimension; ++curDim)
            {
                const auto curLimit = _limitBox[curDim];
                this->pointGenerator[curDim] = std::uniform_real_distribution<ValueType>(curLimit.first,
                                                                                         curLimit.second);
            }
        }
        void operator()()
        {
            for(std::uintmax_t curIter = 0; curIter < this->localIter; ++curIter)
            {
                const auto curPos = this->getRandomPoint();
                if(this->isInside(curPos))
                {
                    ++this->amountInside;
                }
            }
        }
        ValueType GetAmountInside() const
        {
            return this->amountInside;
        }
    private:
        std::array<ValueType, Dimension> getRandomPoint()
        {
            std::array<ValueType, Dimension> res;
            for(std::size_t curDim = 0; curDim < Dimension; ++curDim)
            {
                res[curDim] = this->pointGenerator[curDim](this->randomEngine);
            }
            return res;
        }
};

template<typename UnsignedIntType>
UnsignedIntType gcd(const UnsignedIntType _a, UnsignedIntType _b)
{
    UnsignedIntType a, b;
    if(_a > _b)
    {
        a = _a;
        b = _b;
    }
    else
    {
        a = _b;
        b = _a;
    }
    while(b > 0)
    {
        const UnsignedIntType div = a%b;
        a = b;
        b = div;
    }
    return a;
}

template <std::size_t Dimension, typename ValueType>
ValueType getTotalMeasure(const std::array<std::pair<ValueType, ValueType>, Dimension>& limitBox)
{
    auto prodFun = [](const ValueType tmpProd, const std::pair<ValueType, ValueType>& curDim)->ValueType
    {
        return tmpProd*(curDim.second-curDim.first);
    };
    return std::accumulate(limitBox.begin(), limitBox.end(), ValueType(1), prodFun);
}

template <std::size_t Dimension, typename ValueType, typename RandomEngineType, typename IsInsideType>
ValueType MeasureMcPar(const std::array<std::pair<ValueType, ValueType>, Dimension>& limitBox,
                       const IsInsideType& isInside,
                       const std::uintmax_t totalIter,
                       const unsigned numberOfThreads)
{
    if(totalIter%std::uintmax_t(numberOfThreads) != 0)
    {
        throw std::invalid_argument("totalIter must be a multiple of numberOfThreads.");
    }
    const std::uintmax_t localIter = totalIter/std::uintmax_t(numberOfThreads);
    std::vector<std::thread> threadVector;
    typedef McWorker<Dimension, ValueType, RandomEngineType, IsInsideType> WorkerType;
    threadVector.reserve(numberOfThreads);
    std::vector<WorkerType> workerVector;
    workerVector.reserve(numberOfThreads);
    const auto mainSeed = time(NULL);
    for(unsigned i = 0; i < numberOfThreads; ++i)
    {
        workerVector.push_back(WorkerType(limitBox, isInside, localIter, i+mainSeed));
        threadVector.push_back(std::thread(std::ref(workerVector[i])));
    }
    for(auto & th : threadVector)
    {
        th.join();
    }

    auto sumFun = [](const std::uintmax_t tmpSum, const WorkerType& inWorker)->std::uintmax_t
    {
        return tmpSum+inWorker.GetAmountInside();
    };
    const std::uintmax_t totalSum = std::accumulate(workerVector.begin(), workerVector.end(), 0ULL, sumFun);
    const auto div = gcd(totalSum, totalIter);
    const auto limitingMeasure = getTotalMeasure<Dimension, ValueType>(limitBox);
    return limitingMeasure*ValueType(totalSum/div)/ValueType(totalIter/div);
}

template<typename ValueType>
class IsInside
{
    public:
        bool operator()(const std::array<ValueType, 2>& inPos) const
        {
            const auto r = ValueType(5);
            const auto r2 = r*r;
            const auto x = fabs(inPos[0]);
            const auto y = fabs(inPos[1]);
            const auto xp = x-r;
            const auto yp = y-r;
            return x*x+y*y >= r2 && xp*xp+y*y <= r2 && x*x+yp*yp <= r2;
        }
};

int main()
{
    typedef long double ValueType;
    typedef IsInside<ValueType> IsInsideType;
    const IsInsideType isInObj = IsInsideType();
    const auto limitInterval = std::make_pair(2.5L, 5.0L);
    const std::array<std::pair<ValueType, ValueType>, 2> limitBox = {limitInterval, limitInterval};
    const unsigned numberOfThreads = std::thread::hardware_concurrency();
    const std::uintmax_t totalIter = std::uintmax_t(numberOfThreads)*50000000ULL;

    const auto startTime = std::chrono::steady_clock::now();
    const auto res = MeasureMcPar<2, ValueType, std::mt19937_64, IsInsideType>(limitBox,
                                                                               isInObj,
                                                                               totalIter,
                                                                               numberOfThreads);
    const auto endTime = std::chrono::steady_clock::now();
    std::chrono::duration<double> runTime = endTime-startTime;
    std::cout<<"Runtime: "<<runTime.count()<<" [s]"<<std::endl;
    std::cout<<"Number of threads: "<<numberOfThreads<<std::endl;
    std::cout<<"Number of trials: "<<totalIter<<std::endl;
    std::cout<<"result: "<<4.0L*res<<std::endl;
    return 0;
}

Nice job! Try my problem "Operation Puzzled" only one solver so far. A program would probably go a long way in arriving at a solution.

Log in to reply

Done. But more by smart "trial and error" than pure coding.

Piotr Idzik - 1 year ago

Nice! Thanks for solving it.

0 pending reports

×

Problem Loading...

Note Loading...

Set Loading...