Find the longest uninterrupted arc

Python 3, O(n*log(n)), 167 bytes

import math
def f(p):p=[math.atan2(*x)for x in p];q=sorted(p);d=[b-a for a,b in zip(q,q[1:])]+[math.pi*2-q[-1]+q[0]];i=d.index(max(d));return map(p.index,(q*2)[i:i+2])

Try it online!

The sorting step takes O(n*log(n)) time, all other steps take linear time.


import math
def f(p):
  p=[math.atan2(x, y)for x, y in p]   # convert coords to angle (radians)
  q=sorted(p)                         # sort by angle
  d=[b-a for a,b in zip(q,q[1:])]     # calculate the difference between two adjacent points
  d+=[math.pi*2-q[-1]+q[0]]           # difference between first and last point
  i=d.index(max(d))                   # where is the maximum delta?
  return map(p.index,(q*2)[i:i+2])    # where were these two points in the original list?

JavaScript (Node.js), O(n), 234 229 228 211 bytes


Try it online!


  • atan2 is O(1)
  •, x.filter are O(n) function calls
  • x.indexOf is O(n)

  n=a.length,[t,u])=>Math.atan2(t,u)/Math.PI+2),    // [1, 3)
  // interval = 2/n, just enough
  ),  // furthest

APL (Dyalog Unicode), O(n), 92 bytes


Try it online!

Takes input as a vector of complex numbers and outputs a single array of the two indices. This uses bucket sort to achieve linear complexity.

Requires ⎕IO←0


L←12○⎕   ⍝ Take input to L and convert all points to their phases  -- O(n)
n←⍴L     ⍝ Set n to be the length of L                             
x←n⍴⊂⍬   ⍝ Create an array consisting of `n` empty buckets         -- O(n)
L{...}¨⍳n  ⍝ For each ⍺=element of of L, ⍵=corresponding index:    -- ×n:
  ⍺⍵         ⍝ Create an entry consisting of the two-element array ⍺ ⍵    -- O(1)
  x[...],←⊂⊂ ⍝ Append it to the correct bucket in x                       -- O(1)
  ⌊n×.5+⍺÷○2 ⍝ Map phases in [-pi, pi) to bucket indices in 0..n-1        -- O(1)
x          ⍝ Now, x is a vector of buckets,
           ⍝ each of which contains a vector of entries (phase, index)
{⍵[⍋⊃¨⍵]}¨ ⍝ Sort each bucket by phase (buckets contain 1 element on average, so this is O(1) average case per bucket)
⊃,/        ⍝ Join so we have a single sorted vector of all entries (phase, index)
{...}      ⍝ Computationally less-worrisome part now that we have the phases sorted
           ⍝ Most following lines are O(n), rest are O(1)
  ⊃¨         ⍝ Extract the phase of of each entry
  {⍵,⍵+○2}   ⍝ Add 2pi to each phase, and append (deals with wrapping around)
  2-/        ⍝ Compute the difference of each consecutive pair of phases
               ⍝ (always negative since the phases are increasing)
  ⊃⍸(⌊/=⊢)   ⍝ Find the index i of the minimum difference (most negative --- furthest)
  ⍵⌽⍨        ⍝ Rotate the original vector of (phase, index) by i
  2↑         ⍝ Take the first 2 entries
  1∘⊃¨       ⍝ Get the indices of these two entries