Skip to content

Instantly share code, notes, and snippets.

@Ruthenus
Created April 4, 2025 21:44
Show Gist options
  • Select an option

  • Save Ruthenus/9ecb7566edaf417256c95ec29ae0f9de to your computer and use it in GitHub Desktop.

Select an option

Save Ruthenus/9ecb7566edaf417256c95ec29ae0f9de to your computer and use it in GitHub Desktop.
Week 15 Homework in IT STEP Academy (arrays tasks)
#include <iostream> // для роботи з потоками вводу/виводу
#include <windows.h> // щоб використати функцію SetConsoleOutputCP
#include <cstdlib> // для роботи з генерацією випадкових чисел
#include <ctime> // те саме
#include <algorithm> // зокрема, функції для роботи з масивом
#include <cmath> // математична бібліотека
#include <iomanip> // для налаштування вирівнювання
#include <string> // щоб застосувати рядковий тип
using namespace std;
// Завдання на одновимірні масиви (4 задачі)
// ПОЧАТОК КОДУ ЗАДАЧІ
// 7. Створити масив із 20 випадкових чисел у діапазоні від -30 до 10.
// Визначити суму елементів масиву, що знаходяться ДО
// першого додатного елемента.
int main()
{
SetConsoleOutputCP(1251);
cout << "\tЗАВДАННЯ I.7\n\n";
// Безпечна ініціалізація масиву
const short SIZE = 20;
short array[SIZE]{}; // створення масиву нулів
// Ініціалізація генератора випадкових чисел
srand(time(0));
// Заповнення масиву випадковими числами в заданому діапазоні:
for (short i = 0; i < SIZE; ++i) {
array[i] = rand() % 41 - 30; // від -30 до 10;
}
// Шукаємо перший додатний елемент. Якщо знайдено додатний елемент,
// визначаємо суму елементів, які розташовані до нього в масиві.
short firstPositiveIndex = -1; // ініціалізація індексу!
short sumBeforeFirstPositive = 0; // сума попередніх елементів
for (short i = 0; i < SIZE; ++i) {
if (array[i] > 0) {
firstPositiveIndex = i;
break;
}
sumBeforeFirstPositive += array[i];
}
// Виведення масиву та відповіді
// https://acode.com.ua/urok-95-tsykl-foreach/
cout << "Значить так, маємо масив із 20 випадкових чисел ";
cout << "в діапазоні від -30 до 10:\n\n";
for (const auto& element : array) {
cout << element << " ";
}
cout << "\n";
if (firstPositiveIndex != -1) {
cout << "\nСума елементів до першого додатного елемента дорівнює ";
cout << sumBeforeFirstPositive << ". Уявляєте?\n";
}
else {
cout << "Додатний елемент не знайдений у масиві, ";
cout << "тому нічого не рахуємо.\n";
}
cout << "\n" << string(80, '-') << "\n";
return 0;
}
// КІНЕЦЬ КОДУ ЗАДАЧІ
// ПОЧАТОК КОДУ ЗАДАЧІ
// 9. Створити масив на 100 дійсних чисел. Визначити,
// скільки елементів масиву не мають дробової частини.
int main()
{
SetConsoleOutputCP(1251);
cout << "\tЗАВДАННЯ I.9\n\n";
const int SIZE = 100; // відповідно до завдання!
double array[SIZE];
int count = 0; // лічильник чисел без дробової частини
const double EPS = 1E-9; // допустима похибка для порівняння
// Ініціалізація генератора випадкових чисел
srand(time(0));
// Заповнення масиву випадковими дійсними числами:
for (int i = 0; i < SIZE; ++i) {
if (rand() % 2 == 0) { // 50% шанс на ціле число
array[i] = rand() % 101; // лише ціла частина
}
else { // 50% шанс на дробове число
array[i] = rand() % 101 + ((double)(rand()) / RAND_MAX);
} // https://learn.microsoft.com/ru-ru/cpp/c-runtime-library/rand-max?view=msvc-170
}
// Підрахунок чисел без дробової частини!
// Якщо модуль остачі від ділення на 1 менше ніж похибка округлення
// EPS, вважаємо, що дробова частина відсутня
for (int i = 0; i < SIZE; ++i) {
if (fabs(fmod(array[i], 1.0)) < EPS) {
// https://learn.microsoft.com/ru-ru/cpp/c-runtime-library/reference/fabs-fabsf-fabsl?view=msvc-170
// https://learn.microsoft.com/ru-ru/cpp/c-runtime-library/reference/fmod-fmodf?view=msvc-170
count++;
}
}
cout << "Генерую масив на " << SIZE << " дійсних чисел.\n";
cout << "Кількість елементів без дробової частини: " << count << "\n";
cout << "\n" << string(80, '-') << "\n";
return 0;
}
// КІНЕЦЬ КОДУ ЗАДАЧІ
// ПОЧАТОК КОДУ ЗАДАЧІ
// 11. Створити масив із 10 цілих випадкових чисел. Змінити порядок
// слідування елементів масиву на протилежний (1-й елемент змінюється
// з 10-м, 2-й — з 9-м і т. д.).
int main()
{
SetConsoleOutputCP(1251);
cout << "\tЗАВДАННЯ I.11\n\n";
srand(time(0));
// Створюємо масив із 10 випадкових цілих чисел від -44 до 44:
const short SIZE = 10;
short array[SIZE];
cout << "Випадковий масив із парної кількості цілих чисел: ";
for (short i = 0; i < SIZE; ++i) {
array[i] = rand() % 89 - 44;
cout << array[i] << " ";
}
cout << "\n";
// Переставляємо елементи місцями: 1-й та 10-й, 2-й та 9-й,
// 3-й та 8-й, 4-й та 7-й, 5-й та 6-й – ПРАКТИЧНО ВРУЧНУ
for (short i = 0; i < SIZE / 2; ++i) {
short a = array[i];
array[i] = array[SIZE - i - 1];
array[SIZE - i - 1] = a; // SIZE / 2, тому що вже переставлено
}
cout << "\nЦей масив у зворотному порядку: ";
for (const short element : array) {
cout << element << " ";
}
cout << "\n";
cout << "\n" << string(80, '-') << "\n";
return 0;
}
// КІНЕЦЬ КОДУ ЗАДАЧІ
// ПОЧАТОК КОДУ ЗАДАЧІ
// 12. Дано 2 масиви розміру M і N відповідно. Переписати в
// третій масив спільні елементи перших двох масивів без повторень.
int main()
{
SetConsoleOutputCP(1251);
cout << "\tЗАВДАННЯ I.12\n\n";
// Розміри масивів
const short M = 50;
const short N = 70;
// Створення масивів випадкових цілих чисел розміру M і N відповідно:
srand(time(0));
int arrayM[M];
for (short i = 0; i < M; ++i) {
// arrayM[i] = rand() % (2 * M * 1000 + 1) - M * 1000;
arrayM[i] = rand() % (2 * M + 1) - M;
} // M випадкових чисел у діапазоні -M, M
int arrayN[N];
for (short j = 0; j < N; ++j) {
// arrayN[j] = rand() % (2 * N * 1000 + 1) - N * 1000;
arrayN[j] = rand() % (2 * N + 1) - N;
} // N випадкових чисел у діапазоні -N, N
// Відсортуємо обидва масиви за допомогою стандартної функції
sort(arrayM, arrayM + M);
sort(arrayN, arrayN + N);
// https://stackoverflow.com/questions/5897319/how-to-use-stdsort-to-sort-an-array-in-c
// Створимо масив для зберігання спільних елементів без повторень
int arrayCommon[min(M, N)];
short common = 0; // ініціалізація кількості елементів у масиві
// Див. реалізацію методу подвійного вказівника мовою PYTHON тут:
// https://gist.github.com/Ruthenus/63d013593373e3609f289b0c6896f7bb
short i = 0;
short j = 0;
while (i < M && j < N) {
if (arrayM[i] == arrayN[j]) {
if (common == 0 || arrayCommon[common - 1] != arrayM[i]) {
arrayCommon[common++] = arrayM[i];
} // уникаємо додавання повторюваних елементів
i++;
j++;
}
else if (arrayM[i] < arrayN[j]) {
i++;
}
else {
j++;
}
}
cout << "Дано два масиви: \n\n";
for (const auto& element : arrayM) {
cout << element << " ";
}
cout << "\n\n";
for (const auto& element : arrayN) {
cout << element << " ";
}
cout << "\n\nПерепишемо в третій масив спільні елементи перших двох ";
cout << "масивів без повторень\n\n";
for (short k = 0; k < common; ++k) {
cout << arrayCommon[k] << " ";
}
cout << "\n\nКількість спільних елементів: " << common << "\n";
// ПРОБЛЕМЫ НЕ НАЙДЕНЫ
// БУЛО І ТАКЕ для M = 50'000 та N = 70'000:
// Функция использует байты стека "1360028".
// Рассмотрите возможность перемещения некоторых данных в кучу.
cout << "\n" << string(80, '-') << "\n";
return 0;
}
// КІНЕЦЬ КОДУ ЗАДАЧІ
// Завдання на двовимірні масиви (3 задачі)
// ПОЧАТОК КОДУ ЗАДАЧІ
// 9. Заповнити тривимірний масив N x N x N нулями. У отриманий куб
// вписати кулю, що складається з одиниць. Після цього розрізати куб
// на N шарів і показати кожен шар у вигляді двовимірного масиву
// N x N на екрані консолі.
int main()
{
SetConsoleOutputCP(1251);
cout << "\tЗАВДАННЯ II.9\n\n";
// Створюємо тривимірний масив нулів типорозміру "куб":
const int N = 50; // щось здається, більше С++ не витримає...
int kub[N][N][N]{};
// Оголошуємо відповідно центр куба та радіус кулі, вписаної в куб:
float o;
float r;
// Розташування центра куба залежить від парності N:
if (N % 2 == 0) {
// Для парного N геометричний центр знаходиться поміж двома
// центральними елементами (24 і 25 в разі нумерації від нуля):
o = (N / 2.0) - 0.5; // для N = 50 буде center = 24,5
}
else {
// Для непарного N центр співпадає з центральним елементом:
o = N / 2.0; // для масива з N = 49 center = 24
}
// Оскільки нумерація від нуля, то радіус кулі
r = o;
// Для кожної точки куба перевіряємо, чи належить вона кулі,
// https://ua.onlinemschool.com/math/formula/sphere/
// застосовуючи відоме зі школи рівняння сфери:
for (int x = 0; x < N; ++x) {
for (int y = 0; y < N; ++y) {
for (int z = 0; z < N; ++z) {
if (pow(x - o, 2) + pow(y - o, 2) + pow(z - o, 2) <= r * r) {
kub[x][y][z] = 1; // щодо { 1 } див. умову задачі
}
}
}
}
// Розрізаємо куб на N шарів вздовж осі x, виводимо на консоль:
for (int x = 0; x < N; ++x) {
cout << "\nШар " << x + 1 << "\t\tБАНЗАЙ!\n\n";
for (int y = 0; y < N; ++y) {
for (int z = 0; z < N; ++z) {
cout << kub[x][y][z] << " ";
}
cout << "\n";
}
cout << "\n";
}
cout << "\n" << string(80, '-') << "\n";
return 0;
}
// Функция использует байты стека "500036". Рассмотрите возможность
// перемещения некоторых данных в кучу. ЗАТЕ ХАЙ ЖИВЕ ЯПОНІЯ!
// КІНЕЦЬ КОДУ ЗАДАЧІ
// ПОЧАТОК КОДУ ЗАДАЧІ
// 10. Реалізувати перетворення двовимірного масиву в одновимірний
// і навпаки.
int main()
{
SetConsoleOutputCP(1251);
cout << "\tЗАВДАННЯ II.10\n\n";
// Ініціалізація двовимірного та одновимірного масивів:
const int ROWS = 23;
const int COLUMNS = 14;
int array2D[ROWS][COLUMNS]{};
int array1D[ROWS * COLUMNS]{};
int arrayAgain2D[ROWS][COLUMNS]; // Make Array 2Dimensions Again
// Наповнюємо вихідний двовимірний масив випадковими цілими
// числами від 0 до 99, використовуючи вирівнювання під час виводу:
srand(time(0));
cout << "Дано двовимірний масив: \n\n";
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLUMNS; ++j) {
array2D[i][j] = rand() % 100;
cout << setw(5) << array2D[i][j];
}
cout << "\n";
}
cout << "\n\n";
// У двовимірному масиві ROWS * COLUMNS елементів.
// В одновимірному масиві елементи будуть слідувати рядок за рядком,
// вони матимуть індексацію від 0 до ROWS * COLUMNS - 1. Припустимо.
// Номер рядка двовимірного масиву, звідки береться i-й елемент
// одновимірного, має свідчити скільки рядків заповнено повністю.
// Тоді номер стовпця – це кількість елементів, розташованих після
// крайнього повністю заповненого рядка, мінус один.
// Перетворення двовимірного масиву в одновимірний за один цикл!
cout << "Перетворимо в одновимірний масив рядок за рядком: \n\n";
for (int i = 0; i < ROWS * COLUMNS; ++i) {
array1D[i] = array2D[i / COLUMNS][i % COLUMNS];
cout << setw(4) << array1D[i];
}
// А якщо перетворення стовпець за стовпцем, то
// array1D[i] = array2D[i % ROWS][i / ROWS];
cout << "\n\n\n";
// Відновлення двовимірного масиву з одновимірного:
cout << "Зробимо масив двовимірним знову : \n\n";
for (int i = 0; i < ROWS * COLUMNS; ++i) {
arrayAgain2D[i / COLUMNS][i % COLUMNS] = array1D[i];
}
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLUMNS; ++j) {
cout << setw(5) << arrayAgain2D[i][j];
}
cout << "\n";
}
cout << "\n" << string(80, '-') << "\n";
return 0;
}
// КІНЕЦЬ КОДУ ЗАДАЧІ
// ПОЧАТОК КОДУ ЗАДАЧІ
// 8. Заповнити квадратну матрицю розміром N x N по спіралі.
// Число 1 ставиться в центр матриці, а потім масив заповнюється по
// спіралі проти годинникової стрілки значеннями за зростанням.
int main()
{
SetConsoleOutputCP(1251);
cout << "\tЗАВДАННЯ II.8\n\n";
// Цікаво, чи можна задавати розмір матриці випадковим числом...
const int N = 29; // краще задати непарне N
int matrix[N][N]{}; // матриця квадратна, заповнена нулями
int x; // номер стовпця
int y; // номер рядка
// Напрямки руху за спіраллю проти годинникової стрілки:
// Кожен елемент задає пару змін {dy, dx}, де dy – зсув по рядку,
// а dx – зсув по стовпцю.
int counterClockWise[4][2]{
{-1, 0}, // Вгору: рядок (y) зменшується на одиницю,
// стовпець (x) залишається незмінним.
{0, -1}, // Ліворуч: стовпець (x) зменшується на одиницю,
// рядок (y) незмінний.
{1, 0}, // Вниз: рядок (y) збільшується на одиницю,
// стовпець (x) незмінний.
{0, 1} // Праворуч: стовпець (x) збільшується
// на одиницю, рядок (y) незмінний.
};
// За умовою задачі число 1 розміщуємо в центрі матриці:
x = N / 2; // звісно, виникає питання парності або непарності N
y = N / 2;
matrix[y][x] = 1;
// У разі парного N центр матриці не визначено однозначно, тому
// застосовуємо цілочисельне ділення, що вибирає один із центрів.
// Ініціалізація поточного напрямку руху: 0 – вгору (12 година)
int direction = 0; // 1: вліво, 2: вниз, 3: праворуч
// Наступне число, яке буде заповнювати матрицю:
int number = 2;
// Поточна кількість кроків у заданому напрямку перед поворотом
int steps = 1;
// Кількість вже заповнених клітинок (спочатку лише центральна)
int filled = 1;
// Заповнюємо матрицю числами від 2 до N * N – квадрата її розміру:
while (filled < N * N) {
// Виконуємо задану кількість кроків у поточному напрямку
for (int i = 0; i < steps && filled < N * N; ++i) {
// Координати наступної позиції за поточним напрямком
x += counterClockWise[direction][1];
y += counterClockWise[direction][0];
// Перевіряємо, чи наступна позиція існує в межах матриці
if (x >= 0 && x < N && y >= 0 && y < N) {
matrix[y][x] = number++; // Записуємо наступне число
filled++; // Збільшуємо лічильник заповнених клітинок
}
}
// Змінюємо напрямок руху на наступний, обертаючи
// проти годинникової стрілки
direction = (direction + 1) % 4;
// І НАЙГОЛОВНІШЕ!
// Збільшуємо кількість кроків після кожних двох поворотів
// (щоб спіраль рівномірно розширювалась!)
if (direction % 2 == 0) {
steps++;
}
}
// Врешті-решт, виводимо отриману матрицю з вирівнюванням:
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
cout << setw(4) << matrix[i][j];
}
cout << "\n";
}
cout << "\n" << string(80, '-') << "\n";
return 0;
}
// КІНЕЦЬ КОДУ ЗАДАЧІ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment