SLC21 Week6 - Programming Games&Puzzles (part 2)
Рекурсія виявилася не такою складною як ігри з минулого уроку. Здавалося я нескладні завдання дав, проте ніби троє на перший погляд справилися з завданням, дво є ж відправили явно не те.
Сьогодні я повернуся до її величності випадковості, адже без її участі не було б не те що жодної ігри - не було б жодної програми. Навіть комп'ютер би не існував)) Не існувало б криптографії і світу криптовалют.
Правда в світі програмуваня випадкові числа називають псевдовипадковими. Отже це ніби не справді випадкові числа, чи справді випадкові?
Псевдовипадколвсть
Псевдовипадкові - це тому що вони обчислюються за певним алгоритмом, формулою.
А отже за певних початкових умов(їх називають seed) - будуть передбачувані результати(адже це алгоритм)
Часто це навіть допомагає(при розробці та тестуванні)
Найпростіший алгоритм псевдовипадкових чисел виглядає так:
нове число = (старе число * множник + зсув) і взяти остачу від діення.
xn+1 = (xn * m + n)%k - формула генератора випадкових чисел.
В мовах С/С++ функція яка генерую "випадкові" числа - rand()
Першим випадковим числом, а отже і всією послідовністю можна керувати через seed(n)
але якщо аргументом писати одне і те ж число - послудовність буде одна і та ж. Як же тоді у такий спосіб задати "абсолютно" випадкове число. - Слід задати випадковість із зовнішнього світу, світу поза комп'ютером.
Для цього часто беруть годинник-таймер time(0)
- функція дає час в секундах від 1/1/1970,що для нас зараз не важливо - головне отримана випадковість.
seed(time(0));
Якщо для генератора я задам такі числа m=377, n=133, k=200 - x= (x*377+133)%200;
int myrand(int x)
{
x = (x * 377 + 133) % 200;} ///x= (x*377+133)%200;
x | rand() |
---|---|
7 | 13 |
13 | 25 |
25 | 47 |
47 | 89 |
89 | 164 |
У мене вийшла така от таблиця, легко бачити що наступне число вдівічі більше за попереднє, до того ж вони все зростають і зростають. Тобто наступне число більше за попереднє. Напевне слід взяти m
- більшим, k
- меншим.
Якщо згенерувати моїм генератором багато таких чисел, і підрахувати в масиві кількість появи кожного, то поява кожного числа будле випадковою
Колода карт
Це завдання я хотів минулого разу, то ж зараз задам саме його. Одного разу ще в студентські роки задумав зробити гру в карти на комп'ютері. А для будь-якої гри треба перетасована/перемішана колода карт.
Як реалізувати колоду карт на комп'ютері - звісно у вигляді масиву. Але далі розв'язуючи багато задач на масиви - я часто стикався з задачами заповнення масиву унікальними числами.
І до цього часу ця задача виросла до цілої теорії...
Це стала цікава задача. Вам доведеться дослідити та розв'язати її декілька раз. Адже не відразу народжується геніальна ідея, оптимальний розв'язок. Тут треба пройти від простих, не досконалих рішень до самого оптимального.
То ж головне завдання - "заповнити масив на N чисел випадковими числами так, щоб всі ці N чисел там були, і жодне не повторювалося. Кожне було присутнім і кожне було унікальним. масив на N чисел заповнити числами від 1 до N, або від 0 до N-1 - не має значення.
На виході має бути масив згенерований масив з випадковими числами. Звідси й назва - колоди карт, всі карти є і жодна карта не повторюється
const int N=36;
int a[N];
for(int i=0; i<N; i++)
a[i]=... random number..
це шаблон до вашого завдання, з цього треба починати, але цим не обмежуватися. Функція random() не гарантує що числа в послідовності не повторюються, тому цю логіку необхідно продумати
Завдання в тому, щоб придумати якомога більше способів розв'язку цієї задачі. Від самого тупого(самого довготривалого, самого не ефективного, не раціонального(метод грубої сили) до найоптимальнішого з точки зору часу/кількості операції. А ще я якось думав про імітацію фізичного тасування колоди))))) - цей спосіб я ще сам не реалізовував.
За це завдання 5 балів - з розрахунку один спосіб - 1 бал.
Якщо зможете оцініть часові витрати для генерації випадкового масиву для N чисел. Але при онлайн компіляторах ваші програми невірно оцінюватимуть час. Тому краще замість цього порахувати кількість операцій для генерації масиву на 20, 1000, 10000 "карт"/чисел.
Чому тут вказано 20? - бо той метод що я називаю тупим методом так, не раціонально та повільно генерує масив - ви просто не дочекаєтеся результату. Тому для цього примітивного методу можна взагалі провести дослідження на зразок
N | operatoins |
---|---|
1 | xx |
2 | xx |
3 | xx |
.. | .. |
19 | xx |
Я розумію що рішення на Пайтоні впишеться в два рядки(якщо не в один рядок коду)... проте вам слід все це проробити самостійно.
Homework
- (1 бал) Яку роль відіграють випадкові числа в комп'ютерному світі? Як їх з "псевдовипадкоих" перетворити у більш випадкові.
- (2 бали) Напишіть генератор випадкових чисел. Дослідіть його.
- (5 балів) Знайдіть декілька способів заповнити масив 1...N - 1 Один спосіб - один бал.
- Побудуйте таблицю залежності кількості операцій при генеруванні колоди з N карт для ваших способів.
Наприклад
Ncards | Operations |
---|---|
5 | 4000 |
6 | 5000 |
7 | 6000 |
.. | .. |
Правила проведення
Публікувати можна на будь-якій мові, в будь якій спільноті чи просто у власному блозі, посилання на вашу роботу додайте сюди коментарем
Щоб я швидко знайшов, перевірив та оцінив ваші роботи залиште посилання в коментарі під цим текстом а в роботі поставите тег #slc21w6sergeyk
До всіх завдань код наводити скріншотом, не текстом. Демонструвати теж скріншотом результат роботи програми.
Будьте обережні стосовно ідеальних та надефективних рішень, звичайній людині, початківцю їх не легко найти.
Не надавати рішення задач з допомогою матеріалів, які не вчили. Наприклад масивів, котрі ми ще не вчили. Це обмеження не стосується тих студентів які вже практично знайомі з програмуванням, та надають розширені відповіді на завдання, що більш схоже на лекцію.
Плагіат і використання ШІ заборонено.
Учасники мають бути перевіреними та активними користувачами платформи.
Використані зображення мають належати автору або бути вільними від авторських прав. (Не забудьте вказати джерело.)
Учасники не повинні використовувати будь-які сервіси ботів для голосування, не брати участь у купівлі голосів.
Порекомендуйте прийняти участь своїм друзям.
Роботи слід опублікувати з Monday 2 Dec 24 to Sunday 08 Dec 24
Ваші роботи будуть мною прокоментовані, оцінені та відібрані чотири кращі роботи.
I had a busy week. Didn't even get a chance to read the last lesson. I will do it though some other time for practice.
0.01 SBD,
0.13 STEEM,
0.16 SP