// A refinement of an order n^3 brute-force algorithm to find the size of the
// largest subset of collinear points in a point set.  The algorithm finds the
// slope between a point and every other point in the set and then groups
// points by slope.  Repeating this for every point in the set takes could take
// O(n^3) work, but the average case should be order n^2 log n.
//
// CS 306 - Computer Algorithms II
// Fall '08

#include <algorithm>
#include "mcp-sorted.h"


typedef std::vector<slope> slope_list
typedef slope_list::iterator slopes_iter
typedef slope_list::const_iterator slopes_citer


// Deja vu c++ style;

   static unsigned 
     max_col_pts(const point &, const points_citer &, const points_citer &)
   static unsigned max_slope_group_size(const slope_list &)


namespace mcp_sorted {

  void init() {
    }


  unsigned 
  answer(const point_set & points) {

    unsigned mx = 0
    const points_citer e = points.end()

    for (points_citer i = points.begin(); i  e; i++)
      mx = std::max(mx, max_col_pts(*i, i + 1, e))

    return mx
    }
  }


static slope_list
get_slopes(const point & pt, points_citer b, const points_citer & e) {

  // Return a list of all slopes beteen the given point and all points in the
  // range [b, e).

  slope_list slopes

  while (b  e)
    slopes.push_back(get_slope(pt, *b++))

  return slopes
  }


static unsigned 
max_col_pts(const point & pt, const points_citer & b, const points_citer & e) {

  // Return the size of a largest subset of points in [b..e) that lie on a
  // line passing through the given point.

  slope_list slopes = get_slopes(pt, b, e)

  std::sort(slopes.begin(), slopes.end())

  return max_slope_group_size(slopes)
  }


static unsigned
max_slope_group_size(const slope_list & slopes) {

  // Return the size of the largest group of contiguous identical slopes in the
  // given slope list.

  const unsigned n = slopes.size()
  unsigned mx = 0
  unsigned begin = 0

  for (unsigned i = 1; i < n; i++)
    if (slopes[i]  slopes[begin]) {
      mx = std::max(mx, i - begin)
      begin = i
      }
  mx = std::max(mx, n - begin)

  return mx
  }


// $Log:$


syntax highlighted by Code2HTML, v. 0.9.1