123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- { The Computer Language Shootout
- http://shootout.alioth.debian.org
- contributed by Marc Weustink
- }
- program chameneos;
- {$mode objfpc}{$h-}
- uses
- PThreads;
- type
- TColor = (Blue, Red, Yellow, Faded);
- var
- waitfirst,
- waitsecond : TSemaphore;
- first,second : TColor;
- MeetingsLeft : Integer;
- ThreadInfo : array[0..3] of record
- Id: TThreadId;
- StartColor: TColor;
- Count: Integer;
- end;
- function Complement(c1,c2:TColor):TColor;
- begin
- if c2=Faded then
- begin
- result:=Faded;
- exit;
- end;
- if c1=c2 then
- begin
- result:=c1;
- exit;
- end;
- case c1 of
- Blue :
- if c2=Red then
- result:=Yellow
- else
- result:=Red;
- Red :
- if c2=Blue then
- result:=Yellow
- else
- result:=Blue;
- Yellow :
- if c2=Blue then
- result:=Red
- else
- result:=Blue;
- else
- result:=c1;
- end;
- end;
- function OtherCreaturesColor(me:TColor):TColor;
- const
- firstcall : boolean = true;
- begin
- result:=Faded;
- sem_wait(waitfirst);
- if firstCall then
- begin
- if MeetingsLeft>0 then
- begin
- first:=me;
- firstcall:=false;
- sem_post(waitfirst);
- sem_wait(waitsecond);
- result:=second;
- dec(MeetingsLeft);
- end;
- sem_post(waitfirst);
- end
- else
- begin
- firstcall:=true;
- second:=me;
- result:=first;
- sem_post(waitsecond);
- end;
- end;
- function ThreadFunc(AIndex: PtrInt): Pointer; cdecl;
- var
- Meetings : Integer;
- me,other : TColor;
- begin
- me := ThreadInfo[AIndex].StartColor;
- Meetings := 0;
- while (me<>Faded) do
- begin
- other:=OtherCreaturesColor(me);
- if other=Faded then
- break;
- inc(Meetings);
- me:=Complement(me,other);
- end;
- ThreadInfo[AIndex].Count := Meetings;
- result:=nil;
- end;
- const
- COLOR: array[0..3] of TColor = (Blue, Red, Yellow, Blue);
- var
- n: Integer;
- Attr: TThreadAttr;
- p: Pointer;
- begin
- Val(paramstr(1), MeetingsLeft, n);
- if n <> 0 then exit;
- sem_init(waitfirst,0,1);
- sem_init(waitsecond,0,0);
- pthread_attr_init(Attr);
- pthread_attr_setdetachstate(Attr, 0);
- pthread_attr_setstacksize(Attr, 1024 * 16);
- for n := 0 to 3 do begin
- ThreadInfo[n].Count := 0;
- ThreadInfo[n].StartColor := COLOR[n];
- pthread_create(ThreadInfo[n].Id, Attr, TStartRoutine(@ThreadFunc), Pointer(n));
- end;
- for n := 0 to 3 do
- pthread_join(ThreadInfo[n].Id, p);
- WriteLN(ThreadInfo[0].Count + ThreadInfo[1].Count + ThreadInfo[2].Count + ThreadInfo[3].Count);
- end.
|