Dutch national flag problem: Difference between revisions

From Rosetta Code
Content added Content deleted
m (J)
(→‎{{header|Python}}: Split into sections for second version)
Line 46: Line 46:


=={{header|Python}}==
=={{header|Python}}==
===Python: Sorted===
The heart of the idiomatic Dutch sort in python is the call to function <code>sorted</code> in function dutch_flag_sort.
The heart of the idiomatic Dutch sort in python is the call to function <code>sorted</code> in function dutch_flag_sort.
<lang python>import random
<lang python>import random
Line 84: Line 85:
<pre>Original Ball order: ['Red', 'Red', 'Blue', 'Blue', 'Blue', 'Red', 'Red', 'Red', 'White', 'Blue']
<pre>Original Ball order: ['Red', 'Red', 'Blue', 'Blue', 'Blue', 'Red', 'Red', 'Red', 'White', 'Blue']
Sorted Ball Order: ['Red', 'Red', 'Red', 'Red', 'Red', 'White', 'Blue', 'Blue', 'Blue', 'Blue']</pre>
Sorted Ball Order: ['Red', 'Red', 'Red', 'Red', 'Red', 'White', 'Blue', 'Blue', 'Blue', 'Blue']</pre>

===Python: sum of filters===

Revision as of 06:31, 2 July 2012

Dutch national flag problem is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

The Dutch national flag is composed of three coloured bands in the order red then white and lastly blue. The problem posed by Edsger Dijkstra is:

Given a number of red, blue and white balls in random order, arrange them in the order of the colours Dutch national flag.

When the problem was first posed, Dijkstra then went on to successively refine a solution, minimising the number of swaps and the number of times the colour of a ball needed to determined and restricting the balls to end in an array, ...

This task is to
  1. Generate a randomized order of balls ensuring that they are not in the order of the Dutch national flag.
  2. Sort the balls in a way idiomatic to your language.
  3. Check the sorted balls are in the order of the Dutch national flag.
Cf.

J

We shall define a routine to convert the values 0 1 2 to ball names:

<lang J>i2b=: {&(;:'red white blue')</lang>

and its inverse

<lang J>b2i=: i2b inv</lang>

Next, we need a random assortment of balls:

<lang J> BALLS=: i2b ?20#3

  BALLS

┌────┬───┬────┬───┬───┬─────┬─────┬─────┬────┬────┬─────┬────┬────┬───┬────┬───┬─────┬───┬────┬───┐ │blue│red│blue│red│red│white│white│white│blue│blue│white│blue│blue│red│blue│red│white│red│blue│red│ └────┴───┴────┴───┴───┴─────┴─────┴─────┴────┴────┴─────┴────┴────┴───┴────┴───┴─────┴───┴────┴───┘</lang>

And we want to sort them in their canonical order:

<lang J> /:~&.b2i BALLS ┌───┬───┬───┬───┬───┬───┬───┬─────┬─────┬─────┬─────┬─────┬────┬────┬────┬────┬────┬────┬────┬────┐ │red│red│red│red│red│red│red│white│white│white│white│white│blue│blue│blue│blue│blue│blue│blue│blue│ └───┴───┴───┴───┴───┴───┴───┴─────┴─────┴─────┴─────┴─────┴────┴────┴────┴────┴────┴────┴────┴────┘</lang>

Note that if we were not using J's built in sort, we would probably want to use bin sort here.

Anyways, we can test that they are indeed sorted properly:

<lang J> assert@(-: /:~)&b2i /:~&.b2i BALLS</lang>


Python

Python: Sorted

The heart of the idiomatic Dutch sort in python is the call to function sorted in function dutch_flag_sort. <lang python>import random

colours_in_order = 'Red White Blue'.split()

def dutch_flag_sort(items, order=colours_in_order):

   'return sort of items using the given order'
   return sorted(items, key=lambda x: order.index(x))

def dutch_flag_check(items, order=colours_in_order):

   'Return True if each item of items is in the given order'
   order_of_items = [order.index(item) for item in items]
   return all(x <= y for x, y in zip(order_of_items, order_of_items[1:]))

def random_balls(mx=5):

   'Select from 1 to mx balls of each colour, randomly'
   balls = sum(([[colour] * random.randint(1, mx)
                for colour in colours_in_order]), [])
   random.shuffle(balls)
   return balls

def main():

   # Ensure we start unsorted
   while 1:
       balls = random_balls()
       if not dutch_flag_check(balls):
           break
   print("Original Ball order:", balls)
   sorted_balls = dutch_flag_sort(balls)
   print("Sorted Ball Order:", sorted_balls)
   assert dutch_flag_check(sorted_balls), 'Whoops. Not sorted!'

if __name__ == '__main__':

   main()</lang>
Sample output;
Original Ball order: ['Red', 'Red', 'Blue', 'Blue', 'Blue', 'Red', 'Red', 'Red', 'White', 'Blue']
Sorted Ball Order: ['Red', 'Red', 'Red', 'Red', 'Red', 'White', 'Blue', 'Blue', 'Blue', 'Blue']

Python: sum of filters