Cities Around Amsterdam

Consider this large set of 1D points on the number line . Let S S be the set of unordered pairs ( p , q ) (p,q) such that p q 1000 |p - q| \leq 1000 . How many elements does S S contain?


The answer is 53.

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.

4 solutions

Thaddeus Abiy
Jun 28, 2016

While admittedly there are faster approaches( O ( n + k ) ) O(n+k)) , I will describe an O ( n log ( n ) + k ) O(n\log(n) + k) algorithm(where n n is the number of points and k k is the number of pairs that satisfy the property). This algorithm suffices for our case and is easy to understand. We begin by sorting the set of points( O ( n log ( n ) O(n\log(n) ). We then proceed to iterate through each point P i P_i . From there we will go through every point P j P_j where j > i j > i until P j P i > 1000 P_j - P_i > 1000 . This generates all the unordered pairs.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
with open('points.txt','rb') as text:
    exec('points='+text.read())

points.sort()
S = set([])
n = len(points)
for i in range(n):
     j = i + 1     
     while j < n:
        p , q = points[i] , points[j]
        if q - p > 1000:
             break
        else:
            S.add((p,q))
        j += 1

print len(S)

EDIT: Despite the problem statement, this algorithm finds all the points and then counts them.(instead of directly counting them). I believe this is a more general and applicable version of the classic computational geometery problem.

This algorithm should be O ( n 2 ) O(n^2) right? Because the worst case is all pairs satisfy the property, k = n 2 k=n^2 . I have one slightly better approach is to use Binary Search. After you sort the list O ( n lg n ) O(n\lg n) , for each element you binary search when does it reach > 1000 >1000 . This is O ( n lg n ) O(n\lg n) .

Christopher Boo - 4 years, 11 months ago

Log in to reply

Yes that is accurate. Despite the problem statement, I should have clarified I was demonstrating a generating algorithm in my solution instead of a counting algorithm. Traditionally, such algorithms are expressed in terms of both n n and k k (where k k is the number of pairs that are generated). It is so because we can easily assert that such algorithms are at least Ω ( k ) \Omega(k) (this is not true for the counting case). Therefore, ideally we would like to achieve a O ( n + k ) O(n + k) complexity . For the algorithm in the solution, after sorting, let k i k_i be the number of pairs generated when visiting the i i th element in the list x i x_i . Then we do k i + 1 k_i + 1 computations for x i x_i (the extra computation for the point that exceeds the radius ). Running time is thus

T ( n , k ) = n lg n + i = 1 n k i + 1 = n lg n + n + i = 1 n k i = n lg n + n + k = O ( k + n lg n ) T(n,k) = n\lg n + \sum_{i=1}^{n}{k_i + 1 }= n\lg n +n + \sum_{i=1}^{n}{k_i} = n\lg n + n + k = O(k + n\lg n)

I believe this doesn't change even if we use binary search to find the index, we would still have to report the k i k_i elements.

For an O ( n + k ) O(n+k) algorithm that uses bucketing, take a look at this .

Thaddeus Abiy - 4 years, 11 months ago

I wrote a script in python which returned exactly 10000 more than the answer, can anyone tel me why? l=[the list] s=0 for i in range(10000):

...for n in range(i,10000):

......if abs(l[n]-l[i])<=1000:

.........s+=1

...if i%100==0:

......print(str(i//100)+'%')

(the last bit is just a progress monitor as the function is very inefficient) Just to reiterate the program returned 10053 and I have no idea why. Thanks in advance

William Whitehouse - 4 years, 11 months ago

Log in to reply

Your second for loop should be : for n in range(i+1,10000). Else you will end up comparing 10000 same pairs of numbers which differences is 0.

Christopher Boo - 4 years, 11 months ago

Log in to reply

Ah yes, It's obvious now that you've pointed it out! Thank you

William Whitehouse - 4 years, 11 months ago
Rushikesh Jogdand
Jun 29, 2016
1
2
3
4
5
6
7
with open('points.txt','rb') as text:
    exec('a='+text.read())
count=0
for i in range(0,len(a)):
    for j in range(i+1,len(a)):
        if abs(a[i]-a[j])<=1000:count+=1
print(count)

Masbahul Islam
Jul 16, 2016

A MATLAB Code

SetS = dlmread('points.txt',',');
S = 0;
for i = 1:l(ength(SetS)-1)
  Nop = length(find(abs(SetS((i+1):end)-SetS(i))<=1000));
  S = S+Nop;
end
S

This code searches for all points q q to the right of a point p p in the list, such that p q 1000 |p-q| \leq 1000 , in one go. Thus, there would be 9999 9999 vector comparisons done, as compared to 9999 × 10000 2 = 49995000 \frac{9999 \times 10000}{2}=49995000 scalar comparions.

0 pending reports

×

Problem Loading...

Note Loading...

Set Loading...