Показаны сообщения с ярлыком Программирование. Показать все сообщения
Показаны сообщения с ярлыком Программирование. Показать все сообщения

пятница, 19 мая 2017 г.

Период Пизано

Часть своего свободного времени я уделяю обучению на платформах для дистанционного обучения и прохожу разные курсы. Больше всего мне нравится Stepik.org.
На этом ресурсе можно найти много курсов для "чайников", где понятным языком объясняются разные аспекты IT (и не только).
После освоения основ язык программирования Python, я пошел дальше и поступил на курс "Алгоритмы и структуры данных" от Computer Science Center (Сейчас разделен на два: Алгоритмы: теория и практика. Методы и Алгоритмы: теория и практика. Структуры данных).

Трудности настигли на первом же уроке - "Числа Фибоначчи".
Для справки:
Числа Фибоначчи - это последовательность, в которой первые два числа равны либо 1 и 1, либо 0 и 1, а каждое последующее число равно сумме двух предыдущих чисел. Числа Фибоначчи на OEIS.

Последняя задача урока - задача на программирование повышенной сложности:
Даны целые числа n и m (1 <= n <= 1018, 2 <= m <= 105), необходимо найти остаток от деления n-го числа Фибоначчи на m
Memory Limit - 256 Mb
Time Limit - 5 seconds. 

Как можно догадаться, ограничения по памяти и времени не позволят наивному алгоритму пройти решение.
Немного погуглив, я наткнулся на обсуждение такого термина как "период Пизано".
Оказывается, что если составить последовательность из остатков деления чисел Фибоначчи на какое-ибо число, то остатки будут чередоваться с определенной периодичностью.
Возьмем первые тринадцать чисел - 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233 - и найдем остатки деления на 4 - 1, 1, 2, 3, 1, 0, 1, 1, 2, 3, 1, 0, 1.
Остатки чередуются с периодичностью каждые 6 членов, таким образом период Пизано для делителя 4, равен 6.

Для решения задачи, описанной ранее, прежде всего необходимо определить тот самый период, с указанным делителем.
Для этого в отдельный массив записываем остатки от деления чисел Фибоначчи на m до тех пор, пока не получим две единички идущие подряд.
Далее, для удобства, удаляем два последних числа массива.
После этого нужно найти x - остаток от деления n на период Пизано.
Ну и наконец, программа должны вывести число из массива с остатками с номером x.
Это и будет ответом задачи.


Еще информации на Вики и в OEIS.
На этом все )

четверг, 14 апреля 2016 г.

Создание логотипа ОНМедУ в svg

Приветствую.

Совсем недавно прошел один очень интересный курс на платформе Stepic.org. Курс называется "Компьютерная графика: основы" и ведет его преподаватель Высшей школы экономики Денис Королев. На первом модуле обзорно рассматриваются такие понятия как свет, цвет, цветовосприятие, цветовые модели и пространства и много другого. Также отмечу, что курс обильно приправлен практическими занятиями от которых, иногда, идет пар из ушей. Но в целом, курс несложный и идеально подходит для новичков.
В одном из практических занятий курса необходимо было нарисовать пару фигур в векторном формате SVG (Scalable Vector Graphics — масштабируемая векторная графика). Задания были достаточно сложными, на первый взгляд, но по мере того, как я разбирался в синтаксисе, все стало белее-менее понятно.
После окончания онлайн-курса, я решил, что надо бы применить полученные навыки на практике. Вспомнилось, что раньше я нигде не мог найти логотип моего университета в хорошем качестве для того, чтоб всунуть в презентацию. Неплохо было бы ее сделать. Цель ясна, инструмент есть, пора браться за работу.
Для начала, мне нужна была хоть какая-то картинка, в качестве эскиза. Поискал в Гугле, зашел на сайт университета и нашел только картинку 96х112 пикселей.Да уж, не густо.

Я решил, что выходная картинка будет в 10 раз больше, то есть 960х1120 пикселей. В первую очередь я в Paint'е определил цвета по RGB - (230, 255, 237), (119, 57, 3), (255, 255, 255), а потом на этом сайте перевел в шестнадцатеричное представление или HEX-код - #E6FFED, #773903, #FFFFFF.
Далее я создал обычный html документ с объектом svg внутри, а работал в обычном текстовом редакторе (в моем случае это "Блокнот"). Это удобно в том плане, что такой документ открывается любым браузером, а после внесения изменений в файл, достаточно просто обновить страницу в браузере. Вот как изначально это выглядело:

<!DOCTYPE html>
<html>
<body>
<svg width="960" height="1120">
/*Это комментарий. Код будет ниже*/
</svg>
</body
</html>


Затем я начал вставлять объекты используя этот туториал. В качестве фона я просто отрисовал прямоугольник с размерами 960х1120 пикселей. Начал было я рисовать рамку, но понял, что все совсем уж криво получается. Необходим был какой-то "трафарет" и надо бы его изготовить. Взял я исходную эмблему, увеличил его до размеров 960х1120 и сделал полупрозрачной (50%). Для этого я воспользовался консольной версией программы ImageMagick:
convert emblem.png -resize 960x1120 -alpha on -channel a -evaluate set 50% logo.png

Трафарет готов, пора вставлять его в svg-файл:
<image x="0" y="0" width="960" height="1120" xlink:href="logo.png"/>

После этого шага дальнейший процесс рисования заключался в прописывании нужных фигур с нужными размерами.
До какого-то момента мне вполне достаточно было окружности и овалов. Но потом, для отрисовки головы змеи и книги, возникла необходимость использования кривых Безье. На этом сайте приведен тэг кубической кривой и, собственно, какие числа меняются при передвигании опорных и управляющих точек. Именно кубические кривые я и использовал, хотя для книги вполне подошла бы и квадратичная кривая. Вот ссылка на нее.
После того, как я все было готово, я удалил трафарет, еще раз полюбовался логотипом и создал в том же блокноте файл с расширением .svg. Для того, чтоб браузеры корректно отображали этот файл, нужно прописать все заголовки с типом документа, версией продукта и ссылками.


Вот и все. Ну вот собственно сам логотип, правда немного уменьшенный и в формате png, ибо svg не поддерживается блогспотом.

 «Odesa national medical university logo»
«Логотип Одесского национального медицинского университета»Лицензия Creative Commons



Собственно, видео того, как выстраивались блоки.

 

Ну а под конец сам исходный код svg-файла.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1"
baseProfile="full"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ev="http://www.w3.org/2001/xml-events"
width="960" height="1120">

/*Background*/
<rect x="0" y="0" width="960" height="1120" fill="#e6ffed"/>

/*Frame*/
<rect x="140" y="100" width="690" height="50" fill="#773903"/>
<rect x="140" y="100" width="50" height="920" fill="#773903"/>
<rect x="780" y="100" width="50" height="800" fill="#773903"/>
<rect x="140" y="970" width="570" height="50" fill="#773903"/>
<circle cx="705" cy="895" r="100" stroke="#773903" stroke-width="50" fill="#ffffff"/>
<rect x="700" y="150" width="80" height="750" fill="#ffffff"/>
<rect x="190" y="890" width="520" height="80" fill="#ffffff"/>
<rect x="190" y="150" width="520" height="750" fill="#ffffff"/>

/*Bowl*/
<ellipse cx="310" cy="255" rx="95" ry="45" fill="#773903"/>
<rect x="210" y="210" width="200" height="50" fill="#ffffff"/>

/*Snake*/
<rect x="452.5" y="615" width="270" height="275" rx="50" ry="50" fill="#ffffff" stroke="#773903" stroke-width="55"/>
<rect x="480" y="585" width="50" height="80" fill="#ffffff"/>
<polygon points="480,570 750,570 750,608 480,626" fill="#ffffff"/>
<polygon points="480,633 675,642.5 675,663 480,663" fill="#ffffff"/>
<ellipse cx="532" cy="629" rx="20" ry="6.5" fill="#773903"/>
<path d="M515,628 C630,620 742,602 725,616" stroke="#773903" stroke-width="5" fill="#773903"/>
<rect x="425" y="250" width="55" height="500" fill="#773903"/>
<path d="M278,227 C280,150 510,125 477,258" stroke="#773903" stroke-width="5" fill="#773903"/>
<path d="M278,225 C280,250 425,210 428,254" stroke="#773903" stroke-width="5" fill="#773903"/>
<path d="M298,239 C300,244 427,222 422.5,257" stroke="#ffffff" stroke-width="5" fill="#ffffff"/>
<ellipse cx="371" cy="204" rx="22" ry="15" fill="#ffffff"/>

/*Book*/
<path d="M507,670 C507,660 585,680 585,700" stroke="#773903" stroke-width="8" fill="#773903"/>
<path d="M585,700 C585,680 662,660 665,670" stroke="#773903" stroke-width="8" fill="#773903"/>
<path d="M507,810 C507,800 585,820 585,840" stroke="#773903" stroke-width="8" fill="#ffffff"/>
<path d="M585,840 C585,820 662,800 665,810" stroke="#773903" stroke-width="8" fill="#ffffff"/>
<rect x="503" y="669" width="8" height="143" fill="#773903"/>
<rect x="581" y="700" width="8" height="135" fill="#773903"/>
<rect x="661" y="669" width="8" height="143" fill="#773903"/>
<polygon points="507,668 585,697 665,668 665,805 585,830 507,805" fill="#773903"/>
</svg>