Google CodeJam Past Exercise - Decrease runtime
<p>I have been working on a past Google Codejam algorithm from 2010, but the time complexity is awful.</p>

<p>Here is the question from Google Codejam: <a href="https://code.google.com/codejam/contest/619102/dashboard" rel="nofollow">https://code.google.com/codejam/contest/619102/dashboard</a></p>

<p>TLDR - Imagine two towers that have a number line running up the sides, we draw a line from one buildings number line (say from 10) to another point on the other buildings number line (say from 1). If we do this n times, how many times will those lines intersect?</p>

<p>I was wondering if anyone here is able to suggest a way in which I can speed up my algorithm? After 4 hours I really can't see one and I'm losing my miinnnnddd. </p>

<p>Here is my code as of right now.</p>

<p>An example input would be:</p>

<p>2 - (Number of cases)</p>

<p>3 - (Number of wires in case # 1)</p>

<p>1 10</p>

<p>5 5</p>

<p>7 7</p>

<p>Case #1: 2 - (2 intersections among lines 1,10 5,5 7,7)</p>

<p>2 - (Number of wires in case #2)</p>

<p>5 5</p>

<p>2 2</p>

<p>Case #2: 0 - (No lines intersect)</p>

<pre><code>def solve(wire_ints, test_case):
    answer_integer = 0
    for iterI in range(number_wires):
        for iterJ in range(iterI):
            holder = [wire_ints[iterI], wire_ints[iterJ]] 
            holder.sort()
            if holder[0][1] &gt; holder[1][1]:
                answer_integer = answer_integer + 1
    return("Case #" + str(test_case) + ":" + " " + str(answer_integer))

for test_case in range(1, int(input()) + 1):
  number_wires = int(input())
  wire_ints = []
  for count1 in range(number_wires):
    left_port,right_port = map(int, input().split())
    wire_ints.append((left_port,right_port))
  answer_string = solve(wire_ints, test_case)
  print(answer_string)
</code></pre>

<p>This algorithm does WORK for any input I give it, but as I said its very ugly and slow. </p>

<p>Help would be appreciated!</p>

<p>Since <code>N</code> is 1000 an algorithm with <code>O(N^2)</code> would be acceptable. So what you have to do is sort the wires by one of their end points.</p>

<pre><code>//sorted by first number
1 10    
5 5
7 7
</code></pre>

<p>Then you process each line from the beginning and check whether it has intersection with lines before it. If the second end point of a line before it is bigger than the second point of current line they have intersection. This requires two loops thus the <code>O(N^2)</code> complexity which suffice for <code>N=1000</code>. <br> Also you can interpret this as an inversion count. you have to count the number of inversions of the second end points where the list is sorted by first end point.</p>

<pre><code>10 5 7 -&gt;â number of inversions is 2, because of (10,5) and (10,7)
</code></pre>

<p>Also there is <a href="http://stackoverflow.com/questions/337664/counting-inversions-in-an-array"><code>O(NlogN)</code> approach</a> to count the number of inversions which you don't need for this question.</p>

python algorithm