Fix negative indexing bug and improve readability in wiggle_sort - #15371
Conversation
Issue: - The previous implementation used `enumerate(nums)`, starting the loop at `i = 0`. This caused `nums[i - 1]` to evaluate to `nums[-1]`, accidentally comparing (and potentially swapping) the first element with the last element of the array on the first iteration. - The conditional logic `(i % 2 == 1) == (nums[i - 1] > nums[i])` was convoluted, hard to read, and triggered unnecessary swaps when adjacent numbers were equal. Fix: - Changed the loop to use `range(1, len(nums))` to ensure the index safely starts at 1, eliminating the negative indexing bug. - Replaced the confusing equality check with explicit `if/elif` statements that clearly define the peak (odd indices) and valley (even indices) requirements of a Wiggle Sort. - Preserved all original docstrings and the __main__ block as-is.
for more information, see https://pre-commit.ci
- Updated `wiggle_sort` logic to merge the odd and even swap conditions using a single `or` expression. - Fixes SIM114 ruff linter check failure (`Combine if branches using logical or operator`).
for more information, see https://pre-commit.ci
- Updated expected outputs for negative array doctests in `sorts/wiggle_sort.py`. - The previous doctest expectations relied on the incorrect behavior caused by the index-0 negative lookup bug. - Fixes pytest doctest mismatch failure in CI build job.
|
@priya-sundaram-dev, please review. Does sorts/wiggle_sort.py really have a bug? If so, is this the right fix? |
|
ON HOLD: Our focus is on merging or closing old pull requests before October 1st. |
|
I dug into this. Short version: the new code is a genuine readability win and its logic is correct, but I'd frame the PR as clarity, not a correctness fix — because the old code doesn't actually produce wrong output. Is there really a bug? The That's also why the doctests had to change: e.g. Is the fix right? Yes. (i % 2 == 1 and nums[i - 1] > nums[i]) or (i % 2 == 0 and nums[i - 1] < nums[i])is exactly the correct swap rule (odd Suggestion: retitle to something like "Clarify wiggle_sort logic and start loop at index 1" and reword the description to say the old code did a spurious first/last swap (harmless but confusing) rather than "accidentally comparing … the first with the last" implying broken output. With that framing this is a clean 👍 from me. |
|
Reviewed. Recommendation: merge as a readability/robustness cleanup — but the "bug" framing overstates it. The refactor itself is good and I'd take it:
One correction for the PR title/description, though: this does not fix incorrect sort output. I exhaustively checked the old implementation over every multiset of length ≤ 7 with values 0–4 (and 20k random cases up to length 7) — it always produced a valid wiggle ( So: happy to see it merged for clarity and to kill the negative-index wraparound; I'd just retitle it something like "wiggle_sort: drop accidental negative-index swap and clarify" rather than "fix bug", so the history is accurate. |
|
Merged 4 hours ago. ;-) |
Issue:
enumerate(nums), starting the loop ati = 0. This causednums[i - 1]to evaluate tonums[-1], accidentally comparing (and potentially swapping) the first element with the last element of the array on the first iteration.(i % 2 == 1) == (nums[i - 1] > nums[i])was convoluted, hard to read, and triggered unnecessary swaps when adjacent numbers were equal.Fix:
range(1, len(nums))to ensure the index safely starts at 1, eliminating the negative indexing bug.if/elifstatements that clearly define the peak (odd indices) and valley (even indices) requirements of a Wiggle Sort.Describe your change
Checklist