Skip to content

Commit 757d4fb

Browse files
Added Dutch National Flag algorithm TheAlgorithms#4636 (TheAlgorithms#4639)
* Added Dutch national flag sort Algorithm * Changed file name to dnf_sort.py * Added descriptive name and type hint Added descriptive name and type hint for parameter with doctest for the function dnf_sort. * Added test cases * Added doctest cases * Update sorts/dnf_sort.py * Added doctest for dutch_national_flag_sort sorts/dnf_sort.py * Update sorts/dnf_sort.py * Added doctest for the function dutch_national_flag_sort * update file as per black code formatter * Update dnf_sort.py * Update and rename dnf_sort.py to dutch_national_flag_sort.py Co-authored-by: Christian Clauss <[email protected]>
1 parent ef98271 commit 757d4fb

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

sorts/dutch_national_flag_sort.py

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
"""
2+
A pure implementation of Dutch national flag (DNF) sort algorithm in Python.
3+
Dutch National Flag algorithm is an algorithm originally designed by Edsger Dijkstra.
4+
It is the most optimal sort for 3 unique values (eg. 0, 1, 2) in a sequence. DNF can
5+
sort a sequence of n size with [0 <= a[i] <= 2] at guaranteed O(n) complexity in a
6+
single pass.
7+
8+
The flag of the Netherlands consists of three colors: white, red, and blue.
9+
The task is to randomly arrange balls of white, red, and blue in such a way that balls
10+
of the same color are placed together. DNF sorts a sequence of 0, 1, and 2's in linear
11+
time that does not consume any extra space. This algorithm can be implemented only on
12+
a sequence that contains three unique elements.
13+
14+
1) Time complexity is O(n).
15+
2) Space complexity is O(1).
16+
17+
More info on: https://en.wikipedia.org/wiki/Dutch_national_flag_problem
18+
19+
For doctests run following command:
20+
python3 -m doctest -v dutch_national_flag_sort.py
21+
22+
For manual testing run:
23+
python dnf_sort.py
24+
"""
25+
26+
27+
# Python program to sort a sequence containing only 0, 1 and 2 in a single pass.
28+
red = 0 # The first color of the flag.
29+
white = 1 # The second color of the flag.
30+
blue = 2 # The third color of the flag.
31+
colors = (red, white, blue)
32+
33+
34+
def dutch_national_flag_sort(sequence: list) -> list:
35+
"""
36+
A pure Python implementation of Dutch National Flag sort algorithm.
37+
:param data: 3 unique integer values (e.g., 0, 1, 2) in an sequence
38+
:return: The same collection in ascending order
39+
40+
>>> dutch_national_flag_sort([])
41+
[]
42+
>>> dutch_national_flag_sort([0])
43+
[0]
44+
>>> dutch_national_flag_sort([2, 1, 0, 0, 1, 2])
45+
[0, 0, 1, 1, 2, 2]
46+
>>> dutch_national_flag_sort([0, 1, 1, 0, 1, 2, 1, 2, 0, 0, 0, 1])
47+
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
48+
>>> dutch_national_flag_sort("abacab")
49+
Traceback (most recent call last):
50+
...
51+
ValueError: The elements inside the sequence must contains only (0, 1, 2) values
52+
>>> dutch_national_flag_sort("Abacab")
53+
Traceback (most recent call last):
54+
...
55+
ValueError: The elements inside the sequence must contains only (0, 1, 2) values
56+
>>> dutch_national_flag_sort([3, 2, 3, 1, 3, 0, 3])
57+
Traceback (most recent call last):
58+
...
59+
ValueError: The elements inside the sequence must contains only (0, 1, 2) values
60+
>>> dutch_national_flag_sort([-1, 2, -1, 1, -1, 0, -1])
61+
Traceback (most recent call last):
62+
...
63+
ValueError: The elements inside the sequence must contains only (0, 1, 2) values
64+
>>> dutch_national_flag_sort([1.1, 2, 1.1, 1, 1.1, 0, 1.1])
65+
Traceback (most recent call last):
66+
...
67+
ValueError: The elements inside the sequence must contains only (0, 1, 2) values
68+
"""
69+
if not sequence:
70+
return []
71+
if len(sequence) == 1:
72+
return list(sequence)
73+
low = 0
74+
high = len(sequence) - 1
75+
mid = 0
76+
while mid <= high:
77+
if sequence[mid] == colors[0]:
78+
sequence[low], sequence[mid] = sequence[mid], sequence[low]
79+
low += 1
80+
mid += 1
81+
elif sequence[mid] == colors[1]:
82+
mid += 1
83+
elif sequence[mid] == colors[2]:
84+
sequence[mid], sequence[high] = sequence[high], sequence[mid]
85+
high -= 1
86+
else:
87+
raise ValueError(
88+
f"The elements inside the sequence must contains only {colors} values"
89+
)
90+
return sequence
91+
92+
93+
if __name__ == "__main__":
94+
import doctest
95+
96+
doctest.testmod()
97+
98+
user_input = input("Enter numbers separated by commas:\n").strip()
99+
unsorted = [int(item.strip()) for item in user_input.split(",")]
100+
print(f"{dutch_national_flag_sort(unsorted)}")

0 commit comments

Comments
 (0)