Skip to content

feat(algorithms, graphs): sort items by group#190

Merged
BrianLusina merged 3 commits intomainfrom
feat/algorithms-graphs-sort-items
Mar 19, 2026
Merged

feat(algorithms, graphs): sort items by group#190
BrianLusina merged 3 commits intomainfrom
feat/algorithms-graphs-sort-items

Conversation

@BrianLusina
Copy link
Copy Markdown
Owner

@BrianLusina BrianLusina commented Mar 19, 2026

Describe your change:

Sort items by group

  • 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 Python files are placed inside an existing directory.
  • All filenames are in all lowercase characters with no spaces or dashes.
  • All functions and variable names follow Python naming conventions.
  • All function parameters and return values are annotated with Python type hints.
  • All functions have doctests that pass the automated testing.
  • All new algorithms have a URL in its comments that points to Wikipedia or other similar explanation.
  • If this pull request resolves one or more open issues then the commit message contains Fixes: #{$ISSUE_NO}.

Summary by CodeRabbit

  • New Features

    • Added a graph-based sorting algorithm to order items by group while respecting dependency constraints.
  • Documentation

    • New detailed documentation for the "Sort Items by Groups" problem, including problem statement, examples, solution outline and complexity notes.
    • Directory index updated to list the new entry.
  • Tests

    • Added a comprehensive test suite covering multiple scenarios validating the algorithm.

@BrianLusina BrianLusina self-assigned this Mar 19, 2026
@BrianLusina BrianLusina added enhancement Algorithm Algorithm Problem Datastructures Datastructures Documentation Documentation Updates Sorting Contains sorting in the algorithm Graph Graph data structures and algorithms Array Array data structure Hash Map Hash Map Data structure Queue Depth First Search Topological Sort Breadth First Search labels Mar 19, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 19, 2026

📝 Walkthrough

Walkthrough

Adds a new "Sort Items by Groups" graph algorithm with implementation, documentation, and parameterised unit tests to order items respecting prerequisites and group contiguity.

Changes

Cohort / File(s) Summary
Documentation
DIRECTORY.md, algorithms/graphs/sort_items_by_group/README.md
Added directory entry and a comprehensive README describing problem statement, input/output, examples, algorithm outline (hierarchical topological sort), and complexity.
Implementation
algorithms/graphs/sort_items_by_group/__init__.py
New sort_items(n, m, group, before_items) implementing group normalisation, item- and group-level DAG construction, Kahn-style topological sorts, and final concatenation by group order. Review cross-group edge handling and indegree bookkeeping.
Testing
algorithms/graphs/sort_items_by_group/test_sort_items_by_groups.py
Added parameterised unittest module with multiple test cases and exact-order assertions for expected outputs. Verify test coverage includes cycle and edge cases.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through nodes both near and far,

grouped my friends and chased each bar,
edges bowed down and cycles fled,
order found where chaos led,
now lists line up — hooray, we sped! 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description follows the required template structure with all major sections completed. However, the description is overly vague and generic, merely stating 'Sort items by group' without explaining the specific problem, constraints, or approach. Provide a more detailed description of the problem being solved, key constraints (e.g., dependency handling, group contiguity), and a brief overview of the algorithmic approach used.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarises the main change: adding a new algorithm for sorting items by group in the graphs category.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/algorithms-graphs-sort-items
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
algorithms/graphs/sort_items_by_group/__init__.py (2)

10-13: Input mutation: the group list is modified in place.

The function mutates the caller's group list by reassigning -1 values. This side effect could cause unexpected behaviour for callers who reuse the list after calling sort_items. Consider working on a copy instead.

♻️ Suggested fix to avoid mutating input
+    # Create a copy to avoid mutating the input
+    group = group.copy()
+
     # Assign new group IDs to ungrouped items. -1 means ungrouped
     for i in range(n):
         if group[i] == -1:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@algorithms/graphs/sort_items_by_group/__init__.py` around lines 10 - 13, The
loop for i in range(n) currently mutates the caller's group list by replacing -1
values (group and m); to avoid this, make and use a local copy (e.g., group_copy
= group[:] or list(group)) inside sort_items and perform the for i in range(n)
assignments against that copy (and use group_copy anywhere later in the
function) so the original group passed by the caller remains unchanged while
preserving the same numbering logic with m.

30-33: Optional: Consider deduplicating group-level edges.

When multiple items from one group depend on items from another group, duplicate edges are added to group_graph. While the algorithm still produces correct results (the in-degree counts balance with the duplicate edge traversals), this is inefficient for graphs with many inter-group dependencies.

♻️ Optional fix using a set to track added edges
+    # Track added group edges to avoid duplicates
+    added_group_edges: set[tuple[int, int]] = set()
+
     # Build dependency graphs
     for current in range(n):
         for previous in before_items[current]:
             # Add item-level edge
             item_graph[previous].append(current)
             item_indegree[current] += 1

             # Add group-level edge
             if group[previous] != group[current]:
-                group_graph[group[previous]].append(group[current])
-                group_indegree[group[current]] += 1
+                edge = (group[previous], group[current])
+                if edge not in added_group_edges:
+                    added_group_edges.add(edge)
+                    group_graph[group[previous]].append(group[current])
+                    group_indegree[group[current]] += 1
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@algorithms/graphs/sort_items_by_group/__init__.py` around lines 30 - 33,
Multiple duplicate inter-group edges are being added to group_graph and
incrementing group_indegree redundantly; modify the logic around group_graph and
group_indegree (the block that checks if group[previous] != group[current]) to
deduplicate edges by tracking added group-pair edges (e.g., a set of tuples or a
set per source group) and only append to group_graph[group[previous]] and
increment group_indegree[group[current]] when the pair (group[previous],
group[current]) has not been seen before; keep references to the existing
symbols group_graph, group_indegree, group, previous, and current so the check
is performed inline before mutating those structures.
algorithms/graphs/sort_items_by_group/test_sort_items_by_groups.py (1)

32-33: Consider validating constraints rather than exact equality.

The problem states that multiple valid orderings may exist. Using assertEqual for exact match means the test will fail if the implementation is refactored to produce a different (but still valid) ordering. For more robust tests, consider validating that:

  1. All n items are present exactly once
  2. Dependency order is respected: for each item i, all items in before_items[i] appear before i
  3. Group contiguity: items of the same group appear consecutively
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@algorithms/graphs/sort_items_by_group/test_sort_items_by_groups.py` around
lines 32 - 33, The test currently asserts exact equality between expected and
actual, which is brittle; modify the test in test_sort_items_by_groups.py so
that after calling actual = sort_items(n, m, group, before_items) you instead
(1) verify all n items appear exactly once (compare sorted(actual) to
list(range(n)) or counts), (2) build an index map pos[item]=index and assert for
each i that every j in before_items[i] satisfies pos[j] < pos[i], and (3) verify
group contiguity by grouping items by group id (use the provided group list) and
ensuring that in actual each group’s items occupy a single continuous span (no
interleaving). Use the variables n, m, group, before_items, and the function
sort_items to locate code to change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@algorithms/graphs/sort_items_by_group/README.md`:
- Around line 140-152: Update the README complexity section to reflect the
actual Kahn topological-sort implementation rather than subset recursion:
replace the O(n·2^n) time and recursive stack description with Time: O(n + m +
E) where n = number of items, m = number of groups, and E = total edges (sum of
lengths of beforeItems[i]) because each node and edge is processed once in
Kahn's algorithm; replace the space section to Space: O(n + m + E) accounting
for adjacency lists, in-degree arrays, and the queue used during Kahn’s
algorithm (exclude output storage if you treat it as external). Ensure you
reference beforeItems, in-degree arrays, adjacency lists, and the queue in the
updated text so readers can map the complexity to the implementation.

---

Nitpick comments:
In `@algorithms/graphs/sort_items_by_group/__init__.py`:
- Around line 10-13: The loop for i in range(n) currently mutates the caller's
group list by replacing -1 values (group and m); to avoid this, make and use a
local copy (e.g., group_copy = group[:] or list(group)) inside sort_items and
perform the for i in range(n) assignments against that copy (and use group_copy
anywhere later in the function) so the original group passed by the caller
remains unchanged while preserving the same numbering logic with m.
- Around line 30-33: Multiple duplicate inter-group edges are being added to
group_graph and incrementing group_indegree redundantly; modify the logic around
group_graph and group_indegree (the block that checks if group[previous] !=
group[current]) to deduplicate edges by tracking added group-pair edges (e.g., a
set of tuples or a set per source group) and only append to
group_graph[group[previous]] and increment group_indegree[group[current]] when
the pair (group[previous], group[current]) has not been seen before; keep
references to the existing symbols group_graph, group_indegree, group, previous,
and current so the check is performed inline before mutating those structures.

In `@algorithms/graphs/sort_items_by_group/test_sort_items_by_groups.py`:
- Around line 32-33: The test currently asserts exact equality between expected
and actual, which is brittle; modify the test in test_sort_items_by_groups.py so
that after calling actual = sort_items(n, m, group, before_items) you instead
(1) verify all n items appear exactly once (compare sorted(actual) to
list(range(n)) or counts), (2) build an index map pos[item]=index and assert for
each i that every j in before_items[i] satisfies pos[j] < pos[i], and (3) verify
group contiguity by grouping items by group id (use the provided group list) and
ensuring that in actual each group’s items occupy a single continuous span (no
interleaving). Use the variables n, m, group, before_items, and the function
sort_items to locate code to change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 852b3f77-8b9f-4069-b217-9b079c9dd820

📥 Commits

Reviewing files that changed from the base of the PR and between 79b7801 and baefd0f.

⛔ Files ignored due to path filters (3)
  • algorithms/graphs/sort_items_by_group/images/examples/sort_items_by_groups_respecting_dependencies_example_1.png is excluded by !**/*.png
  • algorithms/graphs/sort_items_by_group/images/examples/sort_items_by_groups_respecting_dependencies_example_2.png is excluded by !**/*.png
  • algorithms/graphs/sort_items_by_group/images/examples/sort_items_by_groups_respecting_dependencies_example_3.png is excluded by !**/*.png
📒 Files selected for processing (4)
  • DIRECTORY.md
  • algorithms/graphs/sort_items_by_group/README.md
  • algorithms/graphs/sort_items_by_group/__init__.py
  • algorithms/graphs/sort_items_by_group/test_sort_items_by_groups.py

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@algorithms/graphs/sort_items_by_group/README.md`:
- Line 27: Update the constraint sentence in the README.md so it reads
"beforeItems[i] does not contain duplicate elements" instead of "duplicates
elements"; locate the line referencing beforeItems[i] in the constraints section
and correct the adjective "duplicates" to "duplicate".

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 77cf8108-ad0e-4187-aadb-abeebd6af022

📥 Commits

Reviewing files that changed from the base of the PR and between baefd0f and 52ace6c.

📒 Files selected for processing (1)
  • algorithms/graphs/sort_items_by_group/README.md

@BrianLusina BrianLusina merged commit d11f015 into main Mar 19, 2026
6 of 8 checks passed
@BrianLusina BrianLusina deleted the feat/algorithms-graphs-sort-items branch March 19, 2026 09:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Algorithm Algorithm Problem Array Array data structure Breadth First Search Datastructures Datastructures Depth First Search Documentation Documentation Updates enhancement Graph Graph data structures and algorithms Hash Map Hash Map Data structure Queue Sorting Contains sorting in the algorithm Topological Sort

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant