chameneos.pp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. { The Computer Language Shootout
  2. http://shootout.alioth.debian.org
  3. contributed by Marc Weustink
  4. }
  5. program chameneos;
  6. {$mode objfpc}{$h-}
  7. uses
  8. PThreads;
  9. type
  10. TColor = (Blue, Red, Yellow, Faded);
  11. var
  12. waitfirst,
  13. waitsecond : TSemaphore;
  14. first,second : TColor;
  15. MeetingsLeft : Integer;
  16. ThreadInfo : array[0..3] of record
  17. Id: TThreadId;
  18. StartColor: TColor;
  19. Count: Integer;
  20. end;
  21. function Complement(c1,c2:TColor):TColor;
  22. begin
  23. if c2=Faded then
  24. begin
  25. result:=Faded;
  26. exit;
  27. end;
  28. if c1=c2 then
  29. begin
  30. result:=c1;
  31. exit;
  32. end;
  33. case c1 of
  34. Blue :
  35. if c2=Red then
  36. result:=Yellow
  37. else
  38. result:=Red;
  39. Red :
  40. if c2=Blue then
  41. result:=Yellow
  42. else
  43. result:=Blue;
  44. Yellow :
  45. if c2=Blue then
  46. result:=Red
  47. else
  48. result:=Blue;
  49. else
  50. result:=c1;
  51. end;
  52. end;
  53. function OtherCreaturesColor(me:TColor):TColor;
  54. const
  55. firstcall : boolean = true;
  56. begin
  57. result:=Faded;
  58. sem_wait(waitfirst);
  59. if firstCall then
  60. begin
  61. if MeetingsLeft>0 then
  62. begin
  63. first:=me;
  64. firstcall:=false;
  65. sem_post(waitfirst);
  66. sem_wait(waitsecond);
  67. result:=second;
  68. dec(MeetingsLeft);
  69. end;
  70. sem_post(waitfirst);
  71. end
  72. else
  73. begin
  74. firstcall:=true;
  75. second:=me;
  76. result:=first;
  77. sem_post(waitsecond);
  78. end;
  79. end;
  80. function ThreadFunc(AIndex: PtrInt): Pointer; cdecl;
  81. var
  82. Meetings : Integer;
  83. me,other : TColor;
  84. begin
  85. me := ThreadInfo[AIndex].StartColor;
  86. Meetings := 0;
  87. while (me<>Faded) do
  88. begin
  89. other:=OtherCreaturesColor(me);
  90. if other=Faded then
  91. break;
  92. inc(Meetings);
  93. me:=Complement(me,other);
  94. end;
  95. ThreadInfo[AIndex].Count := Meetings;
  96. result:=nil;
  97. end;
  98. const
  99. COLOR: array[0..3] of TColor = (Blue, Red, Yellow, Blue);
  100. var
  101. n: Integer;
  102. Attr: TThreadAttr;
  103. p: Pointer;
  104. begin
  105. Val(paramstr(1), MeetingsLeft, n);
  106. if n <> 0 then exit;
  107. sem_init(waitfirst,0,1);
  108. sem_init(waitsecond,0,0);
  109. pthread_attr_init(Attr);
  110. pthread_attr_setdetachstate(Attr, 0);
  111. pthread_attr_setstacksize(Attr, 1024 * 16);
  112. for n := 0 to 3 do begin
  113. ThreadInfo[n].Count := 0;
  114. ThreadInfo[n].StartColor := COLOR[n];
  115. pthread_create(ThreadInfo[n].Id, Attr, TStartRoutine(@ThreadFunc), Pointer(n));
  116. end;
  117. for n := 0 to 3 do
  118. pthread_join(ThreadInfo[n].Id, p);
  119. WriteLN(ThreadInfo[0].Count + ThreadInfo[1].Count + ThreadInfo[2].Count + ThreadInfo[3].Count);
  120. end.