All about flooble | fun stuff | Get a free chatterbox | Free JavaScript | Avatars    
perplexus dot info

Home > Probability
Ducks in a pond (Posted on 2023-01-24) Difficulty: 3 of 5
3 ducks have landed in a circular pond. What is the probability there is a diameter such that the semicircle on one side contains all of them?

Repeat for 4 ducks.

Note: consider the ducks to be randomly chosen points in a circle.

No Solution Yet Submitted by Jer    
Rating: 5.0000 (2 votes)

Comments: ( Back to comment list | You must be logged in to post comments.)
Solution Randomize by XY coordinates instead of polar | Comment 11 of 17 |
Before I worked on this problem, it occurred to me that the answers might be different for different methods of randomness.  All the solvers so far, assumed ducks land along a random ray.  Anywhere along the ray is considered the same.
But what if ducks land at random x and y coordinates?  To simulate this, I let x and y be uniform from -1 to +1 and then ignored values that would be outside the circle.  I thought the results would be different, but in fact they were the same:
3 ducks: 0.75
4 ducks: 0.50

For my algorithm to determine if all angles result in all ducks being on the same side:
sort all angles in increasing order;
then subtract the smallest value from all so that one of them is 0;
now there is no confusing subtracting across the 0/360 line;
check each inter-duck angular "distance";
since they are sorted, if any distance is over 180, then they are all on the same side of some diameter.
------
import random
import math

def angl(dy,dx):
    if dx == 0:
        if dy ==0:
            return 0
        elif dy > 0:
            return 90
        elif dy < 0:
            return 270
        
    a = math.atan(dy/dx) * 180 / math.pi
    if dy >= 0 and dx >= 0:  # quadrant I
        result =  a
    elif dy >= 0 and dx < 0:  # quadrant II
        result =  a + 180
    elif dy < 0 and dx < 0:  # quadrant III
        result = a + 180
    elif dy < 0 and dx >= 0:  # quadrant IV
        result = a + 360
    return int(result)

def issameside(aList):
    """ bool:  input a list of angles between 0 and 360 return True if they are all on the same side of a diameter.  Algorithm, sort all angles in increasing order then subtract the smallest value from all so that one of them is 0.  then check each inter-duck angular distance.  Since they are sorted, if any distance is over 180 then they are all on the same side of some diameter.    """
    ducks = len(aList)
    locs = sorted(aList)
    locs = [ locs[:][i] - locs[:][0] for i in range(ducks) ]
    distances = []
    for i in range(ducks):
        if i == ducks -1:
            distances.append(360-locs[i])
        else:
            distances.append(locs[i+1]-locs[i])
    if max(distances) >= 180:
        return True
    else:
        return False


reps = 100000
ducks = 3   # or change this to 4
countTotal = 0
countSuccess = 0

for j in range(reps):
    xy_coords = []
    angles = []
    landed = 0
    while landed < (ducks):
        x = (random.uniform(-1,1))
        y = (random.uniform(-1,1))
        if x**2 + y**2 > 1:
            continue
        landed += 1
        xy_coords.append([x,y])
        angles.append(angl(y,x))
    countTotal += 1
    if issameside(angles):
        countSuccess +=1
print(ducks, countSuccess, countTotal, countSuccess/countTotal)

  Posted by Larry on 2023-01-25 13:24:36
Please log in:
Login:
Password:
Remember me:
Sign up! | Forgot password


Search:
Search body:
Forums (2)
Newest Problems
Random Problem
FAQ | About This Site
Site Statistics
New Comments (12)
Unsolved Problems
Top Rated Problems
This month's top
Most Commented On

Chatterbox:
Copyright © 2002 - 2024 by Animus Pactum Consulting. All rights reserved. Privacy Information