
В пятницу можно смешивать всё и со всем!
Мы смешаем пифагоровы тройки и библиотеку RxJS.
Пифагоровой тройкой называют три натуральных числа, из которых можно составить прямоугольный треугольник.
Такие числа известны людям с очень древних времён. Например, их использовали ещё в Египте, откуда до нас дошла самая известная пифагорова тройка — это числа 3, 4 и 5.
RxJS — это библиотека для реактивного программирования. Она поможет сделать генерацию троек красивой и простой.
Сразу замечу, что статья претендует только на развлекающую роль
Часть с математикой
Начнём с небольшой теоретической подготовки. Как ранее было замечено, пифагоровой тройкой называют три натуральных числа, которые удовлетворяют уравнению:
Назовём число a малым катетом, число b большим катетом, а число c — гипотенузой.
Все пифагоровы тройки описываются параметрическими формулами, которые называют формулами Евклида.
Чтобы оставить статью скорее развлекательной, мы дальше будем рассматривать только такие пифагоровы тройки, у которых гипотенуза c отличается от большего катета b ровно на единицу.
Вот первые три такие тройки:
Попробуем вывести формулы этого семейства троек. Подставим c = b + 1 и получим:
Видно, что квадрат числа a — это всегда нечётное число. А значит и число a тоже всегда нечётное. Теперь можно легко записать выражения для a, b и c:
Часть с программированием
Напишем несколько простых функций для преобразований, которые нам понадобятся.
Малый катет a надо уметь возводить в квадрат.
function toSquare(n: number): number { return (n ** 2); }
Квадрат малого катета a в нашей задаче — это всегда нечётное число, а больший катет b, как видно из формулы, — это порядковый номер этого нечётного числа.
function toNatural(n: number): number { return ((n - 1) / 2); }
Наконец, если у нас есть больший катет b, то гипотенузу c можно получить прибавлением единицы.
function addOne(n: number): number { return (n + 1); }
Теперь мы можем делать все основные преобразования; осталось получить последовательность нечётных чисел. Последовательность чисел будем представлять в виде потока.
RxJS даёт достаточно много способов создания потоков, но самый подходящий нам — это функция interval(). Она создаёт поток, который будет испускать последовательность натуральных чисел с заданным интервалом.
function generateNaturalNumbers(): Observable <number> { return interval(500); } const naturalNumbers = generateNaturalNumbers(); naturalNumbers.subscribe((value) => { console.log(value); });
Подпишемся на созданный поток и раз в полсекунды будем получать новое натуральное число. Легко понять, как перейти к нужной нам последовательности нечётных чисел:
Для этого напишем вспомогательную функцию, которая по порядковому номеру нечётного числа будет возвращать само число. Эта функция будет обратной к функции toNatural().
function toOdd(n: number): number { return ((n * 2) + 1); }
Теперь препятствий точно не осталось!
Создадим поток с малыми катетами a. Для этого к числу из потока натуральных чисел прибавим единицу, а затем получим соответствующее нечётное число. При испускании нового натурального числа будет испускаться и новый малый катет a.
const smallCathetuses = naturalNumbers.pipe( map(addOne), map(toOdd), );
Из потока с малыми катетами a, опираясь на формулы, создим поток с большими катетами b. При испускании малого катета будет испускаться соответствующий ему большой катет.
const bigCathetuses = smallCathetuses.pipe( map(toSquare), map(toNatural), );
Поток с гипотенузами получить проще всего, надо всего лишь прибавить единицу к большему катету
const hypotenuses = bigCathetuses.pipe( map(addOne), );
Теперь у нас есть три потока: smallCathetuses, bigCathetuses и hypotenuses. Если выбирать из каждого потока по последнему значению, то будем получать искомые пифагоровы тройки.
Сделать это можно с помощью функции withLatestFrom(). Она принимает несколько потоков и возвращает массив, первый элемент которого — это элемент обрабатываемого потока, а следующие значения — это последние значения из переданных потоков.
const pythagoreanTriples = smallCathetuses.pipe( withLatestFrom(bigCathetuses, hypotenuses), );
Подпишемся на поток пифагоровых троек и будем наблюдать их
pythagoreanTriples.subscribe((value) => { console.log(value); }); // [3, 4, 5] // [5, 12, 13] // [7, 24, 25] // ...
Генерация таких пифагоровых троек (где гипотенуза отличается от большего катета на единицу) имеет и практическое применение. Например, можно построить тысячеугольник, у которого все стороны и диагонали будут целыми.
Подробный алгоритм построения от Бориса Трушина
Весь код доступен на ГитХабе
P. S. За обложку спасибо Тане Лишаевой
ссылка на оригинал статьи https://habr.com/ru/articles/729112/
Добавить комментарий