مسیرها
/
Factor
Factor
/
تمرین‌ها
/
خودروها، مونتاژ شوید!
خودروها، مونتاژ شوید!

خودروها، مونتاژ شوید!

تمرین یادگیری

مقدمه

این تمرین «دستورهای شرطی» را معرفی می‌کند: انتخاب بین دو یا چند مسیر اقدام بر اساس یک مقدار. این تمرین بر «مقادیر منطقی» بنا شده است؛ همان‌هایی که در نفوذ آنالین دیدید، به‌همراه محاسبات اعداد صحیح از تبدیل ارز.

واژه‌های مقایسه

همه‌ی این‌ها در math قرار دارند (و = در kernel):

=  ( x y -- ? )    ! equal
<  ( x y -- ? )    ! less than
<= ( x y -- ? )    ! less than or equal
>  ( x y -- ? )    ! greater than
>= ( x y -- ? )    ! greater than or equal
3 3 = .     ! => t
2 3 < .     ! => t
3 3 <= .    ! => t
3 4 = not . ! => t    (inequality: combine = with not)

zero? (در math) صورت کوتاه آزمون رایج 0 = است. عدد را مصرف می‌کند و اینکه صفر بوده یا نه را روی «پشته» می‌گذارد:

zero? ( n -- ? )    ! t when n is 0

بررسی بازه

between? (در math.order) آزمون می‌کند که آیا یک مقدار در یک بازه‌ی بسته قرار می‌گیرد یا نه. وقتی یک کنش بستگی دارد به اینکه یک عدد در کدام بازه می‌افتد، این واژه به کار می‌آید:

between? ( x lo hi -- ? )    ! lo <= x <= hi (inclusive)
5 1 10 between? .    ! => t
0 1 10 between? .    ! => f
10 1 10 between? .   ! => t   (inclusive at both ends)

اغلب آن را به‌عنوان «محمول» cond می‌بینید (dup 1 4 between?) تا شاخه را بر اساس بازه انتخاب کنید، نه بر اساس یک مقدار تنها.

نقل‌قول‌ها

واژه‌های مقایسه‌ی بالا مقادیر منطقی تولید می‌کنند؛ برای اینکه روی یک مقدار منطقی کاری انجام دهید، باید یک یا چند «نقل‌قول» به دستور شرطی بدهید. یک «نقل‌قول» تکه‌کدی است که در «کروشه» پیچیده شده است: [ ... ]. نوشتن آن، کد را به‌جای اجرا کردن به‌عنوان یک مقدار روی پشته می‌گذارد؛ سپس واژه‌ای مانند if تصمیم می‌گیرد که کدام نقل‌قول اجرا شود.

[ neg ]   ! a quotation that negates the top of the stack
[ ]       ! the empty quotation — does nothing

تمرین بعدی نقل‌قول‌ها را به‌طور کامل بررسی می‌کند؛ فعلاً [ ... ] را به‌معنای «کدی که برای این شاخه باید اجرا شود» بخوانید.

if، when، unless

if (در kernel) یک مقدار منطقی و دو نقل‌قول می‌گیرد. وقتی مقدار منطقی «درست» باشد نقل‌قول اول را اجرا می‌کند و وقتی «غلط» باشد نقل‌قول دوم را:

if ( ? then-quot else-quot -- )
: abs ( x -- y ) dup 0 < [ neg ] [ ] if ;

when نقل‌قول خود را فقط وقتی مقدار منطقی «درست» باشد اجرا می‌کند؛ unless فقط وقتی «غلط» باشد:

when   ( ? quot -- )
unless ( ? quot -- )

if*، when* و unless*

سه گونه در kernel مقدار منطقی را وقتی «درست» باشد، به‌عنوان یک مقدار ارزشمند برای نگه داشتن در نظر می‌گیرند. این وقتی به کار می‌آید که یک واژه «یک مقدار، یا f» را برمی‌گرداند:

if*     ( ? true false -- )    ! truthy: true is called WITH ? on stack
when*   ( ? true       -- )    ! truthy: true is called WITH ? on stack
unless* ( ? false      -- )    ! falsy: false runs and pushes a default

if* شکل دوشاخه‌ای است. شاخه‌ی «درست» با مقداری که هنوز روی پشته است فراخوانی می‌شود؛ شاخه‌ی «غلط» بدون آن فراخوانی می‌شود:

42 [ ] [ "nothing" ] if* .   ! prints 42
f  [ ] [ "nothing" ] if* .   ! prints "nothing"

unless* الگوی متعارف «مقدار یا مقدار پیش‌فرض» است. اگر مقدار «درست» باشد، دست‌نخورده رها می‌شود؛ اگر f باشد، مقدار حذف می‌شود و نقل‌قول اجرا می‌شود تا یک جانشین روی پشته بگذارد:

"hello" [ "anonymous" ] unless* .   ! => "hello"
f       [ "anonymous" ] unless* .   ! => "anonymous"

when* شکل یک‌شاخه‌ای if* است: نقل‌قول خود را (در حالی که مقدار هنوز روی پشته است) فقط وقتی مقدار «درست» باشد اجرا می‌کند و وقتی f باشد به‌سادگی مقدار را حذف می‌کند. سراغش بروید تا نتیجه‌ی «یک مقدار، یا f» را در یک مقدار جاری بگنجانید، بدون آنکه به سراغ حالت f بروید:

0 41 [ + ] when* .   ! => 41   (truthy: 41 added to the running total)
0 f  [ + ] when* .   ! => 0    (falsy: f dropped, total left untouched)

cond

وقتی چند کنش جایگزین برای انتخاب دارید، cond (در combinators) انتخاب طبیعی است. این واژه آرایه‌ای از جفت‌های { predicate body } می‌گیرد و بدنه‌ی نخستین محمولی را اجرا می‌کند که مقدار «درست» بدهد:

USING: combinators ;

: classify ( n -- label )
    {
        { [ dup 0 <  ] [ drop "negative" ] }
        { [ dup 0 =  ] [ drop "zero"     ] }
        [ drop "positive" ]
    } cond ;

چند نکته که ارزش توجه دارند:

  • جفت‌ها به ترتیب بررسی می‌شوند. نخستین تطابق برنده است.
  • ورودی‌ای بدون محمول (فقط یک نقل‌قول) در پایان، به‌عنوان حالت پیش‌فرض عمل می‌کند.
  • هر محمول ورودی را بررسی می‌کند، اما باید پشته‌ی داده را همان‌طور که آن را پیدا کرده رها کند؛ الگوی معمول dup ... <test> است.
  • بدنه‌ی جفت انتخاب‌شده همان پشته‌ای را می‌گیرد که محمول دیده بود، بنابراین معمولاً با drop کردن ورودی و گذاشتن نتیجه شروع می‌شود.

دستورالعمل‌ها

در این تمرین کدی می‌نویسید که تولید یک خط مونتاژ در کارخانه‌ی خودروسازی را تحلیل کند. سرعت خط مونتاژ می‌تواند از 0 (خاموش) تا 10 (حداکثر) متغیر باشد.

در پایین‌ترین سرعت غیرصفر (1)، هر ساعت 221 خودرو تولید می‌شود. تولید به‌صورت خطی با سرعت افزایش می‌یابد، بنابراین در سرعت 4، خط مونتاژ هر ساعت 4 * 221 = 884 خودرو تولید می‌کند. با این حال، سرعت‌های بالاتر احتمال تولید خودروهای معیوب را بیشتر می‌کنند، خودروهایی که بعد باید دور انداخته شوند.

شما چهار کار دارید. هر کدام یک پارامتر صحیح را از پشته برمی‌دارد که همان سرعت خط مونتاژ است.

1. گزارش کنید که خط در حال کار است یا نه

production-status را طوری تعریف کنید که وقتی سرعت 0 است "stopped" و برای هر سرعت دیگری "running" برگرداند:

0 production-status .
! => "stopped"
3 production-status .
! => "running"

2. نرخ موفقیت را محاسبه کنید

success-rate را طوری تعریف کنید که احتمال تولید یک خودرو بدون خطا را برگرداند:

  • 0: 0.0
  • 1 تا 4: 1.0
  • 5 تا 8: 0.9
  • 9: 0.8
  • 10: 0.77
10 success-rate .
! => 0.77

3. نرخ تولید در ساعت را محاسبه کنید

production-rate-per-hour را طوری تعریف کنید که نرخ تولید خط مونتاژ در ساعت را با در نظر گرفتن نرخ موفقیت برگرداند.

اول باید base-speed را تعریف کنید، یعنی ثابت 221.

6 production-rate-per-hour .
! => 1193.4

مقداری که برگردانده می‌شود یک عدد اعشاری است.

4. تعداد خودروهای سالم تولیدشده در دقیقه را محاسبه کنید

working-items-per-minute را طوری تعریف کنید که برگرداند در هر دقیقه چند خودروی سالم تولید می‌شود. نتیجه یک عدد صحیح است؛ خودروهای ناقص شمرده نمی‌شوند.

6 working-items-per-minute .
! => 19
ویرایش از طریق GitHub این لینک در پنجره یا زبانه‌ی جدیدی باز می‌شود
Factor Exercism

آماده‌اید خودروها، مونتاژ شوید! را شروع کنید؟

در Exercism ثبت‌نام کنید تا Factor را همراه با 47 مفهوم163 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.