Треки
/
Julia
Julia
/
Вправи
/
Чари Еліз
Чари Еліз

Чари Еліз

Навчальна вправа

Вступ

Одна з головних цілей Julia - уміти швидко й ефективно виконувати обчислення над числовими даними. Багато числових даних.

Зазвичай дані зберігаються в масивах (або в якомусь спорідненому типі), тож цілком слушно сказати, що масиви лежать у самому серці мови Julia.

Масиви можуть бути довільного розміру (обмеженого лише обсягом памʼяті обладнання) і мати довільну кількість вимірів.

Цей вступний концепт зосереджується на основах одновимірних масивів, які називають векторами.

Створення векторів

У Julia вектор - це впорядкована послідовність значень, доступ до яких можна отримати за номером індексу.

Найпростіший спосіб створити вектор - перелічити значення в квадратних дужках:

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 відповідає типу кожного елемента.

То вектори мають бути однорідними (усі елементи одного типу)?

Певною мірою так, і якщо ми хочемо найкращої продуктивності, варто до цього прагнути. Однак Julia, коли потрібно, оминає це обмеження за допомогою типу Any:

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

Коли ми створюємо порожній вектор, Julia типово використовує тип елементів Any, але його можна задати конкретніше, вказавши потрібний тип елементів для порожнього масиву.

julia> empty_vec = []
Any[]

julia> empty_int_vec = Int64[]
Int64[]

Прочитаймо це правило й запамʼятаймо його:

  • Індексація в Julia типово починається з 1, а не з 0.

Це звично кожному, хто користувався іншими мовами для аналізу даних (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, як і будь-який індекс, менший за 1 або більший за length(squares).

Операції з векторами

Вектори в 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

Є чимало функцій для роботи з векторами, хоча документація Julia узагальнює їх до «колекцій», а не векторів.

Зауважмо, що за домовленістю функції, які змінюють свої вхідні дані, мають ! у назві. Компілятор цього не перевіряє, але в світі Julia це дуже стійка домовленість.

Ось кілька корисних функцій:

  • Щоб додати значення в кінець вектора, використаймо push!().
  • Щоб видалити останнє значення, використаймо pop!().
  • Для роботи з початком вектора є відповідні функції: 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 до 10, тож її стос карток можна подати як вектор чисел. Позиція певної картки відповідає індексу у векторі.

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 вправ та справжнє наставництво від людей, і все це безкоштовно.