مسیرها
/
Clojure
Clojure
/
تمرین‌ها
/
تبدیل مختصات
تبدیل مختصات

تبدیل مختصات

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

مقدمه

«بستار» یک الگوی برنامه‌نویسی در Clojure است که اجازه می‌دهد از متغیرهای یک دامنه‌ی واژگانی بیرونی درون یک تابع استفاده شود. Clojure از بستارها به‌صورت شفاف پشتیبانی می‌کند و اغلب بدون آنکه بدانید چه هستند از آن‌ها استفاده می‌شود.

;; Top-level definitions are global-scope
(def dozen 12)

;; Functions create a new scope.
;; Referencing the outer variable here is a closure.
(fn [n] (* dozen n))

بستار برای ذخیره‌ی وضعیت و انتقال مقادیر

با استفاده از atom می‌توان مقداری از وضعیت را حفظ کرد:

;; This function closure increments the counter's state
;; in the outer lexical context.
;; This way the counter can be shared between many calling contexts.

(def increment
  (let [counter (atom 0)]
    (fn [] (swap! counter inc))))

هر فراخوانی پیاپی increment شمارنده‌اش را یک واحد افزایش می‌دهد:

(increment)
;;=> 1
(increment)
;;=> 2

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

شرکت طراحی شما عمدتاً با تبدیل‌های CSS برای ساخت صفحات وب کار کرده است. پس از بحث و گفت‌وگو، تصمیم گرفته می‌شود که برای انجام برخی محاسبات به‌صورت پویا از Clojure استفاده شود. برخی از هم‌تیمی‌های شما تجربه‌ی کمتری با Clojure دارند، بنابراین تصمیم می‌گیرید از یک «بستار» برای ساختن تبدیل‌های قابل استفاده‌ی مجدد برای جفت‌های مختصات {x, y} استفاده کنید.

1. مختصات را انتقال دهید

تابع translate2d را پیاده‌سازی کنید که تابعی را برمی‌گرداند و با استفاده از یک «بستار»، انتقال دوبعدی تکرارپذیر یک جفت مختصات را انجام می‌دهد.

(def move-coordinates-right-2px (translate2d 2 0))
(def result (move-coordinates-right-2px 4 8))
;; result => [6 8]

2. مختصات را تغییر مقیاس دهید

تابع scale2d را پیاده‌سازی کنید که تابعی را برمی‌گرداند و با استفاده از یک بستار، تغییر مقیاس دوبعدی تکرارپذیر یک جفت مختصات را انجام می‌دهد.

در این تمرین، فرض کنید مقادیر مقیاس فقط مثبت‌اند.

(def double-scale (scale2d 2 2))
(def result (double-scale 6 -3))
;; result => [12 -6]

3. توابع تبدیل را ترکیب کنید

دو تابع تبدیل را ترکیب کنید تا یک تبدیل تکرارپذیر انجام دهید. به این کار معمولاً ترکیب توابع می‌گویند که در آن نتیجه‌ی تابع اول، 'f(x)'، به عنوان ورودی تابع دوم، 'g(x)'، استفاده می‌شود.

(def move-coordinates-right-2px (translate2d 2 0))
(def double-coordinates (scale2d 2 2))
(def composed-transformations 
  (compose-transform move-coordinates-right-2px 
                     double-coordinates))
(def result (composed-transformations 0 1))
;; result => [4 2]

4. نتایج توابع را ذخیره کنید

تابع memoize-transform را پیاده‌سازی کنید. این تابع، تابعی را برای حافظه‌سازی می‌گیرد و سپس تابع جدیدی برمی‌گرداند که ورودی‌های تابع داده‌شده را به خاطر می‌سپارد، به طوری که آخرین مقدار بازگشتی «به خاطر سپرده می‌شود» و در صورت فراخوانی دوباره با همان آرگومان‌ها، فقط یک بار محاسبه می‌گردد.

به حافظه‌سازی گاهی برنامه‌نویسی پویا هم می‌گویند؛ این کار اجازه می‌دهد عملیات پرهزینه فقط یک بار انجام شوند، چون نتیجه‌شان به خاطر سپرده می‌شود.

(def triple-scale (scale2d 3 3))
(def memoized-scale (memoize-transform triple-scale))

(memoized-scale 4 3)
;; => [12, 9], this is computed since it hasn't been computed before for the arguments

(memoized-scale 4 3)
;; => [12, 9], this is remembered, since it was computed already
ویرایش از طریق GitHub این لینک در پنجره یا زبانه‌ی جدیدی باز می‌شود
Clojure Exercism

آماده‌اید تبدیل مختصات را شروع کنید؟

در Exercism ثبت‌نام کنید تا Clojure را همراه با 12 مفهوم105 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.