Skip to content

feat: add closest pair of points algorithm #1706

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

feat: add closest pair of points algorithm #1706

wants to merge 1 commit into from

Conversation

saahil-mahato
Copy link

Open in Gitpod know more

Describe your change:

  • Add an algorithm?
  • Fix a bug or typo in an existing algorithm?
  • Documentation change?

Checklist:

  • I have read CONTRIBUTING.md.
  • This pull request is all my own work -- I have not plagiarized.
  • I know that pull requests will not be merged if they fail the automated tests.
  • This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
  • All new JavaScript files are placed inside an existing directory.
  • All filenames should use the UpperCamelCase (PascalCase) style. There should be no spaces in filenames.
    Example:UserProfile.js is allowed but userprofile.js,Userprofile.js,user-Profile.js,userProfile.js are not
  • All new algorithms have a URL in their comments that points to Wikipedia or another similar explanation.
  • If this pull request resolves one or more open issues then the commit message contains Fixes: #{$ISSUE_NO}.

@saahil-mahato saahil-mahato changed the title fix: style feat: add closest pair of points algorithm Oct 2, 2024
@codecov-commenter
Copy link

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 84.78%. Comparing base (9010481) to head (322ca8e).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1706      +/-   ##
==========================================
+ Coverage   84.65%   84.78%   +0.12%     
==========================================
  Files         378      379       +1     
  Lines       19744    19904     +160     
  Branches     2951     2978      +27     
==========================================
+ Hits        16715    16875     +160     
  Misses       3029     3029              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Collaborator

@appgurueu appgurueu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks like a fine addition, however I have some comments.

* @see {@link https://en.wikipedia.org/wiki/Closest_pair_of_points_problem}
* @class
*/
export default class ClosestPair {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be a class. Instead, it should be simply an exported function which takes an array of points and returns the closest pair. All methods here should be just functions or closures inside that function.

The tests then simplify to testing that single function.

}

/**
* Finds the closest pair of points in a small set (3 or fewer).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "3 or fewer" is just how this is used. This method supports arbitrarily many points (but of course has quadratic time complexity). I would document this as "to be used with small sets"; there is no strict requirement here.

This "brute force" function could also be reused for testing with random points.

}

/**
* Finds the closest pair in a strip of points sorted by y-coordinate.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is wrong. Since the function sorts by Y coordinate, it is not a requirement that the strip be sorted by Y coordinate. In fact it won't be, because it's sorted by X coordinate.

/**
* Gets the strip of points within a certain distance from a midpoint.
* @private
* @param {Array<{x: number, y: number}>} points - An array of sorted points.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorted by X coordinate

* @returns {Array<{x: number, y: number}>} The filtered strip of points.
*/
#getStripPoints(points, midPoint, minDistance) {
return points.filter(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't matter for the asymptotic worst case and might make the code a bit harder to follow, but this can be optimized by leveraging the fact that the points are sorted by X and thus doing a binary search to find the bounds.

let pair = []

// Sort by y-coordinate
strip.sort((a, b) => a.y - b.y)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably implies a time complexity of $O(n(\log{n})^2)$ overall, correct?

expect(result.distance).toBe(0) // Distance between identical points is zero
})

test('handles large number of points correctly', () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't actually tested.

As said, I would recommend testing against the brute force search.

@saahil-mahato saahil-mahato closed this by deleting the head repository Oct 27, 2024
@appgurueu
Copy link
Collaborator

😕

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants