Сапер - популярна гра, у якій гравець має знайти міни за числовими підказками, що показують, скільки мін безпосередньо межує з клітинкою (по горизонталі, вертикалі або діагоналі).
У цій вправі ми додаємо кількість мін до порожніх клітинок готового ігрового поля «Сапер». Саме поле має форму прямокутника, що складається з клітинок, і кожна з них або порожня (' '), або містить міну ('*').
Для кожної порожньої клітинки порахуймо кількість сусідніх мін (по горизонталі, по вертикалі, по діагоналі). Якщо в порожньої клітинки немає сусідніх мін, залишмо її порожньою. Інакше замінімо її на кількість сусідніх мін.
Наприклад, ми можемо отримати поле 5 x 4 такого вигляду (тут порожні клітинки позначено символом '·' для показу на екрані):
·*·*·
··*··
··*··
·····
І ось на що його має перетворити наш код:
1*3*1
13*31
·2*2·
·111·
Усі вхідні та вихідні дані мають кодування ASCII.
String і &str у Rust мають кодування utf8, тож хоча можна було б очікувати, що "Hello".chars() буде простим, насправді йому доводиться перевіряти кожен символ, чи він має довжину 1, 2, 3 чи 4 u8.
Якщо ми знаємо, що &str є ASCII, то можемо викликати .as_bytes() і звертатися до даних під ним як до &[u8] (зрізу байтів).
Перебирання зрізу ASCII-байтів набагато швидше, адже тут не задіяні кодові точки: кожен ASCII-байт має довжину один u8.
Чи можна розвʼязати це завдання, не клонуючи вхідні дані?
Зареєструйтеся на Exercism, щоб вивчати й опановувати Rust, а також 99 вправ та справжнє наставництво від людей, і все це безкоштовно.
Ми розглянемо вкладені цикли `for`, вдале застосування min/max для спрощення перевірки меж, функціональні конвеєри та роботу з двовимірними матрицями.