Виклик
Орігамі (складаний папір) - це творча форма мистецтва. Наскільки мені відомо, майстер Орігамі вважає за краще квадратний папір. Почнемо з початку - перетворіть прямокутний папір у квадратний.
Так папір ділиться на квадрати. Крок за кроком видаляємо найбільший квадрат, який розділяє один коротший край із поточною формою (див. Малюнок нижче). І якщо частина, що залишилася після одного кроку, менша або дорівнює 0.001 * (area of the original paper)
, папір більше не можна розділяти. Цілком можливо, що нарешті нічого не залишається.
Ваше завдання - обчислити, скільки квадратів зроблено під час процесу. Квадрат на останньому кроці, який робить папір неможливим розділити, враховується у вихід.
Приклад (папір 1.350
ширини / висоти), вихід 10:
Вхід і вихід
Введення: співвідношення ширини / висоти для прямокутного паперу, один десятковий (або ціле число без крапки) від 1.002
до 1.999
з мінімальним кроком 0.001
. Ви також можете використовувати будь-який інший розумний формат, що описує співвідношення. Просто згадайте про це у своїй відповіді.
Вихід: число квадратів, одне ціле число.
Приклад вводу / виводу
Формат відображення використовується для того, щоб сторінка була охайною, тоді як ваш код не повинен підтримувати введення списку і не бути функцією відображення.
1.002 => 251
1.003 => 223
1.004 => 189
1.005 => 161
1.006 => 140
1.007 => 124
1.008 => 111
1.009 => 100
Завдяки @LuisMendo, ось графік відповідей.
Зауваження
- Це кодовий гольф, тому найкоротший виграш коду
- Зверніть увагу на стандартні лазівки
- Ваша свобода вирішувати, як поводитись із введенням та результатами, але вони повинні дотримуватися стандартних обмежень.
Між іншим...
- Прокоментуйте, якщо у вас є щось незрозуміле щодо виклику
- Особисто я б запропонував, щоб ваша відповідь містила пояснення, якщо ви використовуєте мову для гольфу
- Завдяки @GregMartin, прочитайте його відповідь на гарне математичне пояснення виклику.
Приклад коду
Ось неперевершена версія коду C ++:
#include <iostream>
#include <utility>
int f (double m)
{
double n = 1, k = 0.001;
int cnt = 0;
k *= m; // the target minimum size
while(m*n >= k)
{
m -= n; // extract a square
if(n > m)
std::swap(n, m); // keep m > n
++ cnt;
}
return cnt;
}
int main()
{
double p;
std::cin >> p;
std::cout << f(p);
return 0;
}
Всі розрахунки , пов'язані в прикладі коду потрібна точність 6 десяткових цифр, яка охоплюється в float
.