«مجموعهی ناهمپوشان» (ساختار یکیکردن و یافتن) مجموعهای از مقدارها را نگه میدارد که به گروههای بدون همپوشانی تقسیم شدهاند و بهسرعت به یک پرسش پاسخ میدهد: آیا این دو مقدار در یک گروه قرار دارند؟ این ساختار در واژگان disjoint-sets قرار دارد.
<disjoint-set> یک ساختار خالی میسازد. مقدارها (که «اتم» نامیده میشوند) با add-atom یکییکی، یا با add-atoms از روی یک دنباله اضافه میشوند. هر اتم در ابتدا در گروه خودش قرار میگیرد.
<disjoint-set> ( -- disjoint-set )
add-atom ( atom disjoint-set -- )
add-atoms ( seq disjoint-set -- )
USING: disjoint-sets ;
<disjoint-set>
{ 1 2 3 } over add-atoms ! 1, 2 and 3 each in their own group
مجموعهی ناهمپوشان «تغییرپذیر» است: add-atom، add-atoms و equate آن را در جای خود تغییر میدهند، نه اینکه نمونهی تازهای برگردانند. وقتی میخواهید مجموعهی ناهمپوشان پس از آنکه یکی از این واژهها آن را مصرف کرد دوباره روی پشته قرار بگیرد، keep به کارتان میآید.
equate دو گروهی را که اتمهایش در آنها قرار دارند یکی میکند. یکیکردن گذراست: دو اتم را با equate یکی کنید، سپس یکی از آن دو را با اتم سومی، و هر سه در یک گروه قرار میگیرند.
equate ( atom1 atom2 disjoint-set -- )
هر گروه یک عضو متعارف دارد، «نماینده»ی آن. representative آن نماینده را برمیگرداند، و دو اتم دقیقاً زمانی در یک گروه قرار دارند که نمایندههایشان برابر باشند.
representative ( atom disjoint-set -- representative )
USING: disjoint-sets ;
<disjoint-set>
{ 1 2 3 } over add-atoms
1 2 pick equate
1 over representative . ! => 1
2 over representative . ! => 1 (same representative as 1)
3 over representative . ! => 3 (still on its own)
اینکه یک گروه کدام اتم را بهعنوان نمایندهاش برمیگزیند، یک جزئیات درونی است؛ هرگز به برگزیده شدن اتمی خاص تکیه نکنید، و تنها به این تکیه کنید که نمایندهی دو اتم در یک گروه یکسان باشد.
باشگاه شعر محلی فصل تازهای را آغاز میکند. شاعران به باشگاه میپیوندند و هر بار که دو نفرشان با هم شعری بنویسند، بخشی از یک «حلقهی نوشتن» مشترک میشوند. باشگاه میخواهد بداند چه کسی حلقهاش را با چه کسی شریک است و از شما خواسته شده است واژههایی را بنویسید که این کار را مدیریت میکنند.
یک «مجموعهی مجزا» دقیقاً همان چیزی است که به کار میآید: هر شاعر یک اتم است و هر حلقهی نوشتن یک گروه.
new-club را تعریف کنید؛ این واژه دنبالهای از شاعران میگیرد و یک مجموعهی مجزای تازه برمیگرداند که هر شاعر در آن ثبت شده است. هر شاعر کار را در حلقهی نوشتن خودش آغاز میکند.
{ "Keats" "Byron" "Dickinson" } new-club
! => a disjoint set holding the three poets
collaborate را تعریف کنید؛ این واژه دو شاعر و یک باشگاه میگیرد. حلقههای نوشتن آن دو شاعر را در هم ادغام میکند و باشگاه را برمیگرداند، تا همکاریها یکی پس از دیگری ثبت شوند.
{ "Keats" "Byron" "Dickinson" } new-club
"Keats" "Byron" rot collaborate
! => the club, with Keats and Byron now in one circle
circle-of را تعریف کنید؛ این واژه یک شاعر و یک باشگاه میگیرد و نمایندهی حلقهی نوشتن آن شاعر را برمیگرداند. دو شاعری که در یک حلقهاند همیشه نمایندهی یکسانی را گزارش میکنند.
{ "Keats" "Byron" "Dickinson" } new-club
"Dickinson" swap circle-of
! => "Dickinson" (still in a circle of their own)
same-circle? را تعریف کنید؛ این واژه دو شاعر و یک باشگاه میگیرد و اگر هر دو شاعر به یک حلقهی نوشتن تعلق داشته باشند t و در غیر این صورت f را برمیگرداند. بهجای استفاده از آزمون همارزی توکار، نمایندههای شاعران را با هم مقایسه کنید.
{ "Keats" "Byron" "Dickinson" } new-club
"Keats" "Byron" rot collaborate
dup [ "Keats" "Byron" ] dip same-circle? . ! => t
[ "Keats" "Dickinson" ] dip same-circle? . ! => f