مسیرها
/
Julia
Julia
/
تمرین‌ها
/
جادوهای الیز
جادوهای الیز

جادوهای الیز

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

مقدمه

یکی از اهداف اصلی Julia این است که بتواند محاسبات را روی داده‌های عددی، سریع و کارآمد انجام دهد. کلی داده‌ی عددی.

معمولاً این داده‌ها در آرایه‌ها (یا نوع مرتبط دیگری) ذخیره می‌شوند، بنابراین می‌توان گفت که آرایه‌ها در قلب زبان Julia قرار دارند.

آرایه‌ها می‌توانند اندازه‌ی دلخواه داشته باشند (فقط محدود به حافظه‌ی سخت‌افزار شما) و می‌توانند هر تعداد بُعد داشته باشند.

این مفهوم مقدماتی بر مبانی آرایه‌های یک‌بعدی تمرکز دارد، که به آن‌ها Vector می‌گویند.

ساختن Vector

در Julia، یک Vector دنباله‌ی مرتبی از مقادیر است که می‌توان با شماره‌ی اندیس به آن‌ها دسترسی داشت.

ساده‌ترین راه برای ساختن یک Vector این است که مقادیر را داخل کروشه فهرست کنید:

julia> num_vec = [1, 4, 9]
3-element Vector{Int64}:
 1
 4
 9

julia> str_vec = ["arrays", "are", "important"]
3-element Vector{String}:
 "arrays"
 "are"
 "important"

نوع Vector با نوع هر عنصر مطابقت دارد.

یعنی Vectorها باید همگن باشند (همه‌ی عناصر از یک نوع)؟

تا حدی بله، و اگر بهترین کارایی را می‌خواهید توصیه می‌شود همین را هدف بگیرید. با این حال، Julia می‌تواند (در صورت لزوم) با استفاده از نوع Any این محدودیت را دور بزند:

julia> mixed_vector = [1, "str", 'c']
3-element Vector{Any}:
 1
  "str"
  'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)

هنگام ساختن یک Vector خالی، Julia به‌طور پیش‌فرض نوع عنصر را Any در نظر می‌گیرد، اما می‌توان با حاشیه‌نویسی آرایه‌ی خالی با نوع عنصر موردنظر، آن را دقیق‌تر تعریف کرد.

julia> empty_vec = []
Any[]

julia> empty_int_vec = Int64[]
Int64[]

لطفاً این قاعده را بخوانید و به خاطر بسپارید:

  • به‌طور پیش‌فرض، اندیس‌گذاری در Julia از ۱ شروع می‌شود، نه ۰.

این برای هر کسی که از زبان‌های دیگر علم داده (R، Matlab، Fortran...) استفاده کرده باشد آشناست، اما ممکن است برای دانشمندان رایانه‌ای با پیشینه‌ی زبان‌های شبیه C تکان‌دهنده به نظر برسد.

در غیر این صورت، اندیس‌ها همان‌طور که حدس می‌زنید کار می‌کنند: کافی است آن‌ها را داخل کروشه بگذارید:

squares = [0, 1, 4, 9, 16]
squares[1]  # 0
squares[3]  # 4
squares[begin]  # 0 ("begin" is synonym for 1)
squares[end]  # 16 ("end" is synonym for length(squares))

به سادگیِ اندیس‌گذاری با end (که بسیار مفید است) و begin (که احتمالاً نیست) توجه کنید.

برنامه‌نویسان Python ممکن است درباره‌ی اندیس‌های منفی کنجکاو باشند. دنبالشان نگردید: این‌ها بخشی از Julia نیستند و باعث خطای BoundsError می‌شوند، همان‌طور که هر اندیسی کوچک‌تر از ۱ یا بزرگ‌تر از length(squares) چنین می‌کند.

عملیات روی Vector

Vectorها در Julia تغییرپذیر هستند: می‌توانیم محتویات خانه‌های تک‌تک را تغییر دهیم.

julia> vals = [1, 3, 5, 7]
4-element Vector{Int64}:
 1
 3
 5
 7

julia> vals[2] = 4  # reassign the value of this element
4

# Only the value at position 2 changes:
julia> vals
4-element Vector{Int64}:
 1
 4
 5
 7

توابع زیادی برای دستکاری Vectorها در دسترس است، هرچند مستندات Julia آن‌ها را به‌جای بردار به «مجموعه‌ها» تعمیم می‌دهد.

توجه کنید که بنا بر قرارداد، توابعی که ورودی خود را تغییر می‌دهند در اسمشان ! دارند. کامپایلر این را اجبار نمی‌کند، اما در دنیای Julia یک قرارداد بسیار قوی است.

این‌ها چند تا از توابع مفید هستند:

  • برای افزودن مقادیر به انتهای Vector، از push!() استفاده کنید.
  • برای حذف آخرین مقدار، از pop!() استفاده کنید.
  • برای کار روی ابتدای Vector، توابع متناظر pushfirst!() و popfirst!() هستند.
  • برای درج یا حذف یک عنصر در هر موقعیتی، insert!() و deleteat!() وجود دارند.
julia> vals = [1, 3]
2-element Vector{Int64}:
 1
 3

julia> push!(vals, 5, 6)  # can add multiple values
4-element Vector{Int64}:
 1
 3
 5
 6

julia> pop!(vals)  # mutates vals, return popped value
6

julia> vals
3-element Vector{Int64}:
 1
 3
 5

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

الیس به‌عنوان یک شعبده‌باز تازه‌کار باید چند مقدمه را تمرین کند. او یک دسته کارت دارد که می‌خواهد آن‌ها را دست‌کاری کند.

برای اینکه کار کمی ساده‌تر شود، فقط از کارت‌های ۱ تا ۱۰ استفاده می‌کند، بنابراین دسته‌ی کارت‌هایش را می‌توان با یک بردار از اعداد نمایش داد. موقعیت یک کارت مشخص با اندیس آن در بردار متناظر است.

1. برداشتن یک کارت از دسته

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

julia> stack = [1, 2, 4, 1];
julia> position = 3;
julia> get_item(stack, position)
4

2. تعویض یک کارت در دسته

کمی تردستی کنید و کارت واقع در اندیس position را با کارت جایگزینی که داده شده است عوض کنید. دسته‌ی تغییرداده‌شده را برگردانید.

julia> stack = [1, 2, 4, 1];
julia> position = 3;
julia> replacement_card = 6;
julia> set_item!(stack, position, replacement_card)
[1, 2, 6, 1]

3. درج یک کارت در بالای دسته

با درج یک کارت جدید در بالای دسته، کارتی را ظاهر کنید. دسته‌ی تغییرداده‌شده را برگردانید.

julia> stack = [5, 9, 7, 1];
julia> new_card = 8;
julia> insert_item_at_top!(stack, new_card)
[5, 9, 7, 1, 8]

4. حذف یک کارت از دسته

با حذف کارت واقع در position داده‌شده از دسته، کارتی را ناپدید کنید. دسته‌ی تغییرداده‌شده را برگردانید.

julia> stack = [3, 2, 6, 4, 8];
julia> position = 3;
julia> remove_item!(stack, position)
[3, 2, 4, 8]

5. حذف کارت بالای دسته

با حذف کارت بالای دسته، کارتی را ناپدید کنید. دسته‌ی تغییرداده‌شده را برگردانید.

julia> stack = [3, 2, 6, 4, 8];
julia> remove_item_from_top!(stack)
[3, 2, 6, 4]

6. درج یک کارت در پایین دسته

با درج یک کارت جدید در پایین دسته، کارتی را ظاهر کنید. دسته‌ی تغییرداده‌شده را برگردانید.

julia> stack = [5, 9, 7, 1];
julia> new_card = 8;
julia> insert_item_at_bottom!(stack, new_card)
[8, 5, 9, 7, 1]

7. حذف یک کارت از پایین دسته

با حذف کارت پایین دسته، کارتی را ناپدید کنید. دسته‌ی تغییرداده‌شده را برگردانید.

julia> stack = [8, 5, 9, 7, 1];
julia> remove_item_at_bottom!(stack)
[5, 9, 7, 1]

8. بررسی اندازه‌ی دسته

بررسی کنید که اندازه‌ی دسته با stack_size برابر است یا نه.

julia> stack = [3, 2, 6, 4, 8];
julia> stack_size = 4;
julia> check_size_of_stack(stack, stack_size)
false
ویرایش از طریق GitHub این لینک در پنجره یا زبانه‌ی جدیدی باز می‌شود
Julia Exercism

آماده‌اید جادوهای الیز را شروع کنید؟

در Exercism ثبت‌نام کنید تا Julia را همراه با 35 مفهوم128 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.