---
# System prepended metadata

title: Патріотична футболка

---

# Патріотична футболка

# Формальна частина
## Завдання №1
> Потрібно написати аналогічний псевдо-код для наступного твердження:<br>"Тарас має дві футболки: жовту і синю. Він вдягає їх через день" (дана умова залежить лише від дня).<br>

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

Тоді наш код:

```pseudocode
ЯКЩО день_місяця Є парним числом ТО
    Тарас одягає жовту футболку
ІНАКШЕ
    Тарас одягає синю футболку         
```

## Завдання №2
> Чи буде така умова дійсна протягом кількох місяців? Тобто чи не буде днів, коли Тарас одягне одну і ту ж футболку підряд?<br>

Така умова не буде дійсна протягом кількох місяців тому, що існують місяці із непарною кількістю днів. В такі місяці наша послідовність футболок завершиться на непарній (СИНІЙ) футболці. Для першого дня наступного місяця буде обрано так само непарну (СИНЮ) футболку. Тож при такій реалізації будуть існувати дні, коли Тарас одягне одну футболку двічі відряд.

## Завдання №3
> Продумайте як можна записати умову, враховуючи, що в деяких місяцях є 31 день, і числа 31 та 1 йдуть підряд. В умові потрібно використовувати як число, так і місяць.<br>

Маючи місяць як додатковий аргумент ми можемо дізнатись порядковий номер даної дати у році. Якщо цей номер парний - Тарас одягає ЖОВТУ футболку

```pseudocode

порядковий_номер_дня_у_році дорівнює СУМА(кількості_днів_усіх_попередніх_місяців) + день_місяця

ЯКЩО порядковий_номер_дня_у_році Є парним числом ТО
    Тарас одягає жовту футболку
ІНАКШЕ    
    Тарас одягає синю футболку

```

Таким чином функція буде коректно працювати на діапазонах дат від 365 до 730 днів (залежно від року).

Суми днів для кожного місяця можна легко порахувати:
- січень - 0
- лютий -  0 + 31 = 31
- березень - 31 + 28 = 59
- квітень - 59 + 30 = 89

і т.д.

## Завдання №4
> Які ще граничні випадки можуть бути?<br>

Окрім проблеми переходу між місяцами із 30ма та 31м днем можна згадати про 29е лютого і високосні роки, які зумовлюють його появу. Річ у тім, що так само як при переході від 31го числа до 1го числа, проблема із повторенням виникне при переході між роками, кількість днів у яких варіюється між 365 і 366. На цьому етапі стає зрозуміло, що створення потрібної функції неможливе за умови знання лише про місяць і його день.

---

## Додаткові міркуання

Спробуємо розібратись у тому, що відбувається і можливо знайти повне рішення для задачі безпомилкового і неповторного вибору футболки.

Спершу повернемось до Завдання 1. Тут слід зауважити, що ситуація коли, ми маємо число і два варіанти вибору, невідворотньо спонукає нас звернутись до парності чи непарності числа. Іншої корисної інформації ми просто не можемо отримати від нього для прийняття рішення. 
Також зауважимо, що при цьому перехід від парного до непарного числа, або навпаки відбувається в математиці за такими правилами:
- Парне ± Парне = Парне
- Парне ± Непарне = Непарне
- Непарне ± Непарне = Парне

Тож маючи непарне число (31) додавши до нього непарне (1) ми очікуємо отримати парне (32). Цього не відбувається роботі із датами оскільки там правила переходу між порядковими номерами не співпадають із описаними вище математичними.

Тим не мешн, інтуіція підказує нам, що сам принцип вибору кольору за парністю чи непарністю числа - дієвий. У Завданні 3 ми пробуємо використати порядковий номер дати у році замість її порядкового номеру у місяці. І як у попередньому прикладі нам не вдається забезпечити унікальність послідовності. Без знання року даної дати ми не можемо зробити такий вибір, котрий гарантовано не призведе до повторення у датах майбутнього чи минулого. Але варто відмітити, що *порядковий номер дати у році* по суті не відрізняється від *відстані дати від дати початку року*. Відстань до початку року нам не дуже корисна, але можливо можна знайти чи сформулювати іншу *відстань*.

Для цього додамо точку відліку - опорну дату відносно якої можна вирахувати відстань до дати, що нам дано. У програмуванні широко використовується [Час Unix](https://uk.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81_Unix), при якому такою датою є 1 січня 1970 року. Напишемо код, який використовує 1 січня 1970 року як опорну дату.

```pseudocode

опорна_дата                     дорівнює 1           січня  1970 
дана_дата                       дорівнює день_місяця місяць рік

кількість_мілісекунд_між_датами дорівнює МОДУЛЬ(дана_дата - опорна_дата)
кількість_днів_між_датами       дорівнює ПЕРЕРАХУВАТИ_У_ДНЯХ(кількість_мілісекунд_між_датами)

ЯКЩО кількість_днів_між_датами Є парним числом ТО
    Тарас одягає жовту футболку
ІНАКШЕ    
    Тарас одягає синю футболку

```
Усі сучасні мови програмування уміють порівнювати дати через конвертацію їх у кількість мілісекунд до 1 січня 1970 року. Віднявши по модулю від даної_дати (в мс) опорну_дату (в мс) і конвертувавши отриманий результат у дні, ми отримаємо унікальний для двох дат показник їх віддаленості у днях. Його парність чи непарність, у свою чергу, дасть нам потрібний колір футболки.

Опорною точкою можна обрати будь-яку іншу, або взагалі обирати її динамічно, але я вважаю, що це не дуже принципово.

Я перевірив подібну функцію і вона безпомилково генерує колір футболки з унікальною послідовністю від року Різдва Христового і на 5_000_000 днів вперед (до 13689 року), тож є надія що це правильне рішення.