Skip to content

Add inversion count via merge sort #377

Description

@0xDevNinja

Count the number of inversions in an array — pairs (i, j) with i < j and a[i] > a[j]. This is a measure of "out-of-orderness"; a sorted array has 0, a reverse-sorted array of length n has n(n-1)/2.

Modified merge sort: during the merge, every time you take an element from the right half before exhausting the left half, the remaining left-half elements all form inversions with that right-half element — accumulate the count. O(n log n) time, O(n) extra space.

A Fenwick-tree alternative also exists (coordinate-compress, sweep right-to-left, query prefix sum, then update). Either works; pick merge sort for educational clarity.

API sketch

  • New module src/sorting/inversion_count.rs.
  • pub fn count_inversions<T: Ord + Clone>(values: &[T]) -> u64 — returns the number of inversions; does not mutate input.
  • Internal merge_count(values: &mut [T]) -> u64 operating on a mutable working copy.

Acceptance criteria

  • Module under src/sorting/, exported from mod.rs.
  • Inline tests: empty → 0, single element → 0, sorted ascending → 0, strictly descending of length nn(n-1)/2, [2, 4, 1, 3, 5] → 3, repeated equal values (no inversions among equals — strict < semantics), random length-1000 cross-checked against the brute O(n²) reference.
  • Property test: brute-force O(n²) inversion-counter cross-checks on random Vec<i32> of length ≤ 100.
  • Doc comment explains the merge-step counting rule and gives O(n log n).
  • cargo fmt --check, cargo clippy --all-targets -- -D warnings, cargo test pass.

Reference

Wu & Miller, Daily Coding Problem, Problem #44 — "Determine how 'out of order' an array is".

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions