user
*Szymański's algorithm* is a mutual exclusion algorithm devised by computer scientist Bolesław Szymański.

The algorithm allows mutiple processes or tasks to access a serial resource without conflict, using only linear waiting times.
It has application in multitasking and communications, especially if there is a need for massive parallelism with limited
waiting times for access to resources by the parallel program's components.

Task

* Implement Szymanski's algorithm utilizing parallel processes, threads, or similar coroutines.
* Your example should implement the steps shown in the Wikipedia's pseudocode at the Wikipedia reference below.

See also

* [Wikipedia entry for Szymański's algorithm] * [ACM digital entry for Szymański's paper]

"""
Szymański's algorithm reference:
Boleslaw K. Szymanski. A simple solution to Lamport's concurrent programming problem with linear wait.
Proceedings of the 2nd International Conference on Supercomputing, 1988, Figure 2, Page 624.
https://dl.acm.org/doi/pdf/10.1145/55364.55425
https://en.wikipedia.org/wiki/Szyma%C5%84ski%27s\_algorithm
"""
assistant
```
# 20230822 Raku programming solution

use OO::Monitors;

my \N = 10;

monitor Szymański {

   has @.tasks;
   my $critical = 0;

   method runSzymański($id) {
      @.tasks[$id] = 1; 
      ( my @others = @.tasks ).splice: $id,1;
      until @others.all ~~ 0|1|2 { $*THREAD.yield }
      @.tasks[$id] = 3; 
      if @others.any ~~ 1 {
         @.tasks[$id] = 2;
         until @others.any ~~ 4 { $*THREAD.yield }
      }
      @.tasks[$id] = 4;
      until @.tasks[^$id].all ~~ 0|1 { $*THREAD.yield }
      $critical = ((my $previous = $critical) + $id * 3) div 2;
      say "Thread $id changed the critical value from $previous to $critical";
      until @.tasks[$id^..*-1].all ~~ 0|1|4 { $*THREAD.yield }
      @.tasks[$id] = 0
   }
}

my $flag = Szymański.new: tasks => 0 xx N;
await Promise.allof( ^N .pick(*).map: { start { $flag.runSzymański: $_ } } );

```

Output:

```
Thread 6 changed the critical value from 0 to 9
Thread 1 changed the critical value from 9 to 6
Thread 5 changed the critical value from 6 to 10
Thread 4 changed the critical value from 10 to 11
Thread 7 changed the critical value from 11 to 16
Thread 9 changed the critical value from 16 to 21
Thread 8 changed the critical value from 21 to 22
Thread 3 changed the critical value from 22 to 15
Thread 2 changed the critical value from 15 to 10
Thread 0 changed the critical value from 10 to 5
```