У Clojure списки є колекціями, так само як і списки в інших мовах. Як і в інших мовах сімейства Lisp, Clojure використовує дужки для запису списків.
Списки в Clojure можна створити одним із двох способів. Функція list створює список, або ж список-літерал можна зацитувати за допомогою quote.
Списки особливі тим, що Clojure трактує їх як виклики. Виклик має починатися з оператора, який зазвичай є функцією. Решту елементів списку вважають операндами, тобто вони стають аргументами функції.
Саме через особливе ставлення Clojure до списків ми не можемо створити список-літерал безпосередньо. Цитування списку за допомогою quote або його скороченого запису ' означає, що список не слід обчислювати.
На відміну від деяких сучасних мов, списки в Clojure гетерогенні, тобто можуть містити елементи різних типів, наприклад '(2 "a" "b" 3).
На відміну від інших діалектів Lisp, порожній список у Clojure є правдивим і не дорівнює nil або false.
Еліз дуже хоче пограти в покер (та інші карткові ігри) під час своєї майбутньої поїздки до Вегаса. Будучи великою прихильницею «самовідстеження», вона хоче створити кілька невеликих функцій, які допоможуть їй із завданнями відстеження, і просить нас допомогти все це обміркувати.
Еліз особливо любить покер і хоче відстежувати, скільки раундів вона грає, і які саме раунди. Кожен раунд має свій номер, і кожен стіл показує номер раунду, який грають зараз. Еліз обирає стіл і сідає грати свій перший раунд. Вона планує зіграти три раунди.
Реалізуйте функцію rounds, яка приймає номер поточного раунду й повертає один list із цим раундом і двома наступними:
(rounds 27)
;;=> (27 28 29)
Еліз зіграла кілька раундів за першим столом, потім зробила перерву й зіграла ще кілька раундів за другим столом... але в підсумку отримала окремий масив для кожного столу! Вона хоче поєднати ці два масиви, щоб відстежувати всі раунди покеру в одному місці.
Реалізуйте функцію concat-rounds, яка приймає два масиви й повертає один list, що складається з усіх раундів із першого list, а далі з усіх раундів із другого list:
(concat-rounds '(27 28 29) '(35 36))
;;=> (27 28 29 35 36)
Коли мова заходить про деякі попередні раунди покеру, інший гравець зауважує, як схоже минули два з них. Еліз не певна, чи грала вона ті раунди.
Реалізуйте функцію contains-round?, яка приймає два аргументи: масив зіграних раундів і номер раунду. Функція поверне true, якщо раунд є в масиві зіграних раундів, і false, якщо ні:
(contains-round? '(27 28 29 35 36) 29)
;;=> true
(contains-round? '(27 28 29 35 36) 30)
;;=> false
Еліз хоче спробувати нову гру під назвою «Блек Джо». Вона схожа на блекджек, де наша мета - щоб карти в руці в сумі давали цільове значення, але в «Блек Джо» мета - щоб середнє значень карт дорівнювало 7. Середнє можна знайти, додавши всі значення карт, а потім поділивши цю суму на кількість карт у руці.
Реалізуйте функцію card-average, яка повертає середнє значення карт у руці в «Блек Джо».
(card-average '(5 6 7))
;;=> 6.0
У «Блек Джо» важлива швидкість. Еліз спробує знайти швидший спосіб обчислити середнє.
Вона придумала два способи отримати число, схоже на середнє:
Реалізуйте функцію approx-average?, яка приймає hand, масив зі значеннями карт у руці.
Поверніть true, якщо одна or обидві зі згаданих вище стратегій дають число, рівне фактичному середньому.
Примітка: Довжина всіх рук непарна, щоб легше було знайти медіану.
(approx-average? '(1 2 3))
;;=> true
(approx-average? '(2 3 4 8 8))
;;=> true
(approx-average? '(1 2 3 5 9))
;;=> false
Зацікавлена результатами свого експерименту з усередненням, Еліз думає, чи дадуть однаковий результат середнє карт на парних позиціях і середнє карт на непарних позиціях. Час для ще однієї тестової функції!
Реалізуйте функцію average-even-odd?, яка повертає булеве значення (англ. Boolean), що вказує, чи середнє карт на парних індексах дорівнює середньому карт на непарних індексах.
(average-even-odd? '(1 2 3))
;;=> true
(average-even-odd? '(1 2 3 4))
;;=> false
Кожна 11-та рука в «Блек Джо» - бонусна рука з бонусним правилом: якщо остання карта, яку ми беремо, - валет, ми подвоюємо її значення.
Реалізуйте функцію maybe-double-last, яка приймає руку й перевіряє, чи остання карта - валет (11). Якщо остання карта є валетом (11), подвойте її значення перед поверненням руки.
(maybe-double-last '(5 9 11))
;;=> '(5 9 22)
(maybe-double-last '(5 9 10))
;;=> '(5 9 10)
Зареєструйтеся на Exercism, щоб вивчати й опановувати Clojure, а також 12 концепцій105 вправ та справжнє наставництво від людей, і все це безкоштовно.