<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>@selfinstallation</title><generator>teletype.in</generator><description><![CDATA[@selfinstallation]]></description><link>https://teletype.in/@selfinstallation?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=selfinstallation</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/selfinstallation?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/selfinstallation?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Thu, 25 Jun 2026 21:30:42 GMT</pubDate><lastBuildDate>Thu, 25 Jun 2026 21:30:42 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@selfinstallation/RRINdfWMh</guid><link>https://teletype.in/@selfinstallation/RRINdfWMh?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=selfinstallation</link><comments>https://teletype.in/@selfinstallation/RRINdfWMh?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=selfinstallation#comments</comments><dc:creator>selfinstallation</dc:creator><title>Мини-скринсейвер с летающими шариками</title><pubDate>Fri, 08 May 2020 13:45:17 GMT</pubDate><description><![CDATA[Это просто интересная программа, с кодом которой можно поэкспериментировать и на работу которой можно позалипать.]]></description><content:encoded><![CDATA[
  <p>Это просто интересная программа, с кодом которой можно поэкспериментировать и на работу которой можно позалипать.</p>
  <h3>Если кратко:</h3>
  <p>Создаются n шариков (в коде ниже — 20), поле, по которому они будут перемещаться и, по желанию, препятствие внутри поля, от которого шарики будут также отталкиваться.</p>
  <p>Можно менять размеры и положение поля, препятствия, размер, цвет и количество самих шариков. Начнём.</p>
  <h3>Описание кода</h3>
  <p>Я буду писать на C++,  поэтому для начала подключаем библиотеки:</p>
  <pre>#include &lt;windows.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;math.h&gt;
#include &lt;ddraw.h&gt;
using namespace std;

const int ballsCount = 20;</pre>
  <p>Создаём структуры Шар, Поле и Препятствие:</p>
  <pre>struct Ball {
    float x, y; // координаты шарика
    float dx, dy; // изменение координат по х и у
    float R, G, B; // доли красного, зелёного и синего цветов
    float r; // радиус шарика
};
struct Field {
    float x, y;
    float width, height;
};
struct Obstacle {
    float x, y;
    float width, height;
};</pre>
  <p>Функция, убирающая курсор:</p>
  <pre>void ShowConsoleCursor(bool showFlag)
{
    HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_CURSOR_INFO cursorInfo;
    
    GetConsoleCursorInfo(out, &amp;cursorInfo);
    cursorInfo.bVisible = showFlag;
    SetConsoleCursorInfo(out, &amp;cursorInfo);
}</pre>
  <p>Главная функция:</p>
  <p>Создаём наши поле и препятствие и задаём их параметры (можете изменить их на любые другие положительные числа.</p>
  <pre>Obstacle obstacle;
obstacle.x = 200;
obstacle.y = 90;
obstacle.width = 20;
obstacle.height = 90;

Field board;
board.x = 1;
board.y = 1;
board.width = 350;
board.height = 250;</pre>
  <p>Создаём массив из 20 шариков и прописываем их параметры:</p>
  <pre>Ball balls[ballsCount];
for (int i = 0; i &lt; ballsCount; i++) {
    balls[i].r = 10 + rand() % 10; // радиус от 10 до 19
    balls[i].x = 0 + rand() % (int)board.width;
    balls[i].y = 0 + rand() % (int)board.height;
    balls[i].dx = 5;
    balls[i].dy = 5;
    balls[i].R = rand() % 256; // интенсивность цветов от 0 до 255
    balls[i].G = rand() % 256;
    balls[i].B = rand() % 256;
}</pre>
  <p>Это всё отвечает за рисование в консоли. Можете не обращать внимания:</p>
  <pre>RECT rect;
HWND window = GetConsoleWindow();
HDC handler = GetDC(window);
GetClientRect(window, &amp;rect);
HPEN fieldPen = CreatePen(PS_SOLID, 2, RGB(255, 255, 255));
HBRUSH fieldBrush = CreateSolidBrush(RGB(0, 0, 0));
HPEN ballPen = CreatePen(PS_SOLID, 2, RGB(255, 255, 255));
HBRUSH ballBrush = CreateSolidBrush(RGB(0, 0, 0));
// фикс морганий
HDC memDC = CreateCompatibleDC(handler);
HBITMAP hBitmap = CreateCompatibleBitmap(handler, rect.right, rect.bottom);
SelectObject(memDC, hBitmap);
PatBlt(memDC, 0, 0, rect.right, rect.left, BLACKNESS);
// удаляем _ из консоли
ShowConsoleCursor(false);
int fps = 70;</pre>
  <p>Далее в вечном цикле while(true) последует ещё немного графики:</p>
  <pre>SelectObject(memDC, fieldPen);
SelectObject(memDC, fieldBrush);
Rectangle(memDC, board.x, board.y, board.x + board.width, board.y + board.height);
// Obstacle
Rectangle(memDC, obstacle.x, obstacle.y, obstacle.x + obstacle.width, obstacle.y + obstacle.height);</pre>
  <p>Сдвинем каждый шарик и оттолкнём от стенки, если он до неё долетел:</p>
  <pre>for (int i = 0; i &lt; ballsCount; i++) {
       balls[i].x += balls[i].dx;
       balls[i].y += balls[i].dy;
       if (balls[i].x + balls[i].r &gt; board.width) // правая стенка
       {
            balls[i].x -= balls[i].x - board.width + balls[i].r;
            balls[i].dx = -balls[i].dx;
       }
       if (balls[i].y + balls[i].r &gt; board.height) // верхняя стенка
       {
            balls[i].y -= balls[i].y - board.height + balls[i].r;
            balls[i].dy = -balls[i].dy;
            balls[i].dy += rand() % 1;
        }
        if (balls[i].x - balls[i].r &lt; 0) // левая стенка
        {
            balls[i].x = balls[i].r;
            balls[i].dx = -balls[i].dx;
            balls[i].dx += rand() % 1;
        }
        if (balls[i].y - balls[i].r &lt; 0) // нижняя стенка
        {
            balls[i].y = balls[i].r;
            balls[i].dy = -balls[i].dy;
            balls[i].dy += rand() % 1;
        }
        if ((balls[i].x + balls[i].r &gt; obstacle.x) &amp;&amp; (balls[i].x + balls[i].r &lt; obstacle.x + obstacle.width) 
            &amp;&amp; (balls[i].y &gt;= obstacle.y) &amp;&amp; (balls[i].y &lt;= obstacle.y + obstacle.height)) // левая стенка препятствия
        {
            balls[i].x = balls[i].x - (balls[i].x - obstacle.x) - balls[i].r;
            balls[i].dx = -balls[i].dx;
        }
        if ((balls[i].x &gt;= obstacle.x) &amp;&amp; (balls[i].x &lt;= obstacle.x + obstacle.width) &amp;&amp; (balls[i].y + balls[i].r &gt; obstacle.y) 
            &amp;&amp; (balls[i].y + balls[i].r &lt; obstacle.y + obstacle.height)) // верхняя
        {
            balls[i].y = balls[i].y - (balls[i].y - obstacle.y) - balls[i].r;
            balls[i].dy = -balls[i].dy;
            balls[i].dy += rand() % 1;
        }
        if ((balls[i].x - balls[i].r &gt; obstacle.x) &amp;&amp; (balls[i].x - balls[i].r &lt; obstacle.x + obstacle.width) &amp;&amp; (balls[i].y &gt;= obstacle.y) 
            &amp;&amp; (balls[i].y &lt;= obstacle.y + obstacle.height)) // правая
        {
            balls[i].x = balls[i].x + (obstacle.x + obstacle.width - balls[i].x) + balls[i].r;
            balls[i].dx = -balls[i].dx;
        }
        if ((balls[i].x &gt;= obstacle.x) &amp;&amp; (balls[i].x &lt;= obstacle.x + obstacle.width) &amp;&amp; (balls[i].y - balls[i].r &gt; obstacle.y) 
            &amp;&amp; (balls[i].y - balls[i].r &lt; obstacle.y + obstacle.height)) // нижняя
        {
            balls[i].y = balls[i].y + (obstacle.y + obstacle.height - balls[i].y) + balls[i].r;
            balls[i].dy = -balls[i].dy;
            balls[i].dy += rand() % 1;
       }</pre>
  <p>Ещё немного графики в том же цикле for:</p>
  <pre>ballPen = CreatePen(PS_SOLID, 2, RGB(255, 255, 255));
ballBrush = CreateSolidBrush(RGB(balls[i].R, balls[i].G, balls[i].B));
SelectObject(memDC, ballPen);
SelectObject(memDC, ballBrush);
Ellipse(memDC, balls[i].x - balls[i].r, balls[i].y - balls[i].r, balls[i].x + balls[i].r, balls[i].y + balls[i].r);
DeleteObject(ballPen);
DeleteObject(ballBrush);</pre>
  <p>Оставшийся код тоже посвящён графике, не буду его разбирать, приведу ниже</p>
  <h3>код целиком:</h3>
  <pre>#include &lt;windows.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;math.h&gt;
#include &lt;ddraw.h&gt;
using namespace std;
const int ballsCount = 20;
struct Ball {
    float x, y; // координаты шарика
    float dx, dy; // изменение координат по х и у
    float R, G, B; // доли красного, зелёного и синего цветов
    float r; // радиус шарика
};
struct Field {
    float x, y;
    float width, height;
};
struct Obstacle {
    float x, y;
    float width, height;
};
void ShowConsoleCursor(bool showFlag)
{
    HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_CURSOR_INFO cursorInfo;
    GetConsoleCursorInfo(out, &amp;cursorInfo);
    cursorInfo.bVisible = showFlag;
    SetConsoleCursorInfo(out, &amp;cursorInfo);
}
int main()
{
    Obstacle obstacle;
    obstacle.x = 200;
    obstacle.y = 90;
    obstacle.width = 20;
    obstacle.height = 90;
    Field board;
    board.x = 1;
    board.y = 1;
    board.width = 350;
    board.height = 250;
    Ball balls[ballsCount];
    for (int i = 0; i &lt; ballsCount; i++) {
        balls[i].r = 10 + rand() % 10;
        balls[i].x = 0 + rand() % (int)board.width;
        balls[i].y = 0 + rand() % (int)board.height;
        balls[i].dx = 5;
        balls[i].dy = 5;
        balls[i].R = rand() % 256;
        balls[i].G = rand() % 256;
        balls[i].B = rand() % 256;
    }
    RECT rect;
    HWND window = GetConsoleWindow();
    HDC handler = GetDC(window);
    GetClientRect(window, &amp;rect);
    HPEN fieldPen = CreatePen(PS_SOLID, 2, RGB(255, 255, 255));
    HBRUSH fieldBrush = CreateSolidBrush(RGB(0, 0, 0));
    HPEN ballPen = CreatePen(PS_SOLID, 2, RGB(255, 255, 255));
    HBRUSH ballBrush = CreateSolidBrush(RGB(0, 0, 0));
    // фикс морганий
    HDC memDC = CreateCompatibleDC(handler);
    HBITMAP hBitmap = CreateCompatibleBitmap(handler, rect.right, rect.bottom);
    SelectObject(memDC, hBitmap);
    PatBlt(memDC, 0, 0, rect.right, rect.left, BLACKNESS);
    // удаляем _ из консоли
    ShowConsoleCursor(false);
    int fps = 70;
    while (true) {
        SelectObject(memDC, fieldPen);
        SelectObject(memDC, fieldBrush);
        Rectangle(memDC, board.x, board.y, board.x + board.width, board.y + board.height);
        // Obstacle
        Rectangle(memDC, obstacle.x, obstacle.y, obstacle.x + obstacle.width, obstacle.y + obstacle.height);
        for (int i = 0; i &lt; ballsCount; i++) {
            balls[i].x += balls[i].dx;
            balls[i].y += balls[i].dy;
            if (balls[i].x + balls[i].r &gt; board.width) // правая стенка
            {
                balls[i].x -= balls[i].x - board.width + balls[i].r;
                balls[i].dx = -balls[i].dx;
            }
            if (balls[i].y + balls[i].r &gt; board.height) // верхняя стенка
            {
                balls[i].y -= balls[i].y - board.height + balls[i].r;
                balls[i].dy = -balls[i].dy;
                balls[i].dy += rand() % 1;
            }
            if (balls[i].x - balls[i].r &lt; 0) // левая стенка
            {
                balls[i].x = balls[i].r;
                balls[i].dx = -balls[i].dx;
                balls[i].dx += rand() % 1;
            }
            if (balls[i].y - balls[i].r &lt; 0) // нижняя стенка
            {
                balls[i].y = balls[i].r;
                balls[i].dy = -balls[i].dy;
                balls[i].dy += rand() % 1;
            }
            if ((balls[i].x + balls[i].r &gt; obstacle.x) &amp;&amp; (balls[i].x + balls[i].r &lt; obstacle.x + obstacle.width) 
                &amp;&amp; (balls[i].y &gt;= obstacle.y) &amp;&amp; (balls[i].y &lt;= obstacle.y + obstacle.height)) // левая стенка препятствия
            {
                balls[i].x = balls[i].x - (balls[i].x - obstacle.x) - balls[i].r;
                balls[i].dx = -balls[i].dx;
            }
            if ((balls[i].x &gt;= obstacle.x) &amp;&amp; (balls[i].x &lt;= obstacle.x + obstacle.width) &amp;&amp; (balls[i].y + balls[i].r &gt; obstacle.y) 
                &amp;&amp; (balls[i].y + balls[i].r &lt; obstacle.y + obstacle.height)) // верхняя
            {
                balls[i].y = balls[i].y - (balls[i].y - obstacle.y) - balls[i].r;
                balls[i].dy = -balls[i].dy;
                balls[i].dy += rand() % 1;
            }
            if ((balls[i].x - balls[i].r &gt; obstacle.x) &amp;&amp; (balls[i].x - balls[i].r &lt; obstacle.x + obstacle.width) &amp;&amp; (balls[i].y &gt;= obstacle.y) 
                &amp;&amp; (balls[i].y &lt;= obstacle.y + obstacle.height)) // правая
            {
                balls[i].x = balls[i].x + (obstacle.x + obstacle.width - balls[i].x) + balls[i].r;
                balls[i].dx = -balls[i].dx;
            }
            if ((balls[i].x &gt;= obstacle.x) &amp;&amp; (balls[i].x &lt;= obstacle.x + obstacle.width) &amp;&amp; (balls[i].y - balls[i].r &gt; obstacle.y) 
                &amp;&amp; (balls[i].y - balls[i].r &lt; obstacle.y + obstacle.height)) // нижняя
            {
                balls[i].y = balls[i].y + (obstacle.y + obstacle.height - balls[i].y) + balls[i].r;
                balls[i].dy = -balls[i].dy;
                balls[i].dy += rand() % 1;
            }
            ballPen = CreatePen(PS_SOLID, 2, RGB(255, 255, 255));
            ballBrush = CreateSolidBrush(RGB(balls[i].R, balls[i].G, balls[i].B));
            SelectObject(memDC, ballPen);
            SelectObject(memDC, ballBrush);
            Ellipse(memDC, balls[i].x - balls[i].r, balls[i].y - balls[i].r, balls[i].x + balls[i].r, balls[i].y + balls[i].r);
            DeleteObject(ballPen);
            DeleteObject(ballBrush);
        }
        BitBlt(handler, 0, 0, rect.right, rect.bottom, memDC, 0, 0, SRCCOPY);
        Sleep(2000 / fps);
    }
    ReleaseDC(window, handler);
    DeleteObject(memDC);
}</pre>
  <h3>Бонус)</h3>
  <p>Если вставить этот код в начале цикла for, шарики будут переливаться разными цветами:</p>
  <pre>if (balls[i].R &gt;= 255)
    balls[i].R = 0;
if (balls[i].G &gt;= 255)
    balls[i].G = 0;
if (balls[i].B &gt;= 255)
    balls[i].B = 0;
balls[i].R += 1 + rand() % 10;
balls[i].G += 1 + rand() % 5;
balls[i].B += 1 + rand() % 4;</pre>
  <p><a href="https://tlgg.ru/Selfinstallation" target="_blank">https://tlgg.ru/Selfinstallation</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@selfinstallation/3GBKzLBEB</guid><link>https://teletype.in/@selfinstallation/3GBKzLBEB?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=selfinstallation</link><comments>https://teletype.in/@selfinstallation/3GBKzLBEB?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=selfinstallation#comments</comments><dc:creator>selfinstallation</dc:creator><title>Написание класса Дроби на C++</title><pubDate>Sun, 03 May 2020 19:31:15 GMT</pubDate><description><![CDATA[<img src="https://teletype.in/files/16/04/160406b3-bd58-4424-a327-8d0665338486.jpeg"></img>Это довольно классическая задача, которая рано или поздно встречается каждому программисту. Я думаю, вы знаете, что компьютер не хранит вещественные числа точно и что погрешности, как правило вызванные округлением, имеют свойство накапливаться, а потому даже небольшая погрешность потенциально может сильно исказить результат арифметических операций.]]></description><content:encoded><![CDATA[
  <p>Это довольно классическая задача, которая рано или поздно встречается каждому программисту. Я думаю, вы знаете, что компьютер не хранит вещественные числа точно и что погрешности, как правило вызванные округлением, имеют свойство накапливаться, а потому даже небольшая погрешность потенциально может сильно исказить результат арифметических операций.</p>
  <p>Именно из-за этого класс Дроби часто необходим при работе с большими вычислениями, поскольку помогает хранить дробные числа точно (в виде двух целых чисел) и производить промежуточные расчёты без накопления погрешности.</p>
  <p>Новый тип данных Fraction будет иметь два поля — числитель (numerator) и знаменатель (denominator). Знак будет храниться в числителе.</p>
  <pre>class Fraction {
public:
    int numer, denom;
    Fraction(int n = 0, int d = 1) { //конструктор, на вход подаются два числа n и d
        numer = n;
        denom = d;
    }
}</pre>
  <p>Если на входе одно число, оно записывается в числитель, а знаменатель по умолчанию равен 1. В этом случае мы получаем обычное целое число. Если объект создаётся без входных параметров, по умолчанию создаётся число 0.</p>
  <p>Арифметические операции для дробей будем реализовывать с помощью перегрузки соответствующих операторов:</p>
  <pre>Fraction operator + (Fraction&amp; other) {
        return
            Fraction(
                numer * other.denom + denom * other.numer,
                denom * other.denom
                );
}</pre>
  <p>Вычитание выполняется как сложение с отрицательным числом:)</p>
  <pre>Fraction operator - (Fraction&amp; other) {
        return Fraction(numer, denom) + Fraction(-other.numer, other.denom);
}</pre>
  <p>Умножение и деление (умножение на &quot;перевёрнутую дробь&quot;)</p>
  <pre>Fraction operator * (Fraction&amp; other) {
        return
            Fraction(
                numer * other.numer, denom * other.denom
                ).reduce();
 }
 Fraction operator / (Fraction&amp; other) {
        return Fraction(numer, denom) * Fraction(other.denom, other.numer);
 }</pre>
  <p>Почти готово. Осталось прописать ввод/вывод дроби, и, самое интересное — сокращение дроби до несократимой. Для этого напишем функции input, show и reduce.</p>
  <p>Начнём с сокращения: дробь станет несократимой, если числитель и знаменатель поделить на их НОД, поэтому его сначала нужно найти. Есть разные способы это сделать, я применю рекурсию (алгоритм Евклида):</p>
  <pre>int fract_nod(int a, int b) {
    if (b == 0) return a;
    return fract_nod(b, a % b);
}</pre>
  <p>Здесь важно, чтобы a было больше или равно b, а также чтобы числа были положительны, но это мы учтём в самой функции reduce.</p>
  <pre>Fraction reduce() {
        int a = max(abs(numer), abs(denom)), b = min(abs(numer), abs(denom));
        int sgn; //знак нашей дроби
        if (numer * denom &gt;= 0) sgn = 1;
        else sgn = -1;
        int nod = fract_nod(a, b);
        return Fraction(sgn * (abs(numer) / nod), abs(denom) / nod);
}</pre>
  <p>Теперь нужно встроить эту функцию в операции сложения и умножения так, чтобы конечный результат был несократимой дробью:</p>
  <pre>Fraction operator + (Fraction&amp; other) {
        return
            Fraction(
                numer * other.denom + denom * other.numer,
                denom * other.denom
                ).reduce(); //новое
}</pre>
  <pre>Fraction operator * (Fraction&amp; other) {
        return
            Fraction(
                numer * other.numer, denom * other.denom
                ).reduce(); //новое
}</pre>
  <p>Напишем функцию вывода:</p>
  <pre>void show() {
        cout &lt;&lt; &quot;\t&quot; &lt;&lt; numer;
        if (denom != 1) cout &lt;&lt; &quot;/&quot; &lt;&lt; denom;
}</pre>
  <p>Логично вводить дроби в том же формате, что и выводить, т.е. в виде m/n, где m — целое число, а n — натуральное. Поскольку мы пишем класс на плюсах, придётся повозиться со считыванием строки и преобразованием её в два числа (возможно, с отрицательным знаком).</p>
  <pre>Fraction input(string&amp; s) {
    int n = 0, d = 0, deg = 0;
    int slash_pos = s.find(&#x27;/&#x27;); //ищем разделитель
    if (slash_pos != s.npos) { //если он есть (число введено как дробь)
        int i = slash_pos - 1;
        //записываем в n число перед &quot;/&quot;
        while (i &gt; -1) {
            if (s[i] != &#x27;-&#x27;)
                n += (s[i] - 48) * pow(10, deg++); //сдвиг на 48, т.к. код &quot;0&quot; в ASCII = 48
            else
                n = -n;
            i -= 1;
        }
        deg = 0;
        i = s.size() - 1;
        //записываем в d число после &quot;/&quot;
        while (i &gt; slash_pos) {
            if (s[i] != &#x27;-&#x27;)
                d += (s[i] - 48) * pow(10, deg++);
            else
                d = -d;
            i -= 1;
        }
    } else { //если число введено как целое
        d = 1;
        int i = s.size() - 1;
        while (i &gt; -1) {
            if (s[i] != &#x27;-&#x27;)
                n += (s[i] - 48) * pow(10, deg++);
            else
                n = -n;
            i -= 1;
        }
    }
    //создаём дробь с введёнными числами и сокращаем
    Fraction f;
    if (d) f = Fraction(n, d).reduce();
    else f = Fraction(n);
    return f;
}</pre>
  <p>Готово!</p>
  <h3>Код целиком</h3>
  <pre>#include &lt;algorithm&gt;
#include &lt;string&gt;
using namespace std;
int fract_nod(int a, int b) {
    if (b == 0) return a;
    return fract_nod(b, a % b);
}
class Fraction {
public:
    int numer, denom;
    Fraction(int n = 0, int d = 1) {
        numer = n;
        denom = d;
    }
    Fraction reduce() {
        int a = max(abs(numer), abs(denom)), b = min(abs(numer), abs(denom));
        int sgn;
        if (numer * denom &gt;= 0) sgn = 1;
        else sgn = -1;
        int nod = fract_nod(a, b);
        return Fraction(sgn * (abs(numer) / nod), abs(denom) / nod);
    }
    void show() {
        cout &lt;&lt; &quot;\t&quot; &lt;&lt; numer;
        if (denom != 1) cout &lt;&lt; &quot;/&quot; &lt;&lt; denom;
    }
    Fraction operator + (Fraction&amp; other) {
        return
            Fraction(
                numer * other.denom + denom * other.numer,
                denom * other.denom
                ).reduce();
    }
    Fraction operator - (Fraction&amp; other) {
        return Fraction(numer, denom) + Fraction(-other.numer, other.denom);
    }
    Fraction operator * (Fraction&amp; other) {
        return
            Fraction(
                numer * other.numer, denom * other.denom
                ).reduce();
    }
    Fraction operator / (Fraction&amp; other) {
        return Fraction(numer, denom) * Fraction(other.denom, other.numer);
    }
};
Fraction input(string&amp; s) {
    int n = 0, d = 0, deg = 0;
    int slash_pos = s.find(&#x27;/&#x27;);
    if (slash_pos != s.npos) {
        int i = slash_pos - 1;
        while (i &gt; -1) {
            if (s[i] != &#x27;-&#x27;)
                n += (s[i] - 48) * pow(10, deg++);
            else
                n = -n;
            i--;
        }
        deg = 0;
        i = s.size() - 1;
        while (i &gt; slash_pos) {
            if (s[i] != &#x27;-&#x27;)
                d += (s[i] - 48) * pow(10, deg++);
            else
                d = -d;
            i--;
        }
    } else {
        d = 1;
        int i = s.size() - 1;
        while (i &gt; -1) {
            if (s[i] != &#x27;-&#x27;)
                n += (s[i] - 48) * pow(10, deg++);
            else
                n = -n;
            i--;
        }
    }
    Fraction f;
    if (d) f = Fraction(n, d).reduce();
    else f = Fraction(n);
    return f;
}</pre>
  <p><a href="https://tlgg.ru/Selfinstallation" target="_blank">https://tlgg.ru/Selfinstallation</a></p>
  <figure class="m_original">
    <img src="https://teletype.in/files/16/04/160406b3-bd58-4424-a327-8d0665338486.jpeg" width="500" />
  </figure>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@selfinstallation/6WIffXugcD</guid><link>https://teletype.in/@selfinstallation/6WIffXugcD?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=selfinstallation</link><comments>https://teletype.in/@selfinstallation/6WIffXugcD?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=selfinstallation#comments</comments><dc:creator>selfinstallation</dc:creator><title>Lingua Romana Perligata: пример программы и её разбор</title><pubDate>Thu, 30 Apr 2020 14:16:02 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/b9/ed/b9ed8695-fce4-4b44-a5d1-2a288a617ada.png"></media:content><description><![CDATA[<img src="https://teletype.in/files/11/12/1112dd96-f757-44e1-a5d1-c5f52225f289.jpeg"></img>Эта задача мне встретилась на  контесте April Fools Day Contest 2020 от CodeForces. Участники должны были понять, что делает предложенная программа, и составить на основе этого своё решение.]]></description><content:encoded><![CDATA[
  <p>Эта задача мне встретилась на  контесте <a href="https://codeforces.com/contest/1331" target="_blank">April Fools Day Contest 2020</a> от CodeForces. Участники должны были понять, что делает предложенная программа, и составить на основе этого своё решение.</p>
  <h3>Сам код:</h3>
  <pre>per nextum in unam tum XI conscribementis fac sic
    vestibulo perlegementum da varo.
    morde varo.
    seqis cumula varum.
cis

per nextum in unam tum XI conscribementis fac sic
    seqis decumulamenta da varo.
    varum privamentum fodementum da aresulto.
    varum tum III elevamentum tum V multiplicamentum da bresulto.
    aresultum tum bresultum addementum da resulto.
    
    si CD tum resultum non praestantiam fac sic
        dictum sic f(%d) = %.2f cis tum varum tum resultum egresso describe.
        novumversum egresso scribe.    
    cis  
    si CD tum resultum praestantiam fac sic        
        dictum sic f(%d) = MAGNA NIMIS! cis tum varum egresso describe.        
        novumversum egresso scribe.            
    cis
 cis</pre>
  <p>Кроме ограничений на переменные и набора входных/выходных данных для одного теста ничего не дано, так что сперва надо поработать с самим кодом.</p>
  <p>Возможно, кто-то умеет гуглить и сразу мог понять, что эта программа написана на Lingua::Romana::Perligata, модуле Perl, позволяющем писать программы на латыни, и просто перевести код, но я вместо этого эксперементировал с Google переводчиком и использовал свои познания в лингвистике.</p>
  <p>Поскольку разбор задачи на самой платформе CodeForces не был подробным, я решил его дополнить. Ниже приведены версии кода на Python и C++, а также на естественном языке с переводом конкретных слов (указаны в скобках).</p>
  <h3>Python</h3>
  <pre>v = []
for i in range(11):
    v.append(int(input()))

for i in range(11):
    var = v.pop()
    a = abs(var) ** 0.5
    b = (var ** 3) * 5
    result = a + b
    if 400 &gt; result:
        print(&quot;f(&quot;, var, &#x27;) = &#x27;, &#x27;%.2f&#x27; % result, sep=&#x27;&#x27;)
    else:
        print(&quot;f(&quot;, var, &quot;) = MAGNA NIMIS!&quot;, sep=&#x27;&#x27;)</pre>
  <h3>C++</h3>
  <pre>using namespace std;
#include &lt;iostream&gt;
#include &lt;iomanip&gt;
#include &lt;vector&gt;
#include &lt;cmath&gt;

using namespace std;
int main() {
    int var;
    float a, b, result;
    vector &lt;int&gt; v;
    for (sizet i = 0; i &lt; 11; ++i) {
        cin &gt;&gt; var;
        v.pushback(var);
    }
    for (size_tt i = 0; i &lt; 11; ++i) {
        var = v.back();
        v.pop_back();
        a = sqrt(abs(var));
        b = pow(var, 3) * 5;
        result = a + b;
        if (400 &gt; result) {
            cout &lt;&lt; &quot;f(&quot; &lt;&lt; var &lt;&lt; &quot;) = &quot; &lt;&lt; fixed &lt;&lt; setprecision(2) &lt;&lt; result &lt;&lt; &quot;\n&quot;;
        } else {
            cout &lt;&lt; &quot;f(&quot; &lt;&lt; var &lt;&lt; &quot;) = MAGNA NIMIS!\n&quot;;
        }
    }
    return 0;
}</pre>
  <h3>Естественный язык</h3>
  <pre>Перебирая для некоторой скалярной переменной(per nextum) i значения от 1 до 11 (in unam tum XI) :
{
    Стандартный ввод(vestibulo) до конца строки(perlegementum) в(da) новую переменную(varo) var;
    Обрезать символы перевода строки(morde);
    “Сложить” в массив(seqis cumula) переменную var;
}
Перебирая для некоторой скалярной переменной(per nextum) i значения от 1 до 11 (in unam tum XI) :
{
    “Вынуть” из массива(seqis decumulamenta) переменную var;
    В новую переменную a(da aresulto) записать квадратный корень(fodementum) модуля(privamentum)  var;
    В новую переменную b(da bresulto) записать произведение 5 (tum V multiplicamentum) и куба var(tum III elevamentum);
    В новую переменную result(da resulto) записать сумму(addementum) a и b(aresultum tum bresultum);
    Если(si) 400 не меньше(non praestantiam), чем result,
    {
        Вывести(dictum) “f(var) = result” с точностью до 2 знаков после запятой(%.2f), стандартный вывод(egresso describe);
    Перевод на новую строку(novumversum), стандартный вывод(egresso describe).
    }
        Если(si) 400 меньше(praestantiam), чем result,
        {
            Вывести “f(var) = MAGNA NIMIS!”(TOO MUCH!), стандартный вывод(egresso describe);
    Перевод на новую строку(novumversum), стандартный вывод(egresso describe).
        }
}</pre>
  <p>В этой программе кто-то мог узнать TPK алгоритм, помогающий отслеживать эволюцию языков программирования, и да, это он и есть.</p>
  <figure class="m_original">
    <img src="https://teletype.in/files/11/12/1112dd96-f757-44e1-a5d1-c5f52225f289.jpeg" width="735" />
  </figure>
  <p>Про него и про сам Lingua::Romana::Perligata я могу рассказать подробнее в следующих статьях, если это будет кому-то интересно.</p>
  <p><a href="https://tlgg.ru/Selfinstallation" target="_blank">https://tlgg.ru/Selfinstallation</a></p>

]]></content:encoded></item></channel></rss>