ExamplesBy LevelBy TopicLearning Paths
837 Fundamental

Closest Pair of Points — Divide and Conquer

Functional Programming

Tutorial Video

Text description (accessibility)

This video demonstrates the "Closest Pair of Points — Divide and Conquer" functional Rust example. Difficulty level: Fundamental. Key concepts covered: Functional Programming. Finding the two closest points in a set of n points naively requires O(n^2) distance comparisons. Key difference from OCaml: | Aspect | Rust | OCaml |

Tutorial

The Problem

Finding the two closest points in a set of n points naively requires O(n^2) distance comparisons. Divide-and-conquer solves this in O(n log n): split points by x-coordinate median, recursively find closest pairs in left and right halves, then check the strip of width 2*delta around the dividing line for cross-half pairs. The key insight: within the strip, each point needs to be compared against at most 7 others — a fixed constant, making the strip check O(n) total. This algorithm appears in geographic information systems (nearest neighbor queries), robotics (obstacle proximity), and computational chemistry (molecular interaction detection).

🎯 Learning Outcomes

  • • Split points at median x, recurse on halves, combine with strip check
  • • Understand the strip argument: at most 7 points fit in a delta×2*delta rectangle
  • • Implement the strip check: sort by y-coordinate, slide a window of 8 points
  • • Recognize the O(n log n) recurrence: T(n) = 2T(n/2) + O(n log n) for strip sort
  • • Optimize to true O(n log n) by maintaining y-sorted arrays through recursion
  • Code Example

    #![allow(clippy::all)]
    //! Placeholder

    Key Differences

    AspectRustOCaml
    Array mutationIn-place sort on &mut [Point]Array.sort (in-place)
    SplittingSlice indexing &mut points[..mid]Array.sub (copies)
    StripVec<&Point> — referencesPoint list or Point array
    Base case size<= 3Same
    True O(n log n)Sort by x once, maintain y-orderList.merge approach
    Parallel variantrayon::join for halvesNo built-in parallel

    OCaml Approach

    OCaml sorts with Array.sort and splits using Array.sub. The recursive calls work on sub-arrays. The strip check uses Array.to_list |> List.filter then List.sort by y-coordinate, followed by a sliding window. OCaml's List.fold_left computes the minimum distance in the strip. The functional style returns a new sorted-by-y array at each level (merge-sort style) for the true O(n log n) variant. Float.min combines the two recursive distances.

    Full Source

    #![allow(clippy::all)]
    //! Placeholder

    Deep Comparison

    OCaml vs Rust: Closest Pair Divide Conquer

    Overview

    See the example.rs and example.ml files for detailed implementations.

    Key Differences

    AspectOCamlRust
    Type systemHindley-MilnerOwnership + traits
    MemoryGCZero-cost abstractions
    MutabilityExplicit refmut keyword
    Error handlingOption/ResultResult<T, E>

    See README.md for detailed comparison.

    Exercises

  • Implement the true O(n log n) variant that avoids re-sorting the strip by maintaining y-sorted arrays.
  • Extend to 3D: find the closest pair of points in 3D space using the same divide-and-conquer approach.
  • Use Rayon to parallelize the two recursive halves and measure speedup on 10^6 points.
  • Implement a KD-tree and compare its closest-pair query time against the divide-and-conquer algorithm.
  • Verify correctness by comparing with brute-force O(n^2) on random point sets of size up to 1000.
  • Open Source Repos