Skip to content

Heaps algorithm iterative #2505

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

Merged
merged 16 commits into from
Sep 29, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions divide_and_conquer/heaps_algorithm_iterative.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""
Heap's (iterative) algorithm returns the list of all permutations possible from a list.
It minimizes movement by generating each permutation from the previous one
by swapping only two elements.
More information:
https://en.wikipedia.org/wiki/Heap%27s_algorithm.
"""


def heaps(arr: list) -> list:
"""
Pure python implementation of the iterative Heap's algorithm,
returning all permutations of a list.
>>> heaps([])
[()]
>>> heaps([0])
[(0,)]
>>> heaps([-1, 1])
[(-1, 1), (1, -1)]
>>> heaps([1, 2, 3])
[(1, 2, 3), (2, 1, 3), (3, 1, 2), (1, 3, 2), (2, 3, 1), (3, 2, 1)]
>>> from itertools import permutations
>>> sorted(heaps([1,2,3])) == sorted(permutations([1,2,3]))
True
>>> all(sorted(heaps(x)) == sorted(permutations(x))
... for x in ([], [0], [-1, 1], [1, 2, 3]))
True
"""
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"""
>>> all(sorted(heaps(x)) == sorted(permutations(x)) for x in ([], [0], [-1, 1], [1, 2, 3]))
True
"""

Copy link
Member

Choose a reason for hiding this comment

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

Then I think we are ready to land this one.

Copy link
Contributor Author

@grochedix grochedix Sep 28, 2020

Choose a reason for hiding this comment

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

Modified the iterative version as well as the recursive one (#2475 ) with your suggestion.
Thanks for reviewing ! 👍

Edit: I see there is a problem with pytest but looks like you're working on it so i leave it like that for now.


if len(arr) <= 1:
return [tuple(arr)]

res = []

def generate(n: int, arr: list):
c = [0] * n
res.append(tuple(arr))

i = 0
while i < n:
if c[i] < i:
if i % 2 == 0:
arr[0], arr[i] = arr[i], arr[0]
else:
arr[c[i]], arr[i] = arr[i], arr[c[i]]
res.append(tuple(arr))
c[i] += 1
i = 0
else:
c[i] = 0
i += 1

generate(len(arr), arr)
return res


if __name__ == "__main__":
user_input = input("Enter numbers separated by a comma:\n").strip()
arr = [int(item) for item in user_input.split(",")]
print(heaps(arr))