Skip to content

Commit 59fec2a

Browse files
Added dutch_national_flag.py in sorts. fixing [TheAlgorithms#4636]
1 parent b931537 commit 59fec2a

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

Diff for: sorts/dutch_national_flag.py

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
from typing import List, Any, Tuple
2+
import random
3+
4+
# These constants stores the relative order of the 3 'colors' 0, 1 and 2.
5+
# They can be changed as per the requirement of the user.
6+
# The colors need not be represented by integers, they can also be other comparable or incomparable objects.
7+
RED = 0 # In this case this is the first color of the flag.
8+
WHITE = 1 # This is the second color of the flag.
9+
BLUE = 2 # This is the third color of the flag.
10+
COLORS = (RED, WHITE, BLUE)
11+
"""
12+
The Dutch-National-Flag problem is a problem designed by Edsger Dijkstra. This is called so because the flag of Netherlands
13+
or Dutch flag is composed of three colors and the sequence of numbers it seeks to sort is composed of 3 unique repeated values.
14+
These values can be in any order (0,1,2) in our examples but can be made to be anything by assigning the value to RED, WHITE and BLUE
15+
in that order.
16+
17+
The objective is to sort these n numbers composed of 3 unique repeated values in the most optimal way, that is O(n) (better than the normal
18+
list.sort() method in Python which has the complexity of O(n)). Another way to solve it is by using Counting Sort but that requires 2
19+
passes and depending on the size of array could be much more expensive than DNF algorithm (twice as much).
20+
21+
The idea is to maintain 4 regions inside of the sequence provided (marked by l, mid and r index).
22+
for a sequence of size n:
23+
Region 1 : sequence[0...l-1] should be colored RED
24+
Region 2 : sequence[l...mid-1] should be colored WHITE
25+
Region 3 : sequence[mid...r] is an unknown color that we must process
26+
Region 4 : sequence[r...n] should be colored BLUE
27+
28+
More can be read here : https://en.wikipedia.org/wiki/Dutch_national_flag_problem
29+
30+
"""
31+
def dutch_national_flag(sequence : List, colors:Tuple[Any]=COLORS) -> None:
32+
"""
33+
This method sorts the sequence of 3 colors given in the order in COLORS constant tuple. This method assumes (0<1<2)
34+
but the order can be anything.
35+
Inputs :
36+
colors : Tuple[Any] -> a relative ordered tuple of objects that correspond to RED, WHITE and BLUE colors of the flag (in that order).
37+
sequence : List[any] -> a sequence of length n with values a[0], a[1], a[2] ... a[n-2], a[n-1] where a[i] in COLORS
38+
input example : [0, 0, 2, 2, 2, 1, 1, 2, 2, 1]
39+
output example : [0, 0, 1, 1, 1, 2, 2, 2, 2, 2]
40+
Sorts the array in place in a single pass. O(n) time complexity and O(1) space complexity
41+
>>> from collections import Counter
42+
>>> arr1 = [random.choice(COLORS) for _ in range(100)]
43+
>>> arr2 = arr1.copy()
44+
>>> counter = Counter(arr1)
45+
>>> arr1 = [COLORS[0] for _ in range(counter[COLORS[0]])]+[COLORS[1] for _ in range(counter[COLORS[1]])]+\
46+
[COLORS[2] for _ in range(counter[COLORS[2]])]
47+
>>> dutch_national_flag(arr2)
48+
>>> arr1 == arr2
49+
True
50+
"""
51+
COLORS = colors
52+
if sequence is None: return
53+
if len(sequence) <= 1: return
54+
l = 0
55+
mid = 0
56+
r = len(sequence)-1
57+
while mid <= r:
58+
if sequence[mid] == COLORS[0]:
59+
sequence[l], sequence[mid] = sequence[mid], sequence[l]
60+
l+=1
61+
mid+=1
62+
continue
63+
64+
if sequence[mid] == COLORS[1]:
65+
mid+=1
66+
continue
67+
68+
if sequence[mid] == COLORS[2]:
69+
sequence[r], sequence[mid] = sequence[mid], sequence[r]
70+
r-=1
71+
continue
72+
73+
raise ValueError(f"Invalid value {sequence[mid]} inside of sequence. The elements inside the sequence must \
74+
be in {COLORS} tuple.")
75+
76+
return
77+
78+
79+
def main()->None:
80+
"""
81+
Main method to run doctests
82+
>>> pass
83+
"""
84+
import doctest
85+
doctest.testmod()
86+
87+
88+
if __name__ == "__main__":
89+
main()

0 commit comments

Comments
 (0)