From bd50165d5320eb51b73fa8e4fd8df1310c28bc94 Mon Sep 17 00:00:00 2001 From: Aleksey Lobanov Date: Fri, 4 Nov 2016 16:48:29 +0300 Subject: [PATCH] Changed title icon --- author/aleksei-lobanov.html | 2 +- author/aleksei-lobanov.html.gz | Bin 3692 -> 3692 bytes author/pages/about.html | 9 ++ author/pages/about.html.gz | Bin 0 -> 1702 bytes author/pages/projects.html | 9 ++ author/pages/projects.html.gz | Bin 0 -> 1881 bytes category/misc.html | 2 +- category/misc.html.gz | Bin 2508 -> 2508 bytes category/proekty.html | 2 +- category/proekty.html.gz | Bin 2167 -> 2167 bytes category/project-euler.html | 2 +- category/project-euler.html.gz | Bin 2669 -> 2668 bytes index.html | 2 +- index.html.gz | Bin 3670 -> 3670 bytes pages/projects.html | 2 +- pages/projects.html.gz | Bin 1988 -> 1987 bytes posts/crossgen-v10/index.html | 2 +- posts/crossgen-v10/index.html.gz | Bin 4313 -> 4313 bytes .../index.html | 2 +- .../index.html.gz | Bin 3454 -> 3454 bytes .../kak-ia-shakhmatnogo-bota-pisal/index.html | 2 +- .../index.html.gz | Bin 4481 -> 4480 bytes posts/moi-pervyi-post/index.html | 2 +- posts/moi-pervyi-post/index.html.gz | Bin 2279 -> 2279 bytes posts/moio-reshenie-zadachi-134/index.html | 2 +- posts/moio-reshenie-zadachi-134/index.html.gz | Bin 4058 -> 4056 bytes posts/moio-reshenie-zadachi-146/index.html | 2 +- posts/moio-reshenie-zadachi-146/index.html.gz | Bin 5295 -> 5294 bytes posts/moio-reshenie-zadachi-60/index.html | 2 +- posts/moio-reshenie-zadachi-60/index.html.gz | Bin 6769 -> 6768 bytes .../index.html | 2 +- .../index.html.gz | Bin 3913 -> 3913 bytes posts/wallabag-i-realnaia-zhizn/index.html | 2 +- posts/wallabag-i-realnaia-zhizn/index.html.gz | Bin 4149 -> 4149 bytes sitemap.xml | 92 +++++++++--------- sitemap.xml.gz | Bin 712 -> 718 bytes tag/bgl.html | 2 +- tag/bgl.html.gz | Bin 1748 -> 1748 bytes tag/blog.html | 2 +- tag/blog.html.gz | Bin 1568 -> 1567 bytes tag/bot.html | 2 +- tag/bot.html.gz | Bin 1625 -> 1624 bytes tag/c.html | 2 +- tag/c.html.gz | Bin 2712 -> 2711 bytes tag/flint.html | 2 +- tag/flint.html.gz | Bin 2279 -> 2279 bytes tag/go.html | 2 +- tag/go.html.gz | Bin 1650 -> 1650 bytes tag/matematika.html | 2 +- tag/matematika.html.gz | Bin 2232 -> 2232 bytes tag/open-source.html | 2 +- tag/open-source.html.gz | Bin 1656 -> 1656 bytes tag/proekt.html | 2 +- tag/proekt.html.gz | Bin 2165 -> 2165 bytes tag/project-euler.html | 2 +- tag/project-euler.html.gz | Bin 2669 -> 2668 bytes tag/python.html | 2 +- tag/python.html.gz | Bin 2365 -> 2365 bytes tag/shakhmaty.html | 2 +- tag/shakhmaty.html.gz | Bin 1626 -> 1625 bytes tag/sympy.html | 2 +- tag/sympy.html.gz | Bin 2364 -> 2364 bytes tag/wallabag.html | 2 +- tag/wallabag.html.gz | Bin 1652 -> 1651 bytes tag/wxwidgets.html | 2 +- tag/wxwidgets.html.gz | Bin 1751 -> 1751 bytes 66 files changed, 94 insertions(+), 76 deletions(-) create mode 100644 author/pages/about.html create mode 100644 author/pages/about.html.gz create mode 100644 author/pages/projects.html create mode 100644 author/pages/projects.html.gz diff --git a/author/aleksei-lobanov.html b/author/aleksei-lobanov.html index ce8c901..fd5a690 100644 --- a/author/aleksei-lobanov.html +++ b/author/aleksei-lobanov.html @@ -1,7 +1,7 @@ Блог 529 - Алексей Лобанов
  1. Моё решение задачи 134

    Краткое условие: назовём порождающим для двух последовательных простых \(p_1 < p_2\) наименьшее натуральное число, что оно закачивается на \(p_1\) и при этом делится на \(p_2\). Необходимо найти сумму порождающих для всех \(p_1 \in \left[ 5; 10^6 \right]\)

    Здравствуйте, я Алексей Лобанов

    В данный момент студент ВМК МГУ. Немного занимаюсь фрилансом.

    В основном программирую на Python и C++, есть также знания HTML, CSS, Delphi, Bash. Разрабатываю прикладные приложения (в том числе графические под Win/MacOS/Linux), парсеры (с использованием scrapy), скрипты автоматизации Есть опыт разработки веб-приложений с использованием микрофреймворка Flask.


    Powered by Pelican.

    \ No newline at end of file diff --git a/author/pages/about.html.gz b/author/pages/about.html.gz new file mode 100644 index 0000000000000000000000000000000000000000..7e59c89512843bb30818e9a9fa5f7b2b290e65b3 GIT binary patch literal 1702 zcmV;X23h$ZiwFP!000021GQIeZxlBW{?4y3_kl~4+ughn!pq%K5&}iyC2F88iX!CO z_3fH??Zx)q<)~Wmrt$$qTdJy3U!+R?10f_3Xb68{_aAlay$cDKh=4>Q?cR-No@Zt} z9?#VepS?13_4?c_igm*LL-oUsvp`#jX>?&0O)dJ!{?*MY3K&+ZQQ^Y5sX)V_` zCDSbjTq>op)~Q2oWwhO>eCu30(EfgjgYiyKpgu8 z=osZoND|hlDBWd5#e{%OEJ>?Taa~WxBq3g)l*ffkFr&AL3*Y*NrJjlPr02DONV$;^ z5hFOI$_+$fOi#CPLRq&l7gHvbNMj<8sH|yn#vmiS7IYFefr!HFqQZm?)pPR~SL#q?gOGF4j z^tN=y-DB>!-5k@^>RxFGAIkRD6k*pN=<|orj=y@^Z;fROYf0!n75}=(5S9dG3bq4b zj_OKF!6RQ}I)o5H;3@^EDMd#S>7qHPO+`>0@6KAe9z$NbwrneYmPQhX1a(Cw`{s2I z`$)(E>rSWBtNXI%-#O`>mL#N-1iGPR20r6J(>C~q&RcynV|CFvqio@|Kr~6EX!oee za!Mp6JRok}OW);X*PRm5HliUkUkMQqS$QYv^<}3imMi@vVh+rXig749plY^(NUKdb zCa7G?uPE5#EqeSCyBReGv;0HJJv&#($U1G>#=k9!M5 z)^q#ZMEP6L20$DBCj4&{cZ&PP69nrkXs)Yc!BM_}W=2M8C||c8K1Pt7mHc)7B40Od zyeS=lT-8+y71}RjoWfD~^6I6FP@*9BYkRHF%+GHxpCv4fX$?(d6+^uL0Paic7~~sx zAA#2^#aUI3DiAz#24jUv`jA&< zZ>>99wnCtmL9zkSv%)oXO_xx$=I$+hIuF!q1rxP0h~7i$KK(%ZCkXz-7ny} zVOpG|U+n18phEkm6fhma+k}afIM9ocY6nge!}Ml4Cm_WW{;WZPLo?x zlvJ-PWobvqCEJxUXkg0wVRUR_^4R2Lvx)J<(PnEBA0KcaQ{i5`*DTfnh}$J04S{N6 z^yui+)Br_$X)lJa4}u<19cN9;aE6g3MYGD zP~H+1)6~$M=ok~!?4mhhE`07HTftsw(`PTAy?fc-Fl{W+jR@arEG$%Sz({*02n39W z)mjyPWE>kG9UYsTm~zIdi#1r+5(i6jI3nifKy`8Pl!X{-Wjrtw#!y((!`~Uis1dq> zByj!BGME;)9@4`#1;U8vomZ)6sw-B+QP36k5qeCvV%EhT}^{>AdN7LA=MIAxhc#KTwjJ+#ibk$h@K{JF_EFD wriQ;C3Pq3^r)t$QH`U?cQ-|ISF#AnFcBp)B)+whP&;F|YA15EdY2^+802GWqhX4Qo literal 0 HcmV?d00001 diff --git a/author/pages/projects.html b/author/pages/projects.html new file mode 100644 index 0000000..77b4a51 --- /dev/null +++ b/author/pages/projects.html @@ -0,0 +1,9 @@ + + Мои проекты
    1. Мои проекты

      Значительная часть моих проектов есть на GitHub или BitBucket вместе с открытым исходным кодом.

      CrossGen

      alt text

      Что использовалось

      1. C++
      2. wxWidgets

      Что реализовано

      1. Графический интерфейс
      2. Автоматическая локализация всего интерфейса на русский и английский языки
      3. Быстрая генерация кроссворда по заданной сетке с использованием эвристики
      4. Автоматический бенчмарк для измеренеия производительноти генерации Подробнее я писал тут

      За подробностями пишите мне на почту


    \ No newline at end of file diff --git a/author/pages/projects.html.gz b/author/pages/projects.html.gz new file mode 100644 index 0000000000000000000000000000000000000000..adf0c7a4cac643a9f64ba499798a5d497bacd118 GIT binary patch literal 1881 zcmV-f2d4NRiwFP!000021GQL7Z`?)_zWZ0SdB{kRNJ=siC-w}zmR5EGg%c#koM(GmPWj{<+?$mY+BO=l%22T-HT{BM?5yQ1|$S$rBSTUXcV*)W+(~! zRB2{9PHuWGK&q&HV=|Y0k@G>v`ON+Frn@GSj2hk*%psvn4NF1fgY^!JVzwCel}uP? z8Kez2f(6Ad#c6T$R@&9s_2Naj2TzB^v+_atL)))7Dl;hsF(+a=R6H|WreozZ3Cz$7kmg>(Q|~q96Z-lxT_NMwm5I6O=iPIYTJRl~P}BER?)Mmrv`>Zb zsF8`cn}{YrG|M2VD3+s-XAAbsny11rl~Myuz?N~xDSj%RLv=qPZ?C*ZZUQ&C1&Uw8 zy3+bQ<8X9w+kd-rr!if16QWf(6`p(AA3(2^%1>kjiujkxUGd)WR_uLZTWtH4ApEHM zV^>C_;LM=7M5g}QS<_pq9@taRu$oQ$u&=7LQ~S#M#(e|WNspGAp%# ziiM_QR1TPFX!roIk=vG^tXW=i3z@BYBMDD3B?q->wwp1PwM z%nLUIh+N?P@_#f`L~bZ~4`M^sa{*wBBT}4}_sa*xe(}6~RGi>I zBj`2gurPymN(VtZ7giJecCi4eG7QGI0@>&U#m@j?zc>Ib`{j?;zK={VF=jMo+RrK+ z+QT{S)Pt40JX2q(f_5S68u?#~#{`XoE2p62@LbudLh*CbAOc(9NSlcHxquJrd{0U< zzF7z*PkRyqkU=!%kU_eU?ucwKtnbvTqgTn)C5Jzngvq2fE{=O>o%YtHn9v2+rU|Vw zJcM+uZ`>ZkhM-21RI86Hbvlb)8S1L(bfw%$sM^0PVGYFvOZwj`f z+2}*rrKub^!EJ8d&%3swizCRyqqEXoZn}B6!;B|Y?60zzCDN>1ae`HDR_#G0egOC^ z4k(85K90JvBFfFUW4K|dUR2Y7!gPLNPX?wO^W7RR=4V8yN}sr7A^Ruu^}o*81u(AxMyR- z`{h4?0muiyaacSlPRUu#kV7_+fbtEvUE{EQ4?#b%x}MJBD}OA0hg${81lLb+_n4P^ z6_O{Q{RHhyP~d%>S`!Dh1O0}kUmz%eiccVb?e!^M-XSJbom~I#l1>24VUt(oKf%R4 zn{yD7SzPDE%R2cOQ344M_ljo(P&`Md7`54s04vS1;!O(HXCi^dIE4 zl8>z_a0zu;r{JQ&=bG%O!_c=K7W zRCYNSP(`+5`bB4Rv$YK`FgL?cLYcM}TkwMU&dSo#^4nLgy34JtML0K#hC3Tj>iF{4 z+Sxw;WDRZr=>$N%^A*;pHgGpdyD8-GI?`thu*IIUyYRxaS>TSxUDHS8|yn6kJDQu9f zO0D)XSp8D-F|3&$PhmMTtE?v#n~N9q{MU1l408mv*s5aFnxDUZX|j8sx4ha{h?myX TYC-kwe>DCFsdp31;Sc}-=4_oe literal 0 HcmV?d00001 diff --git a/category/misc.html b/category/misc.html index 2cbafd2..20c08d2 100644 --- a/category/misc.html +++ b/category/misc.html @@ -1,7 +1,7 @@ Блог 529 - misc
    1. Нахождение суммы k-ых степеней

      Как придумать формулу для суммы \(1^5 + 2^5 + 3^5 + \ldots + n^5\) и есть ли она вообще?


      1. CrossGen v1.0

        Читая хабр, случайно натолкнулся на идею сделать программу, которая по заданной кроссвордной сетке находит способ её заполнить. В этом посте вкратце напишу про моё решение и первую версию приложения.


      2. Ещё одно вычисление выражений

        На хабре когда-то увидел статью про то, что в Яндексе двум сотрудникам дали задачу на написание приложения, для вычисления выражений. Менеджер справился за 4 часа, а программист за два. Я решил попробовать свои силы.


      Page 1 / 1
      1. Моё решение задачи 134

        Краткое условие: назовём порождающим для двух последовательных простых \(p_1 < p_2\) наименьшее натуральное число, что оно закачивается на \(p_1\) и при этом делится на \(p_2\). Необходимо найти сумму порождающих для всех \(p_1 \in \left[ 5; 10^6 \right]\)

        1. Моё решение задачи 134

          Краткое условие: назовём порождающим для двух последовательных простых \(p_1 < p_2\) наименьшее натуральное число, что оно закачивается на \(p_1\) и при этом делится на \(p_2\). Необходимо найти сумму порождающих для всех \(p_1 \in \left[ 5; 10^6 \right]\)

          1. Мои проекты

            Значительная часть моих проектов есть на GitHub или BitBucket вместе с открытым исходным кодом.

            CrossGen

            alt text

            Что использовалось

            1. C++
            2. wxWidgets

            Что реализовано

            1. Графический интерфейс
            2. Автоматическая локализация всего интерфейса на русский и английский языки
            3. Быстрая генерация кроссворда по заданной сетке с использованием эвристики
            4. Автоматический бенчмарк для измеренеия производительноти генерации Подробнее я писал тут

            За подробностями пишите мне на почту


          1. CrossGen v1.0

            Начать, наверное, нужно с того, что реальную практическую значимость я осознал после того, как реализовал 90% того, что есть сейчас. Сейчас мне кажется, что единственное применение данного приложения лишь в том, чтобы создавать кроссворды очень сложной или необычной формы. Зачем это надо обычному человеку я вообще не знаю.

            Собственно, алгоритм генерации изначально был примитивным: простой рекурсивный поиск с отсечением. Скорость генерации более-менее сложных сеток была ужасной (для перцентиля 30% это примерно 40 минут на этой сетке, в общем случае, время генерации непредсказуемо.

            В дальнейшем были выполнены некоторые оптимизации. Первой более-менее значимой стала замена передачи сетки в юникоде (во внутреннем цикле) на передачу сетки в однобайтовой кодировке, таким образом, языки с алфавитом больше ~200 букв пролетают. Впрочем, мне кажется, что им не слишком сильно требуются кроссворды. Такая оптимизация дала ~35% прироста при значимом времени перебора (больше секунды).

            В какой-то момент, мне показалось, что оптимизация структуры данных для хранения сетки тоже могла сильно увеличить производительность, но это будет заметно только на разряженных сетках, которые и так достаточно быстро генерируются. На сложных же плотных сетках, прирост скорости может быть минимальным, вплоть до отрицательного. Таким образом, используются просто двумерный массив.

            Наибольший прирост, как и ожидалось, дало упорядочивание словаря по некоторому критерию. Таким образом, при переборе, “плохие” варианты будут попадаться редко. На это ушло немногим больше дня. В конечном итоге, целевой функцией, которая стала критерием сортировки, стала такая \(\sqrt[n]{\prod_{i=1}^{n}{f\left( a_i \right)}}\) (иначе говоря, среднее геометрическое отлично подошло), где \(n\) — количество букв в слове, \(a_i\) — буквы слова, а \(f \left( x \right)\) есть вероятность появления буквы \(x\). Я отсекаю примерно половину самых “плохих” слов, а из того, что осталось я составляю кроссворд. Производительность, в среднем, увеличилась в ~1000 раз. На тестовых сетках для перцентиля 90% длительность работы около секунды.

            Что реализовано

            • Прозрачная интернационализация (пока только русский и английский языки)
            • Быстрая генерация
            • Экспорт в текстовом формате
            • Простая смена словаря
            • Относительно простое редактирование сеток

            Что может быть реализовано

            • Визуальный редактор сетки
            • Экспорт в HTML, PDF, Markdown
            • Экспорт сетки в файл картинки

            Скриншоты

            • Версия для Xubuntu: alt text
            • Версия для Windows 7: alt text
            1. Ещё одно вычисление выражений

              Задачка кажется не очень сложной, даже, если не знать как её делать (я не знал). Целью является быстрое вычисление чего-то типа 4 * ( 5 + 7 ^ 4). Для это я парсил исходную строку в список токенов, а затем непосредственно вычислял, что получится.

              Я решил, что проще всего будет реализовать (а мне потом и понять) алгоритм, когда после каждого действия будет выполняться некий “хороший” инвариант. Первое что приходит в голову — это то, что истинность выражение после выполнения операции не меняется (TITO соблюдается). То есть выражение 3 + 5 можно заменить на 8 или хотя бы на 4 * 2.

              Непосредственно сама обработка является несколькими проходами, так что в каждом проходе мы избавляемся от операций одного приоритета. 4 + 5 * 3 заменяется на 4 + 15, 7 - 5 * 2^3 заменяется на 7 - 5*8. Таким образом, каждый цикл тривиален, и легко задавать приоритеты операций.

              Если использовать один список как контейнер для токенов и при работе изменять непосредственно его, сохраняя указанные инварианты, то сложность получается \(O\left( N \right)\), где \(N\) — число токенов.

              Времени на непосредственно кодирование ушло часа три-четыре, но в это время не входит продумывание мелких деталей.

              Всё написано на C++11. Исходники лежат на GitHub и BitBucket.

              1. Как я шахматного бота писал

                Лет 5 назад я достаточно активно играл в “живые” шахматы. Потом времени на это стало не хватать и постепенно перешёл на редкие партии в онлайне. Сейчас для игры я использую одно из самых популярных приложений вк. Это проще, чем использовать, к примеру, FICS. Предмет обсуждения появился из-за того, что я как-то раз встретился с соперником, который на все ходы потратил порядка 10 секунд, при этом не допустив значимых ошибок. Тогда я решил написать своего бота, чтобы узнать что с ним будет и столкнусь ли я с какими-нибудь подводными камнями.

                Целью было максимально быстрое написание максимально простого решения. Поэтому от разбора протокола я сразу отказался, тем более у меня не было подобного опыта ранее. Была мысль работать с FICS (у меня есть библиотека для работы с их протоколом), но поскольку я там не играю, то и результаты были бы не так интересны, во всяком случае, для меня. Таким образом, я писал простого кликера для приложения вк.

                Изначально хотелось найти доску и определить положения всех фигур, это было бы достаточно универсально, хотя и привязало бы меня к OpenCV. Тем не менее, решил не усложнять: можно определять только последний ход, а это можно сделать, проверяя цвет только одного пикселя.

                В самом скрипте около 200 строк на python. Очень сильно помогла библиотека chess, которая взяла на себя общение с движком (я использовал stockfish), проверку на допустимые ходы и определение мата. Некоторое время я уделил тому, чтобы сделать бота максимально похожим на человека, чтобы было невозможно выявить, что это бот полностью автоматическими средствами. По пунктам:

                • Клик по полю в случайном месте, с распределением по Гауссу, центр которого не совпадает с центром клетки
                • Случайное время хода, длительность которого распределена по Гауссу, причём средняя длительность хода изменяется, в зависимости от номера текущего хода.
                • Прокладываются дополнительные точки, с распределением по Гауссу, при перемещении курсора от точки к точке.

                По факту, всё это было лишним, бан получить не удалось даже при простом клике из начальной точки в конечную.

                Примеры работы скрипта можно посмотреть тут и тут, анализы двух сыгранных игр лежат тут и тут (оппонент имеет рейтинг около 2100).

                На момент публикации аккаунт вполне жив. Рейтинг достиг некоторого потолка (около 2200), после которого найти игроков примерно равного рейтинга, не являющихся ботами, очень сложно. Сражаться же с ботами сильно сложнее, такую цель я не ставил. Интересно, хоть и ожидаемо, что при наборе рейтинга было достаточно личностей, для которых возможность того, что их нагло обманули, и они играли с ботом была столь неприятна, что они не могли сдерживаться. Например: alt text

                p.s. Уже после создания рабочей версии от одного из оппонентов узнал про lichess.org. Это отличный ресурс на котором кроме, собственно, платформы для игры в шахматы (поддерживается большое количество их вариантов), есть тренировки по дебютам, анализ игр. Самое интересное — ресурс полностью открытый, все исходники есть на github.

                В процессе подготовки данного материала узнал про InternetChessKiller, который делает, фактически, тоже самое, что и мой скрипт, но без привязки к какой-то одной игровой площадке. Исходники старых версий можно найти, например, в этом репозитории.

                p.p.s. Боты на серверах, предназначенных для людей, играющие в игры, которые предназначены для людей очень сильно мешают людям. Тем не менее, проверять, насколько сильно они мешают не нужно!



                1. Мой первый пост

                  Главная причина появления заключается в том, что мне захотелось использовать хоть как-то купленный домен (я купил его только ради почты). Плюс мне бы хотелось проще давать контактные данные, а адрес сайта достаточно простой.

                  Пока я планирую публиковать свои, возможно не лучшие, но рабочие решения для задач из Project Euler (projecteuler.net). На самом деле, решения значительного числа задач уже есть в Сети, но на английском. Хотя, это и не есть большая проблема.



                  1. Моё решение задачи 134

                    Назовём порождающим для двух последовательных простых \(p_1 < p_2\) наименьшее натуральное число, что оно закачивается на \(p_1\) и при этом делится на \(p_2\). Необходимо найти сумму порождающих для всех \(p_1 \in \left[ 5; 10^6 \right]\)

                    Например, если \(p_1 = 19\), то следующее простое \(p_2 = 23\). Тогда порождающим будет число \(1219\), при этом \(1219 \: \vdots \: 23\).

                    Полное условие можно найти тут

                    Несмотря на то, что сложность задачи 45%, для её решения достаточно выписать условие.

                    Пусть \(p_1\) содержит в себе \(k\) цифр, т.е. \(n = r \cdot 10^k + p_1\), где \(r\) — какое-то натуральное число с отрезка \(\left[ 1; p_2-1 \right]\)

                    Давайте посчитаем остатки по модулю \(p_2\): \(n \equiv r \cdot 10^k + p_1 \equiv 0\). Отсюда получим явную формулу для \(r\):

                    $$ r \equiv -p_1 \cdot 10^{-k} \equiv -p_1 \cdot 10^{p_2 -1-k} $$

                    Комментарии:

                    1. Так как \(a^p \equiv a \mod p\), то верно что \(a^{-k} \equiv a^{p -1-k} \mod p\)
                    2. Это всё бессмысленно, если не знать про алгоритм быстрого возведения в степень, который делает асимптотическую сложность возведения в степень логарифмической.

                    У нас есть явная формула для порождающего, и мы знаем как её быстро посчитать. Ниже приведён код на Python с использованием sympy.

                    from sympy import primerange  # для получения простых чисел
                    +        
                    1. Моё решение задачи 134

                      Назовём порождающим для двух последовательных простых \(p_1 < p_2\) наименьшее натуральное число, что оно закачивается на \(p_1\) и при этом делится на \(p_2\). Необходимо найти сумму порождающих для всех \(p_1 \in \left[ 5; 10^6 \right]\)

                      Например, если \(p_1 = 19\), то следующее простое \(p_2 = 23\). Тогда порождающим будет число \(1219\), при этом \(1219 \: \vdots \: 23\).

                      Полное условие можно найти тут

                      Несмотря на то, что сложность задачи 45%, для её решения достаточно выписать условие.

                      Пусть \(p_1\) содержит в себе \(k\) цифр, т.е. \(n = r \cdot 10^k + p_1\), где \(r\) — какое-то натуральное число с отрезка \(\left[ 1; p_2-1 \right]\)

                      Давайте посчитаем остатки по модулю \(p_2\): \(n \equiv r \cdot 10^k + p_1 \equiv 0\). Отсюда получим явную формулу для \(r\):

                      $$ r \equiv -p_1 \cdot 10^{-k} \equiv -p_1 \cdot 10^{p_2 -1-k} $$

                      Комментарии:

                      1. Так как \(a^p \equiv a \mod p\), то верно что \(a^{-k} \equiv a^{p -1-k} \mod p\)
                      2. Это всё бессмысленно, если не знать про алгоритм быстрого возведения в степень, который делает асимптотическую сложность возведения в степень логарифмической.

                      У нас есть явная формула для порождающего, и мы знаем как её быстро посчитать. Ниже приведён код на Python с использованием sympy.

                      from sympy import primerange  # для получения простых чисел
                       
                       # быстрое возведение в степень по модулю
                       def fast_pow(x, y, modulo):
                      diff --git a/posts/moio-reshenie-zadachi-134/index.html.gz b/posts/moio-reshenie-zadachi-134/index.html.gz
                      index 110db5e9ba04b1bca09bcc3ddea3a3e4278fa71f..1c4415c2ee1402019579b20ace8bb8f776d252a8 100644
                      GIT binary patch
                      delta 4013
                      zcmV;e4^r^jAJ`v|85RMEk}W$jN!M|lHk~@v)Xq$MlBxlTkuN-daqit;+`RkiwOgbg
                      zdTwj3aZcCQoi1@h^8PJyWwS-(UjuhZ$F+oLYChBN2{@rU^lkNaRlQx&TBLDqo%*)Z
                      z-PH9lwk)a>U^@cM)svtpgYShg3S4Lvz)L_~&jBk+)Uwq_dFj#6BAvd)1r3{86n1ss
                      zd1AXChJjA+N6t=vQ~QeAOP7pfG&oH1BAKr23Zoqh$Il1fDVZUk99j8Ned69vCmGG|PZxc@4rY6FHOGTej
                      zK+xy3+tduhgnwb5derO)Vfu`Fmg{^(4Y(Z#
                      zf#+&UrJ5B4;Gq^~0u%QZ+Q%O^Q8-6;X;)00b3_$o-gV
                      z8(YR4r~5{m*@Fy?$?}*_fI(7CR66f+$fa8A*DN9yrz8@N-y@a}oQ9nFy%vi?8)USB
                      zyjmcCZO(QDzvvSr=74F@(6ggI-#=zypf;C^W>&HOWwo75`D;s;{}}U#H8tifO3cW9cnbp
                      zAgi%VEgi4g&JJ;GC@LIep&Yzg)>z8rs&H(7+P1iss1vVs(YI{2n?z5)$5|A_r$eeM
                      z=xlUY<4x&9x!3}m_m^4?C!yd#nbQMc-*M3$oEFJC9C!pA2C?TdrcSYAVTI0Njk9~8
                      zKyoW`L5$%6ftvkz^aN`3SEFZ8vJatTr>X&rQh@l%w{|kPBUd7aMI9qcOw`#pM1{%P)qnfY^)CbL6)Hfp{X|!0J(921*2BU}psQpzT08zJbOAxF5bAJsEv`
                      z3ba-mJUzkr+3+PnCP6cY*wD;`Po)xk9VfMxOiH*mjjCZrZlZ9h<3^XUF!eGpp5u2}
                      z;!_#7U1PfxLV~mhWQ}5y@{Je`9BP<<3QJ363ivRWbLxPJP{+Or%0=EMnL9q$Hx>@=y-V=xS$ctQ242-EiKkp^!lQ{
                      zym+^MW%bhH>f++U;xfEyB#7F0t{l7UV*fIFOqLf3xBz<6^Wn?UqtP>hXv?{OGLiNX
                      zTu=BL@C{{}IZWqRQGJK%A6d55={q_!$Yxw#+Kg>`7T?A!P;VXIU0?LuBDe+!z~J?K
                      zBFHnFxI^)_fY^dsms4`wULR$cpf&st;N=U5!B?YChi^!OdadC%GJFn)|0|jNWc1I#
                      z^_zwXTLf0V8a>CiSEHw+-xGO%_A%s!eOLk{aQ+E=mT779u{?mNFk8vXh6t>bORVBr
                      zYhymxs*{Uuc#Q;GOB+=vS#SnOL8?K*sJ78FslI)=2&kR{(rofWO-eQnYw#K4A5tXl
                      zDP6x-x<>ZE5Kn-c=MqyXI~gwGBy~VW|AKfyM<6Lk2n3HuG#1Aopy_>ofPXpqJ-mJ{
                      zB|B6?ehG*H|Krh9SbH;iN{TFix{Q_o3PjyMN|_suPc~fI4cE!#YoxyTn-%3|8{Fyj
                      z!_AZ_m2zSykW!+$M~`X*UQwL~Vt*w8ZFtNyhrc`0GnKRwwOQ3PUzl$;OV&LV=&M{H2QfPr&e1;)G8X
                      z6X0et%HK$yzs_4Z*Ek92oZ`Yrv9udL4RHZ(^31g#}~{fVkRsjbj9fE@N7CH{w^
                      zq^=*cA!*CVdzMQ%R-En^*E9oDV46jBXgDFsd(HMcxlt<-d&gca<
                      zB<15n3@{u@OFjaYA*z5BuI&$BmO0FJ2KWyE@;h|d(GvqWChb7YJTVD~{T_%!PXWn6Ujf
                      z*^(*O+K+Rwq=~J6;XVe**p9DdCPQA)FCj#M&rgoeTdQRX-H;EU3bdN+EM~*`Gnp(u
                      zNdp>)Kb0x@4S{M6Z6&4*GWwki^*55ar-_RmW0ci7*&XHfFI<@82_L%TDPi)VzP(qn
                      zgK0>w!~Wcb3k?%+VmlUV`mdNN;#!3I#8i2(s|R0)NV56&X%KeYER^0>$(CQ^h+C6g>BOr|xo(xJLffVB2y
                      zQqyI70QV3eJeI<5G3KjlN<@NdT0Vf{-Zwv{Qp3Ow(>
                      zRdRVOO(Kb@fWiB)T)<#t#W{VtV(z1YYOZAjZUN!q%3=w1Hc-W
                      z^#dg^G>%_OeGWfY#b|91_MsO=o-zHYaDS${OduwkV63|Z&k)4G3kK4Ecm%hd@)8Xe
                      zSC&km_aP^`m=~eb4mfS)qNKy%t{!f1sg_^g_O(`*GcU>KxlP|s2^Q=ksN>;->tbN7
                      z6>zwJpWv3?qsfW6U
                      zgsMc#j@DW%VR06J4hxv%G>o`kO0|Ak`7wSM0iH1{PPH#50>ogrd`zmFt`ddC34QZNWgsgh5DR4hm&&|(?9ONDKG-{Yv)L(E
                      zrO%QV2%s+GWzpjlbGZvUeyKmr>=)7rsec+D6tm_b{rGm|%=$E7(sp{MiO3n10U#pe
                      zXQ{vS5+JAK{ARUS<8h{ZEgyZxH?NR?1YhA3i}-2Wx6m#>y9#(_$~Y>|l)2dE%qecE
                      z__nds!Oz^@Gj|N9>A%bK|545H55tzH$UG;vWhSlsqo}1idu#Xu3CdF>rtPmHP6frInSH<(2xCdi`oT&841(
                      z##3o(;!O@S-m`WrwTkz%={4`tU+Fh)-_dX1{`uBV
                      z@8147%Q`b;l2)&;-T+
                      zz50wYg92+67KM0?^5{2z@7yU8C@%>paOs}34M2OIJHC)OsUMB6{)sWKL`$|K0@oVc
                      zaGjnHB6Pq%DX)~CdmmKdhj4I_dIhIMpY0~(R|!rrPM?VxN9|4R;h*DUibE_QCJ4F#
                      zfAb&+zE>-o1PoCK7jrlUyl?@a-~~YnAp*`iRES%mV+B-{@vBaMQXIwyxux-@&g>QN
                      zR7q`FDyo_}#_fs`d;iwEN{kvwR*2!T+?A8N@)3Q9xePt9?OL5}a*n94Uo1bYfICie
                      zo9AY)dW~o*gy++Yg(J7*x4$I?X;Hj0xNG%3usk|n!C9+Hb$xNOYTyj1Z{O@Yu05Yi
                      z1(4?U=JM0M(?eT-@mN;bFda8bb}SrA%?)$m4=9eA*IV9r#NlG%FD=(&U*AfFC3n=D`YdJc&n-m>Wsh
                      zpB|OZNO~QA*0&ODS}SoF5{!p@-&LnoM5To1awDcwh|~FW5J+!xoYgMIo@+H-)?>Ot
                      zqO}y=wDGjC>rDN0A}G`t@WjOM#JDp{$DMOnk|ws16%0Ldt7qMBuCG_N1PyO=IxK>`
                      zU8{U}Ltj~1T&!PSzM|Kmbi;ngA-%6zJz0z@o11Ze(oWspu7%Zyh_TnSCmcMi)&wjT
                      zx=4uLp>XxkeVg+YHLOx;HeIHE8)8733K`Uy>)_c!xRuq4oI|Ko7b@}Z8Fb6H+yUrE
                      z8N6qW{aP4-#ewJta0g>JzMwpOhr*o$o$u8|buV@IS{jGojngILs9%@Jp9K~Djzs-<
                      Tq+!Yo-&X!VEUlVtU<(fjYG@t4B1f0+v`nGzzs@|?>ZPGlqPJP?y
                      zZtD6NTNc#`upNQs>PgU)!S})#1unD;;3c50=YSO@YTD|fy!2>j602`=LBp07g`B=fApu}{_yMJ!Em1pzZkw4em;CL`s486|Ng77d}*#}D3}RWd=pS>
                      zHWe0kg3w`ph5@bk@Qy=w1IEM5$z8_|`z@R9I2P6AMFv)X!n=;YO*nO1ng|Cj6@5wp
                      zL7&rZORLun_!su6M-58|!)M$xUFRcOhpQ|T5{ZPVpbA$FqYE5}dXKT5OU=L$b&Gk3
                      z<9gTh9Cy%K>pLzJEa+2yQA8cIi3^JMYu11}uIpG8$y8;`RE30tfVL_jeGnq1%D1Bb
                      z9^;XhQ2w@mG><3u3$bgu_IE7Phn>g|qlMedXWucUwYv*tom^geo7{lYo*Mr
                      z8(YR0r~77y*@Fy?$?}*_fI(7CR66f+$fa8Q*DN9?rz8@N-y^0EoQ9nFy*7(N8)USB
                      zyjmcC9nN+I<#nb=n2&5uSU)2no^|kTr@)%CE<0;84?lP*~b3Q^1G0oKpu(ggW+3P%iR5$=vY)*Ad}#
                      z2UVa3lZTE4F&Mk51cr``4+{Ju?N&j?_`Ezi9UoIrq2uLg;DSalL*b{EwzSw-(Ho2U
                      z^5WgbmDNj&tBZ>Zi_7q;ks#{expM5Xi~Y;!F<}jUOMfDx3e`MOG)pvAgkd3&!bQs(AOumg-pwT|QyT0gmL~sodfWaI2
                      zM384Tafjk<0kH+OE~n(Uy*|n?L3{Wgz{?j9gRe%P4&RU__1eR4WcVBo|5q~k$>^Vf
                      z>o-jUwg{|zHF}P3uSQQtzbEp4>|@9c`>+H^;QSN#EYs5HV|f5kVYZT&O%a$WmsrKM
                      z_Qrg$)gTw$@EQrWmNu$TvfvDmf>eWqQEj7VQhob!5l}q^q}k+$nv`rD*5EV7Kcq<9
                      zQ@VbwbdBtRA)Wv?&n2c(b~0SVN$P-%{sr-ZjzCh75C|TRXe>^hfTs6<0siIa_wf3;
                      zlM~aTD-d=6C}nOqKG|?-H(V!|uaU;$Z&s9>ZE&a8
                      z4>wb$RLY5+KuU?~9zCiNctv#{l+$RD#@i_(&^qco@dU6B@+=LO+Fw+IDGb?IB^x_73k814@|P;^KLNv6i4#6m
                      zOn{roD1Re){yJ~vT;n95bBYTi#nN8)X^0DOBk#2!CunWy>rYhmNo|F;0pzgvDDgiO
                      zC3XFn4M|%@-m_fFA(t+{RZE>|eWOz0D7)*hGipB_hraUSyb4D+?
                      zAt@gpVu0aLTJjOF3{eH7aBYA1vdm$&Gr)fUkl&%pj-J$kgJJ+5{EL$f3v7wuuuT?7
                      zmIcrT`dSG!KBji@{MDt#(lvq^1^$E8b(L(6OG_XSQ5FNazCiF|T5;4iWG>Vj$As;_
                      z$(BsH)_$CeB~5I94fiof#&&!yGa2%VehDE8e139#-dZhF=!Sd%RiM>mXE7VjpUGtT
                      zNgB{V{HaXIZwORtXe%*gkkRjCsK1fSJxyHn7^AGt$?hn(f8oL$Px#O!PYII`_3gcq
                      z9ZW-d1NP@GTxc4A6Wg&^(|^TG5!WKrC#K4SRkh9V;U=_ySCF&7DPrF!=Gy#CkPtV?
                      z2HZ1}U^0h-GB6S_tGSi(Arj_rY0Y{fGAcMIINK#6*fPsbrGHgvqpqRytJo36R#l
                      zOlrDp58xgGgvV0&jXVKq8(b9?@>+RmL3%wAWn~t1@27kS9RAH1JFI_Mk8Nd0uL95e
                      zZGx=IB7ekcXzlY^8^uX5^_P6B92XC8%QTAR+gz!n$L$v|lMSK$0ymb6
                      z6K*_RMo!9LPM=!arrly)cEL)f2)6>Zo1o6_2U>f+XdP_upyYh5%xHsI0U*6bE-Qhm
                      zuAWd8>ZUEP4ySt@llcv%wOg&i9naC)izO_7&ca~r~%CLBzHQnj*L#N$%ahk^T59RUmUuGqPQz+J3289lV#8k6nna%lC!l)0D`hrw}uL
                      zCdQ7|#wWltX2q%Y)Jft7rj+|Ma229#c?=%rPqcQ+Q
                      zg#0Y^w_XC|l$_tJ7Hd4tl&|HZ&-mtl6_Vg9d}0wljr$hb&tLfQ`AW4)9?GeK9g~xP+)>gZDNc)1Go&%v`HDJFsa}(iIjFj01K=@4i{MZ;
                      zgq)DB@T}k#9yJWh_UrMMe3Tr2HeBFVgvM>S{26TB6W1-~cb#7AF8!5$_U)f<
                      z{q*kbpEC}hifF9Q?>fHCcIzyFTP1RxXpZkwjxZWoCDI65b(6Hxkqa$oXFR?7(6?z9!p&9`2)!T4Imr(quS2;&>}C`)b-79qUxnFO8gKGE>f@Hl<2eFg#0SODaPqDG2^JcsXhF2d`xkO1;hkF
                      zH{fp`1i|-eWs`s*3gKc7$AA|u02I6+NFhYPnMH-TB`haq84y{p8ikz|F`J(jz2a#ud0x0uV&13Rv1ZIg3Eef?tkVFlcA
                      zn%g`#d(~@1Qz1N`W-J`JCBOYGDM*XroxxqR_kror`3lZjRjTWYo7Fnbkoxw`zT?{S
                      zxl{mYZf`C>-8(&hv=xtKl?~Hzqh!a#vDDl!7yf|am`Sd`#=}?1ccjl(Cui6!NPs=Y
                      z2g%ThuBJ}Z_+)O#G@Up(is0WQv4bfxq1ihbg<2t`{Pr*bkr$1Yjg)c@
                      z+o;*2?2-MB(PEx-4Q*ly6N2)7B(_3e$F#Mij%O#uOKNg|N*C*Dj0Lg_5AmllSiF+q
                      z_PF>+@9jpu^rHEsDCdxf`zI;Mc&@yd%3V_od@P`tFRtb2;BH!6D`a7s^92ZXwJ68G
                      zDU=RbUh;V6Pa1Y72vLmWf)E8(t7D>j)%o~pVhrDB@nt*=PkpoFQt~s<$(`7Mj9_jg
                      zVSjp5J|pRWby(j@uxahYVMs6@@_kpGRuPpFp39AxP9aX`(?KA;!*N!-7<;bObXkw-
                      z3W?TMbkoMu#I7^-(}|!^W55#=!xQ7qEFE{wVM&_UW>zrt%&nezzqP(z*%CCoVOcDK
                      zyj`n&ctc-VT3l>gUcRC?pmf82$RWM2nLSyIDw~^sanerR-mZn!hlsJ)vL_rotkwi9
                      z7P?4?-l1^y(0yC;6*a6WmY6*-4csV-FF-!tf@Z@L4}
                      zk1}}A9Q(DX2POxiAHW?<-SGwG;X4%W9O!(nCaQa>yVue<1aF)!8AtuPME)$O=yxRQ
                      V$0JP+L;kk%{{c_aS!ZiG0078j;Qasq
                      
                      diff --git a/posts/moio-reshenie-zadachi-146/index.html b/posts/moio-reshenie-zadachi-146/index.html
                      index 031f4d6..5191fd2 100644
                      --- a/posts/moio-reshenie-zadachi-146/index.html
                      +++ b/posts/moio-reshenie-zadachi-146/index.html
                      @@ -1,7 +1,7 @@
                       
                        Моё решение задачи 146
                      1. Моё решение задачи 146

                        Необходимо найти сумму всех натуральных \(n\), что \(n^2+1\), \(n^2+3\), \(n^2+7\), \(n^2+9\), \(n^2+13\), и \(n^2+27\) будут последовательными простыми числами.

                        Полное условие можно найти тут

                        Хочется отметить, что сложность у задачи 50%, а на текущий момент её решило меньше 4000 человек. Тем не менее, мне она показалось простой. Простейшее решение отработало очень быстро.

                        Для начала, можно отметить, что в лоб проверять условие очень долго. Проверять на простоту числа порядка \(10^{15}\) достаточно сложно, поэтому их нужно как-то отсеять.

                        Самое простое — не рассматривать те \(n\), что хотя бы одно из \(n^2+1\), \(n^2+3\), \(n^2+7\), \(n^2+9\), \(n^2+13\), и \(n^2+27\) будет заведомо делиться на какое-то маленькое простое число. Это даёт достаточно хорошие результаты: из 150 миллионов чисел, после отсеивания по простым числам \(< 3000\) (этот параметр я подбирал уже после решения задач: если он слишком маленький, то будет слишком много проверок на простоту, если же слишком большой, то мы делаем слишком много работы, чтобы отсеять несколько чисел), останется меньше \(2000\) чисел. Их уже можно проверить непосредственно.

                        Тогда алгоритм может быть таким:

                        1. Находим простые числа меньше \(3000\).
                        2. Для каждого из них находим допустимые остатки.
                        3. Для каждого из чисел от \(1\) до \(n\) проверяем, что остатки по всем простым хорошие.
                        4. Непосредственно проверяем условие. Важно не забыть проверить непростоту оставшихся нечётных чисел из диапазона \(n^2 + 1 \ldots n^2 + 27\) там могут быть (и будут!) другие простые числа.

                        Непосредственно сам поиск такой клики можно реализовать тривиально. Ниже мой код на C++11 с использованием библиотек Flint и primesieve. Распараллеливание хоть и просится, но смысла не имеет, т.к. я получил ответ менее, чем за 5 секунд.

                        /*
                        +        
                        1. Моё решение задачи 146

                          Необходимо найти сумму всех натуральных \(n\), что \(n^2+1\), \(n^2+3\), \(n^2+7\), \(n^2+9\), \(n^2+13\), и \(n^2+27\) будут последовательными простыми числами.

                          Полное условие можно найти тут

                          Хочется отметить, что сложность у задачи 50%, а на текущий момент её решило меньше 4000 человек. Тем не менее, мне она показалось простой. Простейшее решение отработало очень быстро.

                          Для начала, можно отметить, что в лоб проверять условие очень долго. Проверять на простоту числа порядка \(10^{15}\) достаточно сложно, поэтому их нужно как-то отсеять.

                          Самое простое — не рассматривать те \(n\), что хотя бы одно из \(n^2+1\), \(n^2+3\), \(n^2+7\), \(n^2+9\), \(n^2+13\), и \(n^2+27\) будет заведомо делиться на какое-то маленькое простое число. Это даёт достаточно хорошие результаты: из 150 миллионов чисел, после отсеивания по простым числам \(< 3000\) (этот параметр я подбирал уже после решения задач: если он слишком маленький, то будет слишком много проверок на простоту, если же слишком большой, то мы делаем слишком много работы, чтобы отсеять несколько чисел), останется меньше \(2000\) чисел. Их уже можно проверить непосредственно.

                          Тогда алгоритм может быть таким:

                          1. Находим простые числа меньше \(3000\).
                          2. Для каждого из них находим допустимые остатки.
                          3. Для каждого из чисел от \(1\) до \(n\) проверяем, что остатки по всем простым хорошие.
                          4. Непосредственно проверяем условие. Важно не забыть проверить непростоту оставшихся нечётных чисел из диапазона \(n^2 + 1 \ldots n^2 + 27\) там могут быть (и будут!) другие простые числа.

                          Непосредственно сам поиск такой клики можно реализовать тривиально. Ниже мой код на C++11 с использованием библиотек Flint и primesieve. Распараллеливание хоть и просится, но смысла не имеет, т.к. я получил ответ менее, чем за 5 секунд.

                          /*
                            * Problem 146 on Project Euler
                            * Aleksey Lobanov (c) 2016
                            */
                          diff --git a/posts/moio-reshenie-zadachi-146/index.html.gz b/posts/moio-reshenie-zadachi-146/index.html.gz
                          index 58fd4c4361bc78e66acf42b8d840bd56c711976d..66e4cd725f8836549ebe7a64abcf648cf6e3b698 100644
                          GIT binary patch
                          delta 4408
                          zcmV-85y$SYDXuB7paXw*fqctGbFgY8Y;a%^&>7f15>j;l9TO{54%a+(3j|0mc5Gmy
                          zyGUFU6
                          z9?U;=Ul1e`B(sYJO)7XQl;H1vP^-zHg!hI)Rf-+ECvYj_N`o;GSQ#kKavH2>Qz5gx
                          z#?~pg1gUS3YZQZ&Q}Dq+r%F*lsi{Z-AC5$f+GSkiv2KEN5w%HX_dD1Y7sC})j2LuJ
                          zSO)l@Z>n-IRAhhNMvPqq)hh7l_m^FV{bOj9u-Z`^ctax?q3}~xTPl@L=gX!1Qu#*t
                          z%<{?7a;dafIsv~m;&$rTFB!V5V*kANh%A)}m;hSR^X`kiulAl11e;7%5pj>8dcfX*
                          zZb;M2VtEfUs$AremX(JBx#*{tI%Bunx_29+K)HW5zPdi{)VX^W0D!{F(LfL-
                          zwr39U%^Z9Sa$Q8oetA7gF>bB^&yn
                          zSPy}ZuVphx`7yBNN1(l@aJ#}?J)i(Hv{w6a!TB-^IS3kRIkNWzJu{)-@0J$Jp}vWo
                          zPE6A2%p`xEKANOcIgAhFk=SvmkCT8nA9r7afF6+wZP&W*FkV9d-2w^kLJ$S%!DnA`
                          zAl>as5xV)&5F@*~t84?UM2_CXdnyH@;{FVv-ul5GP(746<)tz(P-6G5*cMi0BxiF-
                          z+I~!?m{kf66?g;YknJj%qgIm|exw4QkMe(jx+i~N0*`>k=a_^Z0j4bk4!52K3ifG{
                          z1W0b45j3BW)ss`D_d%SSk~|`%@dmK{5vcz`QNM%U0`dd!f&XkHSmHN5Lx&D=}SWzq8H$W58^;S~)ETjTx{Got>rFXprVniR_
                          z8ghSUkb`uE7g8ddib^Rdq*G}TOya4O1%T`8@ZZ4*o-2QPA_s2fBFamWaQ7vV48Q1Q
                          zP~aRQ-g95pQDX=wA=3Qbc3%MrK4+1EzF7JaKocN+`;#KW-T(w-$@((mq`lS!EKaD`@hxYovY7j<{ZxCs$S$%&k
                          zE5BVCER>^mzXv)Y)T*9)PnVT~%BM<50EQGGRE7j_h8{+s-nU8_wn@+6l&PTKBUA5?
                          zo=D6l;b0vv$K$p*OHM%8>Wgwg**-G$4v73pS}{i1uZWKZn0*0&WxgfSFSf$ug#!|f
                          z2qNt=#!u|CEu)@tyKU%-;@%n500e*E98ps4D|dJZO6pa>x{4qeO5@{4E<^&7JqYgw
                          zh9nuycl+pf(4mwOZOT}lOhrHP?mg|frtgs9AR%2JF5f70_&22NY_310`mvwj!kH#k
                          znM)Bp_ThoK{s+Xco~A+(JuEZnAAUr`6eSfZZT7XK<)zf=z^LmNfdsHL*M_a
                          z3=pq+F;ZHqUrmOHz&`IVhhf%3OXzL|QNQQ!Z)71f0gk>(q&+00tZ1?tmjDKGF4|{5
                          zF-K_hLxilG2j#ot>n0Mh!c2dCJIW$rXc)-*V1oZD<>6O>{O|
                          z4g`Mk5=q|sx)x()wjZd3I&xnx_8!2IrdF!ALUU88{MFIWr(dFQQ62XFg%4TbDoi4!3G9w
                          zs~DLhJ$dY4eXD|nG`4?j88aXlVN5SzS>DTKZ$UjzF!QSV_N9tgp*mgGt2@$O$thn`
                          z57iU_y1e%5JzNs;t*2!*TQ>ZMxo*YvXf0w|1~Vxxc2RBMep{;*Kk)6!|8r#Gk>mqh
                          zmBZN*f!Pv)sdr?NZU(UDZF-y24e}|g>keBZ3r1EhWK0jTIO%`TRG?k0cFb}NyJOOx
                          za}IQ9Xf>>MEC#WJ>h0rAakfXvAf&07o0x(%&=&7#4AyepgQxYjR+Eq1
                          zV(ElNeA5AL8S#INI9d$?LL9w7?%8QnJTpBFtPN(RC>6z!tLu!}@dSaQExszXoIun<
                          z+Xa@g&p7Y=NzKX!bJB#xVORu{RwcQ_
                          z3gblT5oc15_$c*=a(c3slIVJ{pZO@+pe9&Wx^n)D)vM{0FNI^LiOF)rsZ#18rPAES
                          z%s3sJS;p5syL{zhdO4q%ot>Y_Y+61)U5$UP1I+R9Q~w!l0&UC73DrcCI@Hs}7}}Dm
                          zmqFc67EH!0mQEn6>`%cwMh_$hwCX&<=$ed~s~*J~z@#1@yWH?|m@SN|v6pA?zPS`b
                          zan{7CIM7HlvA(CB8#U5Bu$~};0LkfdM=9;<*$6D7oO+bOC3@xJVnS@|6R{sF6k~sN
                          zpR__@Ih=YTW$+)t%RIyLPr<3`I;X1#=vfC8Op&caeP|b_+sR}-S4$4bVMvPaPZJpS
                          z*8!${fbx$hd;n4Su-texnWyF1qS`bfna7%H`ph$8(R75_EshgU+83WDiWtK_Hr~m|
                          zyi_yS+5x7Ioc?@Dhsh>I^L~`G|4V-kDMUXV>r*}yoZhZRJQ&PQ|EB94SK^1G+}PI?
                          zjD)rNnUd^2(8)XPgQqk7dpYuJW#pgEe|Giq)n88ir7isVfI!+Nysg_dfmY~Ir}Fil
                          z8KJ5-fo_&@Bd-(qt56^-_+F4q2E=lRT%1Vvick`=dPfj^G)fTxbLNoY{aDXITFnVXh{eWx95ms+6m0QjGy}TxI}&JYfy|#x+V+a^U%`tFA+}h1*;LoQEsMn{Db%F^p*Sw
                          z=I7~a;r&7P-|OZ!7R{e^#Hf-gv8>{~EdT(5BS@7*zWkpK*66j5aYKJ0RoeUT+RW^d
                          z`Hb?8Enrf;Jfm<%*!^J$XY?Dgb6M;eXW>P;yHL@z)@nzN$bF*z)Z4*mIoLnz^qJEq
                          zPMlaeQwlcGQX3Zeo5-sT>gCx3xAZk#-NndE7LJVsX#s1BLzSvfK?
                          zs$iKga17G8amX8v9N;dtFZT@WS}Yo-Q}CM#%xf0?&qW)k<)U~6E`JS8xA-}OISs2>
                          zy+OaopTBZFf91-jtG~K&(}ELigE%1T)HK71Ebq*yMG~J
                          zQm50u`e(-42~sjG?%MjsdE06_z=8qxNxe*Bzsn#JM?l9CZO8QDEw`Js1VQa7gS3*JB3d{317W
                          zm+~ZfRZog%=K$YQc|(03#L$!pbeYJiIwAy{GX>xJS3gl~y`e$GX3ZdeYwaUNNCX$5SLCd#~ep
                          zM`Jc#|4)A#@ZJ`l&zA?coHrl_`MCBwJ7hV62;Jr5*>e~hw%1)25U=`&;|}m0B5|@;j043
                          z(M_$Fx5EdzB;?`%FXmGp3Pcr8;66&2w0dXI_(?}vZKLBz>sja};|LIbXOdKm{gRWY
                          zY}NUOgNYO4#MuZQYz>lXhAa+Kz6dU^Zpu?yD5MOTR-$kgCUv(7ToXMw#x;S|Y#-@^
                          z?1F!PHE>#v!~9GC%o^(GFbgHW2AN#<703w2M0~$YW73U2(tAdR6`T6|mrBbPU>cp9R8B#X1
                          z3lGBjHN7d5P-bPt57vR%n>mraj}V(xbHKnwHpk&+tceJ;4h5@;=38CJsPhRj)vC?Z
                          z5l#gNPl7>yIR}=_xt&?g$Rmd`*~N^1>`-2JbbABjqZHoM`*zI>uI>TSt5E0{)VnZv
                          yAJYc&=t48cvkwAu&jo%6);OFhMjZkrPw$F5?n#~TR4K|M5dRO(5sZTpaR30-mvO`Z
                          
                          delta 4409
                          zcmV-95ytMWDX%H8paXw5SOaVo&B3aXu)%>vKxbh4NJ!NIbWE&JIb8GDEf65N*s+0)
                          z?lys({c!IQ7N}PlyH@M|
                          z8<4!&eF?}m_nsrY6>!9f2D^Hb@}jF);03IV03MVb$j3VhfRI9+F-(Pke_K%@a!fHox;0=vngu+i%ZK+f~oiCU2OXVBo
                          zGs`DS%cas{=>+`Nh})@SzhvmLiv9E6BeGN`U;=1K&$}=7zS?_65NtA4MZ`UV>H&KL
                          zx*<(7i{(AcsE$SR_jFS?T2>wkWtlP>)vgQ0_A_&`0Dz&Q|Ink000UvM*~5W
                          z*q%AWH*@eU$aN7R`{ng0#kjTZw?Nh|$m?tP{Tj&I>FyHr^6n4dM%x79%wxE>v-g;Q
                          zV?6{uzLw1(<;TF5AA$Cs!tDxo^?(A*&|2-w1?S5w^vr~Qzgt=?hx#UV
                          zIx$J7Gn0RG`e>3)wM`FjNK28GSeB6Bv0(wL$v|a1I!*~q=bPFWB3qcg52cLb(
                          zfpoVkMd;>7LyYX|uCfiZ5;=Mk@2M1siu*Hwdg}*&K=n}Ol$XlDK#ASIVp~|1k(|vT
                          zY5OsmVpb_QRNxJmL$<46j#^D>_>l^HKFa?A>Yjgq2|NNCpJNhw1emrEINW*`DA=b(
                          z5+J#GM$mjhR!>fq-Uo4RO7e)5#v8!)N1*-(Mg0zX3&;<^2mZ5-V2R)K3>}J`ER{+G
                          zY4W)TI0e%E4*u>S>@B}H{NKvqXL)N^VnwZV-vCWW*IP;Hvycj)@rMEimfrOih!K5w
                          zYsi0{K@QRtUPy^-Dk`OK
                          zL4k9Kc+Y)VM~xw%gh=yy+kFKj_?$%s`eNxz08N1O?N5pfdjlL0T)Z!oOTW8cKJ_5v
                          z46l3DiUj#Yauzm`oPzr=Qsy$yY|9`6KIDIk0k!ldkL|uNkur=$lJ34Z|6BS9Iz&W|
                          zTjcn$50}bIXO&5yuAt>1blsE+*;X!zqI-mu)P!*iLnbC0boZx3hEGZDcK7@LH!%)v
                          zQ+f7FKf1~M@me~hv{@A@q-9ApqCWDM2h|ps9@^{wszDe*zCon1X7zuy
                          zto(LmuuzWL{T}FqP^)_GJzZ7`DxWGL0T@z%P#F@y8G0CjdfzH#*d{%LQ>KD`k4(Ko
                          zdLl8KgoAaw9FN=LEI9#Tt1rq0W&6m~J0S8aX~h_2zal;wVD<$7mid-Qzt{?s7Y;}`
                          zB8arh7(cPkwv2kp?Y5ySihE~J0}y|Fb3{qGuiW7wD5+Ng>neg^D2c@V93ul^G
                          zWiCbZ*oOz^`X3O(dYTGF^svmNfA|p%Q^ri~s
                          z3Xl>CqLChn*(Lxk*+TX1EGsw+m*ZhV0L9;CzwnFN@>V49kCjBkq6=!OBvJS&4t@Wx
                          zGC;iQ#Ykzbel-~)0{gtf9EMpBEup&=ME#z>zmbK|1UULCk@k>~vZBdqTml%#xoDsL
                          z#2lf~4-v9%9+dBnubW833NwH8?I??gpt1}{0trA|_U8g&xl3K6ayK!&0TrtLO3E^1k(9}ow#fu1>N1>mBx>K*
                          zU&#tPU}*sb9#q~(vw#$2^B9a_JCa)Z7S*@#p5TkpHQaI1he47G49$NC;SKS9Y!~a-
                          zH!`J2{r5dz!r7E9-}fc~vf}UyknR3z4yf*1xDG;x1PT730_=sw#c~-aAQJOCKc4w8
                          zRY|Ji>NfnBxlPsA8O)@(*oCWak^60}R{X%XEC0`tiARzT
                          za8(XxO9W<11g74RMYtgbt3jVu^hxsWkE$l`ybLsNlvwc0VuG3<^>
                          zd(Jt~p`q2V+OZhK5~{b4H^tc=C4-QrVs2sz)<7@JJ3Rab7bf`L;Ss>;AtJX}TX!t?
                          z@CeZDCi5)Onu`VQ1BrJ!Oq^}B-FtWM7Fz1+5CkRh>L{oAk+EN7hB8>obq}7_+geRN
                          za*L%C8u3jBxMhFDGva792nccX0=Z|WQSr?5G_W?9m7-J>L$0nfX2%l*injQw)N%q*
                          z3vu@mDDZLmr9kTc1dfPpl;BSJh>ZW;M$q=N|2)HMc
                          z=}4>T9l?J_GMCJu4WkqJTTW8aL{gbH6r>HL7_kzxH%)nzY}0_~gRvuqXj@DY;uLn3
                          zRLPI^y?hp{sg*EuDLTjeQ@0%5+gRmP
                          z_l#D`Bs7&K>$GV(iK@&^Won625ywoA$vW_qH%UZHV$tpJ)@ofhZl~0pHS0A0@3n9o
                          ztBHSuE*}3;B<@#{s9wmOznT9XP1*aa$-^^t{HjyBoIK;a^CvYcAIwP;7KdRGOj?!X
                          z5-W@osYjeiJ>sL(Bg*N?T1ukp!G7kWWP_SuS?S98FIKOnQ@#|AohByB5vNM2hm=Zl
                          z8#Ci{Y-Sl>`|R?Si|OTjVs>_ZCbMbz{B(acx(+bM$4~udvWWP!TaV?
                          z48>U!r{X{(&BXeic5c*2_rQ9B3<4yl&mE<-t7jvyjB@Hx2AAlSi;D@dtxv>$tWbZ9
                          z)qTzCTT1
                          z*k1>j@&U>}qVNGk;lpy{)nuNQXNzjnh-4mXs_8S&h(*&8X16#_JZWEinkZrn``CCV
                          zBlA+tTx$oIK63i=DIF%86wUil&i;QdIiwK%bgWPLP;h#?8u4H-JN=ukb6klZj&fsP
                          zQ!oSs!_`#>k}v=5%n^zY@!ua%L1I{(?#%U6Fn^_RBr=K}(1oA9=7+XPynN1e*o
                          zduD{H-UPZ?#*MsA;IBe~tl)b=G8qudA#!md-77*#$m$(I@X;tm1kABF;1_=dcGUOa
                          z%coA3OW0B_=5_4t)TAX41bA-8$c=w}x;0C)tmAf^?6OIFU_bB}M
                          zW%jDwI?$!N(Jw>G=lxhpqujHI2_qG542#z3C68Z9fI#{FEKE{6yg;Z(p!)r6M
                          zOXf4mJGOvH_416u8DaN_A)L`~$j)W4XPku>VNb0LHK
                          zW8Kp4s?Mvf+BbUj*!zFKIQHHzj%Bi0a$j!pyQX_2(iI#efN4MlAgB*^A)`8EvS;PU
                          z$f$y4!oV>|VTUv=t*3liPJeT^*kJK!%x$1=H@xq{dc9*~z=$qn@cQkThn0(hvyE#`0>
                          z1hmTo3}8qOFZf2g&TOu(9d^<4m=|1q4)uQntkYB&2))yh#~NH!-|a)__@quR&$VE|rzMxH@{xeSCJyheWV7p`BAV<^fA2yp3^)D4Vox9$Fg
                          zgh`!F|LUI^YbQv_w76^Q8|Q7S=>Q7`*eCTeiTy5vNE`tjOSB!+i?`T%5B)O1rH$b}
                          zKH(_6p*H-n9E=DE1=s{ezl5I!UtFpuv5_OaJEYKNkt-{5e;E@lGd7)+5=0YSCK$v@QBzhRf@E+^_F6v2p-+RS`79CHKi0r+N
                          z=N*mNc>O>9ZNPh5cs^eq+;ZN40N7;SMsK6;yxOT-opvy=-JHKm_b7zlNo3nYXoTLJ
                          z3_~t%q~Z5AaNd&8NA51<_q+7z<*PURo=Fr#GfIDSlpey{{~4?;O+p(uECHPHPKU1w
                          zAV)W~UfvEL=#r3&1H70|eJBuBJc0WtVbbcILE|SKX|;`xBduqlmy9Do_?<~oG4@MN
                          zqOw)z8xAH;j1y-gc(64{su{94O!*?XxVkA%X`zrZWLk;BS(wz_CU8yk;275gQnP)e
                          z53+v?{?))~IS%tL{WEK*qr)te{2F9(-B%zZ7!&ac)6khTAx_W1{nZ{ctg)5B5VwC8
                          z$0w?{@}vOqk;q99Lx6*0WPqW3-NPeQ;-N<>OPe)WUIEc+3U5$o>R4q4b~@k`>a>o5
                          zgFOaLC1Js-BoQdRqO}rc3@vlDso$yIyqSMl(}(AOhTEJ6+c)9W^d+1_C7*vR?Pte7ug(#o3SP$&^i>XCYo<`A*0SG$W*H~
                          zQ%5)zAUp{M`Q;o~Hs^L`IU|o8%48Qa{;@-O-O=q0kdIP$Q}5d~FSxn~NUuVnUr;gc
                          z;(bgT%%cm<9M3)o%sm(QAz0&Zsu*<$lsvsF?zks)##5yzk3jrC{c@4k5^(?k4$p|o
                          
                          diff --git a/posts/moio-reshenie-zadachi-60/index.html b/posts/moio-reshenie-zadachi-60/index.html
                          index 47e9fc5..a77bf56 100644
                          --- a/posts/moio-reshenie-zadachi-60/index.html
                          +++ b/posts/moio-reshenie-zadachi-60/index.html
                          @@ -1,7 +1,7 @@
                           
                            Моё решение задачи 60
                          1. Моё решение задачи 60

                            Необходимо найти множество из пяти простых чисел с минимальной суммой такое, что после “склеивания” в любом порядке любых двух чисел из него тоже будет простое число. Здесь под процедурой “склеивания” чисел \(a\) и \(b\) подразумевается получения из \(a = \overline{a_1 a_2 \ldots a_n}\) и \(b = \overline{b_1 b_2 \ldots b_m}\) некоторого \(c\) так, что \(c = \overline{a_1 a_2 \ldots a_n b_1 b_2 \ldots b_m}\).

                            Полное условие можно найти тут

                            Для начала, можно понять, что непосредственный перебор “в лоб” слишком медленный и нужного результата не даст. Поэтому хочется уйти от, как мне кажется, не самого формализуемого условия к чему-то более простого, с чем проще работать. Давайте сначала поймём, какие вообще числа могут быть в одном множестве. Для этого достаточно перебрать все разбиения на два подчисла всех простых чисел. Это достаточно быстро, порядка \(O\left( N \right)\) операций. Важно не забыть, что мы можем разбивать число \(p\) только на \(\overline{p_1 p_2}\), между числами не может быть нулей! То есть если число 37 разбивается на 3 и 7, то 307 нет.

                            Пусть мы получили набор таких разбиений, то есть набор пар вида \(\left( p, q \right)\). Давайте составим из них граф, где вершинки это простые числа, а ориентированное ребро из \(p\) в \(q\) означает, что есть пара \(\left( p, q \right)\). Из того, что порядок склеивания чисел произвольный сразу следует, что рассматриваемый граф должен быть неориентированным. Таким образом, все пары \(\left( p, q \right)\) для которых нет пары \(\left( q, p \right)\) необходимо выкинуть, а из оставшихся построить граф.

                            Теперь задача стало гораздо понятнее: достаточно выбрать клику размера 5, что сумма значений её вершин минимальна. В общем случае, это достаточно ресурсоёмкая(как мне кажется) задача, но в реальном графе количество рёбер не слишком большое. В худшем случае, по теореме Турана, количество рёбер в графе лишь с одной такой кликой примерно на 10% меньше числа рёбер в полном графе.

                            Непосредственно сам поиск такой клики можно реализовать тривиально. Ниже мой код на C++11 с использованием библиотеки Boost Graph Library (BGL).

                            #include <iostream>
                            +        
                            1. Моё решение задачи 60

                              Необходимо найти множество из пяти простых чисел с минимальной суммой такое, что после “склеивания” в любом порядке любых двух чисел из него тоже будет простое число. Здесь под процедурой “склеивания” чисел \(a\) и \(b\) подразумевается получения из \(a = \overline{a_1 a_2 \ldots a_n}\) и \(b = \overline{b_1 b_2 \ldots b_m}\) некоторого \(c\) так, что \(c = \overline{a_1 a_2 \ldots a_n b_1 b_2 \ldots b_m}\).

                              Полное условие можно найти тут

                              Для начала, можно понять, что непосредственный перебор “в лоб” слишком медленный и нужного результата не даст. Поэтому хочется уйти от, как мне кажется, не самого формализуемого условия к чему-то более простого, с чем проще работать. Давайте сначала поймём, какие вообще числа могут быть в одном множестве. Для этого достаточно перебрать все разбиения на два подчисла всех простых чисел. Это достаточно быстро, порядка \(O\left( N \right)\) операций. Важно не забыть, что мы можем разбивать число \(p\) только на \(\overline{p_1 p_2}\), между числами не может быть нулей! То есть если число 37 разбивается на 3 и 7, то 307 нет.

                              Пусть мы получили набор таких разбиений, то есть набор пар вида \(\left( p, q \right)\). Давайте составим из них граф, где вершинки это простые числа, а ориентированное ребро из \(p\) в \(q\) означает, что есть пара \(\left( p, q \right)\). Из того, что порядок склеивания чисел произвольный сразу следует, что рассматриваемый граф должен быть неориентированным. Таким образом, все пары \(\left( p, q \right)\) для которых нет пары \(\left( q, p \right)\) необходимо выкинуть, а из оставшихся построить граф.

                              Теперь задача стало гораздо понятнее: достаточно выбрать клику размера 5, что сумма значений её вершин минимальна. В общем случае, это достаточно ресурсоёмкая(как мне кажется) задача, но в реальном графе количество рёбер не слишком большое. В худшем случае, по теореме Турана, количество рёбер в графе лишь с одной такой кликой примерно на 10% меньше числа рёбер в полном графе.

                              Непосредственно сам поиск такой клики можно реализовать тривиально. Ниже мой код на C++11 с использованием библиотеки Boost Graph Library (BGL).

                              #include <iostream>
                               #include <algorithm>
                               #include <vector>
                               #include <set>
                              diff --git a/posts/moio-reshenie-zadachi-60/index.html.gz b/posts/moio-reshenie-zadachi-60/index.html.gz
                              index bc2a731aa5b376bcaad5dcb1c0ec313e6fc7cdbe..a1a15f7480ab46c3ed4ee89504f18a9da3fcaebf 100644
                              GIT binary patch
                              delta 5882
                              zcmV`oqF?pCfQWqn5qqE-peO`zuXNfTq21C1ak!a7%d!u}S=Z#sgW;86PnDhj
                              z0G7MXGw7__dxHEH!4RivY|=Wj3#Jso&SPQ(^dRd%Ievh=1Gs;8c6*O|pT{6etAO-A
                              z&3`yg2{H+qIlz1-55KAu7OsDWBs
                              zt$_`?P!)|KBeQ=xKDZbpt01FWUsN5pkFi!8_8!3Vw3O|)nD@)67FE*0FkQZW3*Q>U%st^(z6bu%(>%k{
                              z9p?pF>=Ri*m@XFfKJWdRph&$(K=T#pJ;K&ILgu{@AN3MSdY{0pJ$ZrtYZt9Q3$4*+
                              zfhJM}PqTkbUVrV)m6fG6xZ1^QAoUEY1IgYKQM9~9oM!}Rf8{&{8hf(s$Gs;Y%r2^0
                              zlnB<~&a>VpULK_^`|$ZY=odRjQ3!fjFX6!qLks4ygS1_M~4d^_N{cBN?{
                              zlAa3;4+wz+*awUWW~2=vS%e*!JB|$g7Yu(9;qibIFdR^0?@M7(d%aHx`W^(Mi%)3l
                              z`X0am2)m2JD;?3cy!yUhH!CRvpIxC7!N8vcc7(@4Tm!l7Vd2P_p;~u|uma#BCpGs}
                              z4DdGgG-~+JHj55T*6x>mhJB-%Jr$7c;vj%@e-#;$M1Wv!WbovGy@VdWcJ}(hN&J6+
                              zZxx>Svr#wGm4p2q;(`cA_88p_j1;=-{r(f4bTp*wv
                              zE^YKgQmz*u+0M{Q>?1qRQMSI18DUd2LpK`~5P+%wkxKUE1ZBfUAET;0UcBpX)4#c`
                              zu?@aJJ|MR(wcg;F5kGR^3f2W*yyJhogs%T0aN}C18-iVR4((>I_j%vAaF|DQ@XXcD
                              z(Es~0WqSP5fe3oLu1oN5G4x6%xFEB#GW0uHX>#9VFd2aaMpah|msbxq&>j)OFV7R_
                              zTkKlE0!y}~L5~V?;nE=~hhYLazJL~fDJx_l7nUx`Yz6xUJ05yPG%MMK(BOYC!0d?r
                              zgg=z7#*Ownh>SxBb6&dr3>hA_1Daj@gTD58peiLG%q-a)!-St*_GeE>bZ?LgAa7uB
                              z2%bN|2z-Y@9yY>8k#$Z%v{y6+~MQ_$Va64Qt7zF&V5{|qETN%k>z
                              zpqE2H3XBhMk9h9=d5{(M{V&{v2Cl8UIvra3w<5VfYxrVxCetPTwFvC|JE3UQ-E&Wt
                              zB3RvC4Tu5A@<=4w6%l+F@gQmKNvBTU7$TxSmFSWI@Lg|$kpJ3axPJ4IF2)AZ54`B~
                              zAGyA(D`q5L28S#$t9yThdA{%^5YRDL^`0z*r7Rhb&O`!(f=gd8oFwfHz$_^oh)nF$
                              zk!cw8`ZYMmZS;z6668tNo=V$-8wVmG_zUD&II9u!(8FTl0HI+^`@nn&di_>RVbD0b
                              z*~vUS^KdL!!Fc&-n5m4+^XR
                              z7DOKa_nY9XSRe@_t0aZJ?D}%MGn#z&$4vOLgJF))_e?v(0fhnh2Cl#F2knr`;{Hs3IhOL2djErYL_mfB>t%GykDBJLff
                              z4)3MPVo%GLPbkEr1aPb7FNmHh!_fQj3+%4N(cR4ah@qa9qlg^iR;a=@f>`n*&W|@k
                              z!ql$_+GDF50U~9CIt6bSxlK!#8;DG~5ya)tRK{A15P8&^XH8S1+#d}gT7{XtpvoKlFV)hd7HR{dYZy()aZIMBoKZO7`zsO*f;b+sunvq1+h4F
                              zXu>kuG=u0V!SOvaOYprJ9l5@G91Tn}x#1}pgjrRsWmTFjjYnm3IdL`tL>mK;kZEy8
                              zTikyL(!R?1ee)Kr32Y3?QfSBn&7#KN{zz6jbuFNo)qT
                              z80&w6CCr)y9U?!@S7}m)KD})w??YxugwEpovBdY-GeVQ9NyX}s#gjy0d-(Ky9oGie
                              zf&0WJ@nW?x>Z*{<`0=MYa-H;4tU#Pjyv=`S2_!6?843Q=Cp00eS~CN3TJs9CqNB|h
                              zIasIq5vv5wRMcn+4$FksBKLu#k!0$Jq6VgZK}_Tl5;Qc4oL3GR=*Tyh<5*6_Y4Ch!
                              zy3?`{11Qt2ACbBD6bPhArZfhmnHMdCk+gD#q+=i7Bq15PsF_J>BhD9R5W>`rXd8bX
                              zlfrCN={MA1@dKJ{E=Ni$Ll-n+@fufCy?k}gxg#xiy(`YlBP)#EX
                              zW_B|}c!P5HqpA~p&5KQ{Ex5IrHQ|4jO>~3DJm++37T<81*)~)qFiBzB6{=iA-OMQ|
                              z{4uPtOjzJzA?llHGp|X_s0zjbS9N~z=M^3)VRhTZS$@K;1Uu4%+%;ME8GRc*v~+G0
                              zV}qFFXJj+MJa?|!dK!Q^Kgah;llw;AP3G{LnPwQTw<0U+PQ+c`X_g}6f{kgz(^@BA
                              zLG#s5k_X|=_J$JJ8#)W4XJPcDgwZ6uSg;#g`H?J`m`NS29uvb&>d`X$vu>P?TZ}3l
                              z!tSf~a0E|tJX@NFRUFqE5SoAb7Bv$)6`qadug{KF&G2N>(H!xSTZbR&>gETn=Gjuw
                              z$y+KqG8mjCl*joTma5y#;t9q4X>!cOAHh1IGKXfo!^7!=S5BU7)cmLqEl=7v!E-c>
                              zDK}VDT#i0z9Vv3uqo!Pe&vZjatE+*b+T!efrT=9G0bW_WJ0MDw4cmWR5W7$&Z%mZ$
                              zsG?$`ii;9j@wp6}MclWU@VwhpTS!NzfiS=(eeN6?s!Vfi{z#V*PZ1<%(S5~e@x=4o
                              z38&IWbGYeO;DFHzi?IQ2^QZu?&*OQ@*g%|Pe3;VAKO@mY5Tqk=2x1yxS1dbBJsZCn9Vago+K1GbJ`?z?G`JhDH?!q?sv%x2NLq;_daTjJz%+Kv~!r^KAyxyx7^n`b?
                              zVI;cHGW$wV9RCx;Hb*C!QFi{86WjTVk|ZY`rY5+`S@(1kLHd6zt7a!5h((THll<9i
                              z2ut>no{6*R#GZeM95BLWIY-BKup^vnjKM>+s@`IAdRIv7h0c1!JhmONeyBT-{^W2r
                              z$wj#+i%*fF!jZf+9|`tVOjep^qKTBFymp&{0>}>P%-A
                              zhEUF#5?F@^93q{`k16K5jk4N{R}Y0M`B<_h;1Z%;U$vu`u4UrbtOTs!*rPfU?<
                              zpPCt(kC
                              z;&9Fkn282{E8><^tV43qvC^Ky5yI0BugK4JP0TQ6K5nQ8`f=Vv9frxowxtt&_$zzr
                              z#0h_{EApYrdA(2_VT$TgYccZgLk(vRYinoEMa=Z|4~C(ff}`#2I7i!ka5~o$?(JA7
                              z+-HB_GU0>n?aKVVrD$$PbEf`kqjtpO>UezMjU)LElcRDBQ8sjAp9l(bD4G8c@6j6j
                              zvW)51Rf3z%=;14N@N(Cw|00p4M88NR4z6RZ_@1Dz|CoKP{aw%w0p~|vn{5$V4FLb*
                              zr0-LV$@ihXfMnkuHWBRNxMtLE`JLN)o#uZq17=#(DR7vX-HK=zcM^Hs*+7P9bDX0&
                              z#~rBP*6*`zxZnVwMT|`WA64y*J+kd{f|AY+WqU8l0a7O}}D}9c!ArGxz5hlTT!R%j}lMXFtu^RP_qeSd;0IC%iE=9`Ap|
                              zQ|$4L{D>_E@H>GkrKez?h4DG6Z#X4#RVU6YBE92_Ci$M=Fe|Gjxvcjv6QH?V&>G4#
                              ztRMA}oAAL&V)8ICQWZ>#!Ih%6%jeFWE1G5JAHB!UGiST^coo>;mZ8_nD;Jk8T!1F>
                              z3fh#hX1~8^NV)f@_asY-$fswqQQRQTo^t^8_MHRb
                              zJnen%yn+wCkDYC3{mR*KUO?$HrwdfRAkKHr0TgxN=5wt616&;RK6AFS#M$XRa(;li
                              zuX3s=JyFhANT*C)sqbuq>ftJwhIaYh(@+un~yslSma}A{EN{RDQ
                              z$8x!l@Q%q!DbDWm!d=>?@-Ai$WZ}GG)LIz0@}S3SGKO90yr(Rro0K>1()+S<#blaV
                              zqk84FpZ@Z-pZxN*bS6U{oI`&+wy8xtRY{2qXx1!7IdjP_q-BM4W=*v8w92arG@Q_>
                              zUptfyTON|mx2|o~uxg=DQ}n!BlsBw;!TnsoHvrnaa2+mx4MlhDw`zvIq1H<`+3$0g
                              zuiwaBzy5yZS2wS}Z&>ijua8>`TdJ-YTY1A|7A0?yl&b5@!Zs0Cdp
                              zN%edCRjZo6D!N;EkRpr23iwO%u}W^GuVe2>57Y324f?2TnLbts|4w#$wTsR
                              zoEK0F_O9w?ix+?~ATNJEqs*YdY#MSnyheF)S8v?#6UZwGC~)Pj7#nEaY-+;`L6hmN
                              z;nlwyMl(Q5ifWr0?OfK>x(*`L0H4fC2iAKJRHAdJxWt-1wd{tm)$e|laI3|}>$r@g
                              z_QuNaN7d2eA{7u51icME3m^#o&7|)T7zp2XE{DU0Klur?f?t2w#J7cM88v3x*KBZM
                              zctX~nUs;p2Rkj6ki@_VK^U#N<^k6IlMYVZHV**F%yo>(I+fs}y>E9vwrs26#Jy$xC
                              zuNj(w2&`%_aU|!7+B6M|Q=O*)j^o^Vxp|mbBPnUZ3j>c;HIxqd;~$BSTePoqZqoV(
                              zw8<9I4Mvr8=GK4GolKsZCWQ8@4OLSXJgxxT+(U?u@}hi>`20XAtD$KH6gR9wKnb-~
                              zg$?4eVe?#*ahme4Em}Zi{yRoJ2skq6K|p~BO-aLI8>Lh}Ux0r#aDa8g>OfRC?gDE$
                              z*3y`jZ}6s;DzD3X97N`v5VI6)eI@=lRhSU0VJ!F6VTGrg!HC#Los8g+LZY>d^
                              zMXexip%}FpHU>q=Z-&`XQ^3JhwkT4SQVI-lvt?I!1HV`x)z67!&K4Sn2mN9!b*X?y
                              zvA7Oc!+@o!_ZULU4LAa^8!cTRXQ3a6Jw)uyX~Hnp3l5;7l-eB~gC_cjHBUcSItZv~
                              zvN+E9BA9=-yqO1`6&QpI5mLN#7N#||Da;bB*T*b@)y%NdhnWTU%4?iO-Ec40HAZbl
                              zm`te6tqKTQ7mZc
                              z@J_K{XfD%UD*XvTaa1rwW~ELyOSf*N@y!*NYvSwmAXb;Rn9kP?qpqNK;w9r==%)hvG3O!AWh+}UBGuxK!@Tn*HPdU5dS!$
                              Q==sY32MFIGVZyrr0DR(BJ^%m!
                              
                              delta 5883
                              zcmV
                              zXNN$@e$;ymA^KJC3y9bU5U~fU0g6HZ_e!Vj5!x+H5Qm#Nv@H8joOMmEJQ!XH_Eg#V
                              z4`8|LJcG`^vq$Ko7DGl;a1;JAi+CXSesb_jwGmvKjHMQzNil
                              zH?|m<1gUn&IzuO==Up;TsaTLy%FI
                              zhHB(2jHSBDavxEJ)*5Q=;!?qlD^xDKYh{TY5g2k!Qq1A^A=yae+B%iI%w<$K^CJu#Cb-5_E*kRps^?0e%yNk!tA1|
                              zMTuYy?mX*#;^k4wvJaoXgMP7d6qP`WPoVlXplK+daIbD#@Y{Lf{HLh%2ylkII?wx+
                              z{|)Fphps*r0!|^q2uDTRq=Rw9{3cbty+ChgAcB8GK^eWiZ-9%t}yC7
                              z0iJ(-ul;xuBpWg$HvlpW;dz~LyaDs|X6fQmsthCaN$;@?GH#E5g`s*PD8hJkG5Tgb
                              zUEyHvqb>Hn7}^i2QP>bV9)N;0T^#NG-sb>GDBKoBPf^c(gbG7KXE1;z%C`fKYgd{U
                              zBI&un@PH6FfPKK2U`E;yl112ox#P&-f5Cqc5grdX0mA_`_P!Jrwb%QEpzlF2y7+{)
                              zuI~XHfUvtbywVYE%d7AEb+eK(@YxkQ5e)oEU`Kcy#5IuH9u|&_8LD-c2rB?Ca#C|o
                              z#Q<+(PostpZL{dmWbJ<0XV^EI*;4`8E)D`n_g9f2NdySyMg~s~*h}c~YiF-7oWy?*
                              z_*UVGKO1#3T{+m_Aufn;WRKC^z(}FH-tUi#*GF#)CJ;BSmQi%5?q-X^x<2j0#{~k)
                              z;nGG=B;|SmlI;w=#6Gg~9A)eKm=QKbGjy{-0Rfo$AE{(tPEa;%^f9X1Mo+9f+W}>$(L07DKOOf(tS$D?`7Nl_vK+29ps;U{rObaC!A$1MLwZ{PH|;
                              zzQwKuEU;u-8uX|T7cL!=au_C%;|plvm$E_@a$)I`%vP{(u;ZauM6;4z2n~M@1I&)-
                              zPxwRWYTRhQgUC39Fz2P)&ye9^JD}OcKj>?p2dYv6!pxG*F--W`Wqq;Gi#ArW{4
                              zQDFAIRW?1ye=+bk+vq?0*dBi#y;Y#EzGV+Kd$|Hmrlt)mwC(QBVK4cMg7>(Rf6CMT#pcU_rS_bC2K_dbb_VQ>k
                              z(jo5=;fy6l4}`Clj#26lU>;e2$d(A^gA7OJrTcE8IR)L#EHQoP?)!fw@y|dalw==c
                              z2YNXKq`>$9_lW1-p9fiC-~Yl*XyDqqtJ9&ie=Cv;w1zK6XEI&VUyH!bzY~f^-97hY
                              zDT3AQ)qog)ERRH@T@k@|5f75qo^Gu)hU+&U>0)dk{lJS(
                              z|B>svx?)E1WpKz6v$}srnCA;$0s$R^Rqx3{Sjv*|=u9LqD7f?m!%5QK0L+rYfyl%@
                              z9hrtfuU~_6+(xhHCPAKL?WwdaxN#s7g1
                              zo1M(VGY`jt6^xgUhMCI9T<_&zaOK4h!YbwP_A_X*y!2BU0QY}|7@n-?P|rUM^71_|
                              zY(ew^aK8!8iUpD|vPx3e%dRiCJEO^Wf6Rn0I~e8&eb2Nr98eg5Z{Yg-e$aj?75ZFC
                              zdUbJed0FTRd;Y=oiZ2GvX-8(A7%HEN?heFQAv;$LnCp{wEowH%`)bvqR);KjTu6?^hO30QZ0Wggrpm9WdQEF7tnY~q
                              zRoF;;oj0j@
                              ze4W>9uBdt<($9y%D%xeQt=8>;0a*yZ+RY$xdaD^gD&yM(3LZ>3
                              z=yHSQICW()dq&`n$p8r3YN#3uQqIC;MURPazT{idR8!@ppneh=9lsF@)>%FPTV~5{
                              zRI0RgFCr#GH1g9xg)A=x!F6p$!9&<7#Te8=bP<1IgA&?4oWUq9NK-7EMI659K&i62
                              zst5Iw$tKnh)0MzpGP78|#dyoo=jUzW4(e$NuTi7x&5%I&L16G&2x8yR2dP@@;1tB-
                              z)S(H>XwwX$rv%6M%q+q8W_0BG>TxtM&E$rsWDsUmwU$+Bwlp4<&E>?|1Q2ZuKtiU)
                              z9c_PcBS`xyj~sVG5EA4Rt#I$V7M;8EiLw{wv;(bZaWR0L%9Ajl@cd|;n^I88&nB@M
                              z*kY{z36?Nx7IcXGIA5hn8T$0LnY<5~B@sG{@5d6~W6uapswNeyM;1>KiS6Oj_jOzw
                              zTnFwGo5YLN#;B`8Hsi;i>d1A{Q?UYZI`MxtpCyp6bY>*@PoL0)tZK~+$Z5?h%!-aS
                              zU*uq&>PM^+I8#xhDL5<>UW?oZjz*HHABq~7`UNqOOGwbrBywIkWS}G8T#jQo5vRfP
                              zo#{@?LJXixw|+$C-culuCYjP0kY--A3`Ww*8Iq2De3OJ^=%QvOsf{>aoIwavH==)S
                              zcuWejQKjEdgT)VMvbh{7tqfhzh{bd0h()w};-6KIrq(BK09H=H03@i_7)DKbM4hS$
                              zsWfy6H*nAKL1fe(=l)`o-eZ-ZSz8>(k&O)W$nibF^{lhCFu1>*Di;dGVojsXY(h1S
                              zESTBN4B-vR-H)nH@HH%2HKQsR2VB+p#h+Jrq=eON7iakiw-W3~6LQyN-DmV|_|Ve1
                              zO^gjy1oPavZtH0P<^Z`@gOnADmARbv8ArqzQ}
                              zK&8xM-z>%iX@YGen1&ArFo8Tg4$om}_@v`)vt*iKyxxketUD2ReWzK9j0-lV4Nq&G
                              zd^hJKGydU~lLwjGl$jlM+Ug^kTtoY~@F?U}7e9w0cYoH>pRRZ%I>{NI*mcKqbS~bIyNk?YFw3=s2
                              zMJI2m=*VDjmQWt&b6BcwGm9q_^QXx%6MqEjgvuP6@eU8C4_-NWwo&t=KD0b(-vrOm
                              zFs9sKQE@r?q;;goQIDE(1wPXa9j&eghH8tm`<4Ee6$E%?@$P^qQ8s^UcR}nznY=Mk
                              zzN3nYi7GBiXvOC;Y!-3fX2SDsQ*9v~od&`HoAkMJWT-ODvH2riMm$B3oJIE)qs0@?
                              zb0?fiAI;&WUx5QgD=fwaxXq&iygrZTDPse1j`3lFpQFm%3KBZ;6A6G+CB~DRVQ7kz
                              zbFanW?tG%`O|>9A{i%QZ5yofT6^sh5q!&~sG}L-dl3m=`8{UU=^Fb&Itt
                              z?WmLX@PsLI^!pSsw(jHNHRgj7ak~rK;Lir1=nWawOvGK7IWa%C(+P*C?eluCR?rjP
                              z!G@9OLd)zcMREL34BH%?WJcNfTTX1}FG`Y}beNjpDreo(O$2}Gv#gq(gdi3a)|8{!3{S<`
                              zi@y_8a{cn}E5Coc{CyTM
                              zJ`5J>D5l=4julNN?Rsch=swelIzDAZoytz|sWZ=H!!~L7V2v@-i%?>}qs@%GwQVOD
                              zKmDDr*@?Pu5x6j$?5mxl_cP5>^B8ZmcCRAWFIm)g0ZcN?Oy;lubaa2AbRe31qJK8A<`k6UKUF^wi)+UUr^_4o?d>2Q%4*EKQ2nEAM&BIw6?4|NzO6Wf+f^x?1U
                              zsS_vsxvt2ED(Ce=b%ZIZPp!qszYjH>IjpUnJr^<4*FPABate;Nx8odb_rd90Pq?>Z
                              zop67jfy;ysy0k%zW!tOwf1*GI|Q5`d2O~uXf*)*
                              zi<7=jF(%)K_5zZ9d)P#nKKyCuwkg8Z`ZiId-gR^3L3!V@y7g`7N_s8lU|%XH(THOk+)^N1pJ;)Odfq
                              z6Hl?nH}WI47{KoYu9TjFc^1a!sJ`Kp$W@&zEe2PL+Ag0vcdlrboqzNmJI|c$-s4qZhg*hTFRxr&x^MxS
                              z$SY`5#+v<7Z{O4e|NP^gedBq4g_g$9Vyz&zvq$`GPp#IR{YGg`3Z@`VVk%(EH5U&Jt&*_sIDH
                              z>b~lI;k@X5())_|FnZ0Zc*N_>IL_60p9><^TKtw{52Hawcn~4`i5FB-DJPd
                              zUA}%Jcm4YNm0#Vw{=Q+sC%-;!Eo`Z}Vr=CNlUbC!MN+D+GYi|K$SQvkgOJMHA*FNu
                              zv?kT>?N_a8{;KG1;X#Tl4lCd<$;T?WmA;O>BRya*eJ49s6Ifj(4+!+bbXzra8yf-d
                              z$R;+);)UI5Rt?RT*Sc}dvH+m{s}FUBZGiPFvIoL8Ta*JO`526i)Nvs|Uak_PmnIL%
                              z!*O0fE!exNn=M`d#(;mk{ERY#0<&qz;qV&e$z8p1!%rZuB%r{RyJBphb+f4rF9c1d
                              zw}w~$Y8cG`Eh(yPYP54%Q|mg2Py>82D;-$xJy40xq2dy2`qZ);##X=kRl=gkBd}5Oc3-o{49VV_&1ZjLtr3$+qoPL8~)@c&hdT$SnqMtj4Mo9gPVbrSmTOD{o6NvZQ~9*eNQW{sqz2`>yhR@G2C|oLtQ$`2)AfIl^=nykYu9k`JfKdsuDP{D
                              zgch}exP@ZWX4n`MA-@@BM@<0-SJ|RSRZ1x^#Lbpn;SKy^fmA;yk~v#w93J$GvDBpk
                              z9>wB1U=0J7rru)+EjQo@#BQ{7ft-bYAodWkH>U~1ST8t$ic)HKbPSs4Bi20qVCf*B
                              zrpe+s=Zk+}-tuN1bXH&xE<{N2(pi|+)TS^?v|b;x1XeS{P9J6#+$*nf7InkDT-O-2
                              z8DToDYK;6EbaKNTK!cz^B)q|fplfh$t`-U-lD-A^D}8FXP$2w(};npwkav
                              zE|QlIeqCW3hQ$`@Sv&J^0Qc;`4grnhVWRIdkjK7XYk)L`yLJKJK>;0#$6QB&Q$YOV
                              Rh@$5!{~u!kipIjb004X}O$7h|
                              
                              diff --git a/posts/nakhozhdenie-summy-k-ykh-stepenei/index.html b/posts/nakhozhdenie-summy-k-ykh-stepenei/index.html
                              index 77762b6..e4c0187 100644
                              --- a/posts/nakhozhdenie-summy-k-ykh-stepenei/index.html
                              +++ b/posts/nakhozhdenie-summy-k-ykh-stepenei/index.html
                              @@ -1,7 +1,7 @@
                               
                                Нахождение суммы k-ых степеней
                              1. Нахождение суммы k-ых степеней

                                Давайте сразу обобщим задачу до нахождения \(f_k\left( n \right)\), где

                                $$f_k\left( n \right) = 1^k + 2^k + \ldots + n^k$$
                                Для \(k=1\) формула известна всем школьникам: \(f_1\left( n \right) = \frac{n\left(n+1 \right)}{2}\). Формулу для \(k=2\) знают уже не все, но всё же в школе её найти можно (я видел на обложке учебника по алгебре): \(f_2\left( n \right) = \frac{n\left(n+1 \right) \left( 2n + 1 \right)}{6}\)

                                Интуиция может подсказать, что \(f_k \left( n \right)\) есть некий полином со степенью \(k+1\). Если это так, то его нахождение тривиально. Например, можно посчитать его в явном виде, используя полином Лагранжа. Осталось показать, что наша функция представима в таком виде.

                                Для начала введём обозначение. “Нижней степенью”, \(x^{\underline{k}}\), будем обозначать такое выражение:

                                $$x^{\underline{k}} = x(x-1)\cdot \ldots \cdot (x-k+1)$$
                                .

                                Далее, заметим следующее, если \(a_i = A_{i+1} - A_i\), где \(\lbrace a_i \rbrace\) и \(\lbrace A_i \rbrace\) — некие последовательности, то \(\sum_{i=1}^n = A_{n+1}-A_1\) (телескопирование, можно посмотреть тут, с. 6).

                                Теперь посчитаем сумму \(\sum_{i=1}^n i^{\underline{k}}\). Для этого достаточно понять, что \(\left( x+1 \right)^{\underline{k+1}} - \left(x \right)^{\underline{k+1}} = \left( k+ 1 \right)x^{\underline{k}}\). Отсюда сразу получаем, что

                                $$\sum_{i=1}^n i^{\underline{k}} = \frac{\left( n+1 \right)^{\underline{k+1}}}{k+1}$$

                                Осталось показать, что “нормальные” степени выражаются через нижние. Начнём со степени \(k=1\), тут всё просто:

                                $$x = x^{\underline{1}}$$
                                С бОльшими степенями сделаем следующее: считая, что все степени, меньше, чем \(k\) мы выражать умеем, раскроем скобки в определении нижней степени. Теперь поймём, что старший коэффициент \(1\): \(x^{\underline{k}} = x^k + \sum_{i=1}^k a_ix^i\) или \(x^k = \sum_{i=1}^k a_ix^i - x^{\underline{k}}\). Осталось понять, что каждое из слагаемых вида \(a_ix^i\) мы умеем выражать через нижние степени. Таким образом, можно получить следующее:
                                $$ \sum_{i=1}^{n} i^k = \sum_{i=1}^{n} \sum_{j=1}^{k} a_j i^{\underline{k}} = \sum_{j=1}^{k} \sum_{i=1}^{n} a_j i^{\underline{k}} = \sum_{j=1}^{k} \frac{a_j \left(n+1 \right)^{\underline{k+1}}}{k+1}$$

                                Кстати, формула для суммы в самом начале такая:

                                $$ \sum_{i=1}^n i^5 = \frac{1}{12} n^2 \left(n+1 \right)^2 \left(2n^2 + 2n-1 \right) $$

                                1. Wallabag и реальная жизнь

                                  Начать следует с того, что Wallabag действительно является самым популярным среди открытых приложений для отложенного чтения. Можно взять, например, alternativeto:

                                  Первый релиз вышел почти два года назад. Тем не менее, мне сложно назвать продукт зрелым. Последняя, на момент написания, версия 2.0.0-beta.2 не может похвастаться простым процессом установки. Вариант просто выполнить команды из мануалов по очереди у меня не получился. В этом соперничать с тем же Pocket, очевидно, бессмысленно.

                                  Стандартная тема, material, ужасно выглядит на моём ноутбуке с разрешением 1366x768, элементы явно рассчитаны на большую диагональ. Ещё часть места отъедает неубирающаяся плашка внизу страницы, предупреждающая о том, что баги в бета версии не есть что-то плохое. Официальное Android приложение упорно не может найти сервер.

                                  После волевого решения перейти на стабильную версию (то есть откатиться в равзвитии на полгода назад), дела улучшились, но не сильно. Количество настроек минимально, если не сказать, что их вообще нет. Но оно работает, вроде.

                                  Сложности, впрочем, только начались. Обещанная синхронизация с Pocket работает, мягко говоря, неоптимально. После загрузки экспортированного html файла со ссылками, wallabag почти час выкачивал мои 750 статей. Где-то на 500-й статье он выделил слишком много памяти и упал с ошибкой. После этого пришлось руками искать потенциально проблемные статьи и удалять их по одной — удалить сразу несколько элементов невозможно. Затем надо было выкачивать ещё 250 статей, периодически посматривая, чтобы ничего снова не упало.

                                  Кажется, что все проблемы закончились, но нет. Дальше синхронизация с телефоном. Она заняла почти столько же времени, при этом, начальное очевидное предположение о том, что токен безопасности вбивать не нужно (он сам заполняется в приложении) стоило где-то 15 минут поиска. Но и это не всё. После того, как база загрузилась, небольшие изменения на телефоне (такие как удаление статьи) синхронизировались больше минуты!

                                  Резюме: пользоваться можно, но советовать кому-либо это использовать я точно не стану.

                                  Этого бы поста не было бы, если бы я сказал, что Wallabag плохой, а OTHER_PRODUCT хороший и можно пользоваться им. Но я так написать не могу. Ни я, ни alternativeto других решений не знают. Значит нужно их создать. На моём слабеньком VPS уже почти год трудится Syncthing, управляя значительным количеством файлов с минимальной нагрузкой на ЦП. Поэтому мне кажется, что Go подойдёт идеально.

                                  Если написать подобный продукт на Go, то многие проблемы даже не появятся:

                                  • не нужно разрешать большое количество зависимостей — достаточно одного бинарника
                                  • скорость генерации контента (например, создание pdf, epub) будет значительно выше
                                  • небольшой оверхед позволит всё хранить в памяти
                                  • работа почти на чём угодно

                                  В совокупности, будет достигнуто, как мне кажется, самое главное — удобство для обычного пользователя, который сможет без проблем развернуть это на любом VPS.



                                  1. Моё решение задачи 60

                                    Краткое условие: необходимо найти множество из пяти простых чисел с минимальной суммой такое, что после “склеивания” в любом порядке любых двух чисел из него тоже будет простое число.


                                  Page 1 / 1

                                  Page 1 / 1

                                  Page 1 / 1
                                  1. Моё решение задачи 146

                                    Краткое условие: необходимо найти сумму всех натуральных \(n\), что \(n^2+1\), \(n^2+3\), \(n^2+7\), \(n^2+9\), \(n^2+13\), и \(n^2+27\) будут последовательными простыми числами.

                                    1. Моё решение задачи 146

                                      Краткое условие: необходимо найти сумму всех натуральных \(n\), что \(n^2+1\), \(n^2+3\), \(n^2+7\), \(n^2+9\), \(n^2+13\), и \(n^2+27\) будут последовательными простыми числами.

                                      1. Wallabag и реальная жизнь

                                        Как я устанавливал известнейшее свободное решение для отложенного чтения, и что из этого получилось.


                                      Page 1 / 1
                                      1. Нахождение суммы k-ых степеней

                                        Как придумать формулу для суммы \(1^5 + 2^5 + 3^5 + \ldots + n^5\) и есть ли она вообще?

                                        1. Wallabag и реальная жизнь

                                          Как я устанавливал известнейшее свободное решение для отложенного чтения, и что из этого получилось.


                                        Page 1 / 1

                                        1. CrossGen v1.0

                                          Читая хабр, случайно натолкнулся на идею сделать программу, которая по заданной кроссвордной сетке находит способ её заполнить. В этом посте вкратце напишу про моё решение и первую версию приложения.


                                        2. Ещё одно вычисление выражений

                                          На хабре когда-то увидел статью про то, что в Яндексе двум сотрудникам дали задачу на написание приложения, для вычисления выражений. Менеджер справился за 4 часа, а программист за два. Я решил попробовать свои силы.


                                        Page 1 / 1
                                        1. Моё решение задачи 134

                                          Краткое условие: назовём порождающим для двух последовательных простых \(p_1 < p_2\) наименьшее натуральное число, что оно закачивается на \(p_1\) и при этом делится на \(p_2\). Необходимо найти сумму порождающих для всех \(p_1 \in \left[ 5; 10^6 \right]\)

                                          1. Моё решение задачи 134

                                            Краткое условие: назовём порождающим для двух последовательных простых \(p_1 < p_2\) наименьшее натуральное число, что оно закачивается на \(p_1\) и при этом делится на \(p_2\). Необходимо найти сумму порождающих для всех \(p_1 \in \left[ 5; 10^6 \right]\)


                                            Page 1 / 1
                                            1. Моё решение задачи 134

                                              Краткое условие: назовём порождающим для двух последовательных простых \(p_1 < p_2\) наименьшее натуральное число, что оно закачивается на \(p_1\) и при этом делится на \(p_2\). Необходимо найти сумму порождающих для всех \(p_1 \in \left[ 5; 10^6 \right]\)

                                              1. Wallabag и реальная жизнь

                                                Как я устанавливал известнейшее свободное решение для отложенного чтения, и что из этого получилось.


                                              Page 1 / 1
                                              1. CrossGen v1.0

                                                Читая хабр, случайно натолкнулся на идею сделать программу, которая по заданной кроссвордной сетке находит способ её заполнить. В этом посте вкратце напишу про моё решение и первую версию приложения.


                                              Page 1 / 1