Треки
/
R
R
/
Вправи
/
Вороняче таксі
Вороняче таксі

Вороняче таксі

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

Вступ

Complex numbers не такі вже й складні. Просто їм потрібна назва, яка не так лякає.

Вони настільки корисні, особливо в інженерії та науці, що R включає комплексні числа як стандартні атомарні типи поряд із цілими числами, числами з плаваючою комою, логічними значеннями, символами та raw.

Основи

Число типу complex у R - це одне значення. Однак у роботі його можна уявляти як пару чисел. Їх називають «дійсною» та «уявною» частинами, з нещасливих історичних причин. І знову ж таки, краще зосередитися на простоті, що лежить в основі, а не на дивних назвах.

Щоб створити комплексне число з двох дійсних чисел, достатньо додати суфікс i до уявної частини.

2+3i
#> [1] 2+3i

typeof(2+3i)
#> [1] "complex"

Але щоб створити комплексне число з дійсних змінних, наведений вище синтаксис не спрацює. Запис r + imi збиває парсер із пантелику, і він вважає imi назвою (неіснуючої) змінної.

Можна або помножити уявну частину на 1i, або скористатися функцією [complex()][ref-complex]:

r <- 2
im <- 3

r + im * 1i
#> [1] 2+3i

# must include the `real` and `imaginary` keywords
complex(real = r, imaginary = im)
#> [1] 2+3i

Можливо, виникає питання: чому i, а не j?

Більшість інженерів віддають перевагу j. Більшість науковців і математиків віддають перевагу математичному позначенню i для уявної частини, але це позначення конфліктує з використанням i на позначення струму в електротехніці.

У R обрали i, у Python - j, а в Julia оминули суперечку, обравши im. Варто бути уважними, перемикаючись між мовами програмування [STEM][wiki-STEM].

Щоб отримати частини комплексного числа окремо:

z <- 2+3i

Re(z)  # real part
#> [1] 2

Im(z)  # imaginary part
#> [1] 3

Будь-яка з частин може дорівнювати нулю, і тоді математики можуть казати, що число «цілком дійсне» або «цілком уявне». Однак у R це все одно комплексне число.

1.2 + 0i
#> [1] 1.2+0i

typeof(1.2 + 0i)
#> [1] "complex"

2i
#> [1] 0+2i

typeof(2i)
#> [1] "complex"

Можливо, ви чули, що «i (або j) - це квадратний корінь із -1».

Поки що це означає лише те, що уявна частина за означенням задовольняє таку рівність:

1i * 1i == -1  # more precisely, 1i * 1i == -1 + 0i
#> [1] TRUE

Це проста ідея, але вона веде до цікавих наслідків.

Арифметика

Більшість операторів, які використовуються з числами з плаваючою комою та цілими числами, також працюють із комплексними числами:

z1 = 1.5 + 2i
z2 = 2 + 1.5i

z1 + z2  # addition
#> [1] 3.5+3.5i

z1 * z2  # multiplication
#> [1] 0+6.25i

z1 / z2  # division
#> [1] 0.96+0.28i

z1^2  # exponentiation
#> [1] -1.75+6i

2^z1  # another exponentiation
#> [1] 0.518895+2.780422i

Функції

Більшість математичних функцій працюють із комплексними вхідними даними.

Окрім Re() та Im(), є кілька функцій, особливо дотичних до комплексних чисел.

  • Conj() просто змінює знак уявної частини комплексного числа (з + на - або навпаки).
    • Через те, як працює комплексне множення, це корисніше, ніж може здатися.
  • abs(<complex number>) гарантовано повертає дійсне число без уявної частини (його «модуль»), а Mod(<complex number>) - це синонім.
  • Arg(<complex number>) повертає фазовий кут у радіанах.
z1
#> [1] 1.5+2i

abs(z1)
#> [1] 2.5

Mod(z1)  # same as previous
#> [1] 2.5

Conj(z1)  # flip sign
#> [1] 1.5-2i

Arg(z1)
#> [1] 0.9272952

Вказівки

Нас щойно найняли в нову службу таксі, яка намагається вирізнитися серед інших пропозицій на вже насиченому ринку. Щоб цього досягти, генеральний директор вирішив запустити в Мангеттені ультрарозкішний сервіс із помічниками на кожному перехресті, які допомагають клієнтам до та після поїздки. Тепер нам потрібно написати трохи коду, який допоможе з роботою сервісу.

1. Просте комплексне число

Генеральний директор вирішив, що оскільки вулиці Мангеттена розташовані переважно у вигляді сітки, для позначення перехресть вулиць зручно використовувати комплексні числа. У цьому поданні додатні та відʼємні дійсні числа позначають схід і захід, а додатні та відʼємні уявні числа - північ і південь відповідно.

Оскільки створити комплексне число в R трохи, гм... незвично, нам доручили реалізувати функцію простого комплексного числа.

Реалізуйте функцію simplex(a, b), яка приймає цілі числа a і b. Поверніть комплексне число a+bi.

simplex(1, 1)
#> 1+1i

simplex(-3, 4)
#> -3+4i

2. Отримати напрямок руху для водія

Коли клієнт називає перехрестя призначення, водії отримують напрямок, як туди дістатися. Цей напрямок подається у вигляді комплексного числа, де дійсна частина показує, скільки кварталів проїхати на північ чи південь, а уявна частина - відстань на схід чи захід. Щоб узгодити це з канонічним компасом, керівник проєкту вирішив, що північ відповідає додатному уявному напрямку, а південь - відʼємному уявному напрямку. Так само схід відповідає додатному дійсному напрямку, а захід - відʼємному дійсному напрямку.

Реалізуйте функцію driver_directions(start, end), яка приймає координати початкового перехрестя start і координати перехрестя призначення end. Поверніть комплексне число, яке показує, скільки кварталів на схід/захід і на північ/південь має проїхати водій.

driver_directions(0+0i, 7+5i)
#> 7+5i

driver_directions(-2+3i, 4-5i)
#> 6-8i

3. Обчислити мангеттенську відстань

З клієнта беруть плату за відстань, яку має подолати таксі. Оскільки вулиці Мангеттена розташовані у вигляді сітки, таксі можуть їздити лише цими маршрутами. Така структура змушує вимірювати відстань уздовж ліній сітки. Відстань можна знайти, додавши кількість пройдених ліній або кількість досягнутих перехресть (тобто не враховуючи початкове перехрестя). Цей показник зазвичай називають мангеттенською відстанню, або нормою L1.

Реалізуйте функцію manhattan(start, end), яка приймає перехрестя start і end. Поверніть мангеттенську відстань між перехрестями start і end.

manhattan(0+0i, 3+4i)
#> 7

manhattan(-2-3i, -1+1i)
#> 5

4. Обчислити відстань «по прямій»

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

За цю послугу також беруть плату залежно від пройденої відстані. Утім, оскільки ворони вміють літати, їм не потрібно триматися сітки доріг, і вони можуть летіти найкоротшим шляхом. Звісно, так було б не завжди, якби на шляху стояли величезні хмарочоси, але генеральний директор запускає цю послугу в Мангеттені, штат Канзас (він же «Маленьке яблуко»), де ворони легко перелітають невисокі будівлі. Питання про потенційний попит на таку послугу в Мангеттені, штат Канзас, і про те, як місцеві перехожі ставитимуться до всіх цих птахів, що літають над головою, залишимо на інший день.

Реалізуйте функцію as_crow_flies(start, end), яка приймає перехрестя start і end. Поверніть відстань між ними по прямій.

as_crow_flies(0+0i, 3+4i)
#> 5

5. Отримати напрямок руху для ворон

Генеральний директор навчив ворон орієнтуватися за напрямками, схожими на ті, що використовують водії. Однак генеральний директор обожнює Південну півкулю й навчав ворон за іншим компасом, ніж той, яким користується керівник проєкту для решти системи. Генеральний директор виявляється досить ексцентричною людиною. У компасі генерального директора північ відповідає відʼємному уявному напрямку, а південь - додатному уявному напрямку. Це протилежно до напрямку північ/південь у водіїв, тоді як схід/захід залишаються такими самими.

Реалізуйте функцію crows_directions(start, end), яка приймає перехрестя start і end. Поверніть комплексне число, аналогічне до напрямку руху водія, але з північчю та півднем, поміняними місцями.

driver_directions(0+0i, 7+5i)
#> 7-5i

driver_directions(-2+3i, 4-5i)
#> 6+8i
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці
R Exercism

Час розпочати Вороняче таксі?

Зареєструйтеся на Exercism, щоб вивчати й опановувати R, а також 21 концепція111 вправ та справжнє наставництво від людей, і все це безкоштовно.