В этом году мы с товарищами (ForNever, Minoru, Hagane, grouzen) опять взялись участвовать в ICFPC. Если кто не в курсе, что это такое — см мой предыдущий пост или серию постов товарища adept.
В этот раз для разнообразия мы не писали AI для игрушки. Организаторы были из Японии, и поэтому мы весь уик-енд… складывали оригами. Кто-то из кода, а кто-то нет.
Задача состояла в том, чтобы из квадратного «листа бумаги» складывать разные (плоские) фигуры. В качестве задачи даётся описание нужной фигуры, а решение — набор складок на квадрате и описание, какие вершины в какие переходят при складывании. Первая сотня фигур была предложена организаторами, а дальше задачи могли отправлять участники, и за отправку задач тоже давали очки.
При этом, на самом деле, это было «не настоящее оригами». Были допустимы решения, невозможные с бумагой — части листа могли проходить друг через друга при складывании. При отправке решений чужих задач можно было даже «рвать бумагу» (при отправке своих задач — нельзя). Момент про разрешено ли разрезание мы уточняли долго и сложно.
Контест в этот раз проходил с утра пятницы по вечер воскресенья в моём часовом поясе.
В пятницу
с утра я «по-быстрому» написал скачивалку задач с сервера и закачивалку решений (на python, просто потому что там было REST API, а у меня уже был опыт использования для этого питоньей библиотеки requests). Ещё я написал парсер предложенного формата задач и рендерилку, которая рисует фигуры из задач в виде svg (на Haskell). Сразу пригодился хаскельный модуль Data.Ratio. Дело в том, что в задачах использовались координаты в виде рациональных чисел, причём размеры числителя и знаменателя не были ограничены. Так что быстро образовалась строчка type Number = Ratio Integer.
Потом я посмотрел на результаты рендера и увидел, что первые семь задач тривиальные (там просто квадрат, сдвинутый или повёрнутый, но не сложенный), решения для них легко написать вручную. Решил и залил.
Потом мы начали думать над задачей (я уже писал, у меня всегда так — сначала код, потом думать).
Когда нет ограничения на разрезание бумаги, задача сводится к тому, чтобы разрезать квадрат на эн многоугольников и сложить из них нужную фигуру. Насколько я знаю, подобные темы широко и глубоко изучены, но я не знаком с конкретными работами и алгоритмами. (в университете был даже какой-то спецкурс по оригами, как разделу геометрии, но я на него не попал). Поэтому я долго и упорно думал в эту сторону, но ничего не придумал.
В чате довольно быстро образовалось несколько идей:
- Разрезать требуемую фигуру на треугольники и попытаться из таких треугольников сложить квадрат.
- Какой-нибудь вариант генетических алгоритмов: разрезаем квадрат как попало и складываем как попало, оцениваем скор в соответствии с правилами организаторов.
- Быстро придумался простой алгоритм для складывания любого достаточно маленького выпуклого многоугольника: пройти по всем его рёбрам и сложить бумагу вдоль них. Если останутся торчащие «хвосты», то опять пройти по рёбрам и подвернуть вдоль них.
- Кроме силуэта фигуры, в задачах приводился её «скелет» — набор всех рёбер в положении после складывания. При этом, правда, было указание, что это только подсказка, складывать в соответствии с этим скелетом не обязательно. Так вот, появилась идея брать этот скелет и пытаться разворачивать его до квадрата.
Товарищ grouzen произвёл обширные изыскания существующих научных работ на тему оригами и около, и обеспечил нас пейперами для чтения на всю неделю. К сожалению, применить их мы не смогли.
Потом начался как всегда разброд и шатание, каждый стал заниматься чем-то своим.
Я решил начать с написания какого-никакого «фреймворка» для дальнейшей работы — набора функций для разрезания многоугольников, объединения и т.п. Некоторые из геометрических алгоритмов тривиальны (отражение многоугольника относительно прямой), зато другие зубодробительны (объединение произвольных многоугольников). Для таких алгоритмов я стал гуглить существующие реализации, по возможности на Haskell (т.к. парсер задач уже был на Haskell). Нашёл только clipper. Это биндинги к одноимённой библиотеке на C++. Сразу обнаружилась особенность: Clipper работает с целочисленными координатами (видим
Python: настройка URL's в Django
Автор: Няшный Человек
Дата публикации: 2016-06-12T17:03:00.000+03:00
Python: Запуск Django проекта
Для того чтоб такое не повторялось, я создал данную заметку, которая и вам может понадобиться…
Шаг первый: Открываем калькулятор, закрываем!
Шаг номер два: Входим в виртуальное окружение Django
Шаг номер три: запускаем сервер
Для этого я должен попасть в папку в которой находится manage.py
Вот и все, сервер запущен, приложение — сайт работает!!!
Автор: Няшный Человек
Дата публикации: 2016-06-12T15:37:00.000+03:00
Майкл Доусон — Программируем на Python, ответы на 5-ую главу…
Задача №1
- # coding=utf-8
- # Создайте программу, которая будет выводить список слов в случайном порядке.
- # На экране должны печататься без повторений все слова из представленного списка.
- import random
- print(«Введите 4 слова для демонстрации программы:»)
- a = input(«Первое слово: n«)
- b = input(«Второе слово: n«)
- c = input(«Третье слово: n«)
- d = input(«Четвертое слово: n«)
- WORDS = [a, b, c, d]
- print(«nИзначальный список:n«, WORDS)
- # Эта функция не упоминалась в главе, но чтобы не писать лишнего, лучше заменим строчки этим:
- random.shuffle(WORDS)
- print(«nСписок в случайном порядке:n«, WORDS)
- input(«nНажмите Enter, чтобы выйти…»)
Задача №2
- «»» coding=utf-8
- Напишите программу «Генератор персонажей» для ролевой игры.
- Пользователю должно быть предоставлено 30 пунктов,которые можно
- распределить между четырями характеристиками: Сила, Здоровье,
- Мудрость и Ловкость. Надо сдлать так, чтобы пользователь мог
- не только брать эти пункты из общего»пула», но и возвращать их туда из
- характеристик, которым он решит присвоить другие значения.»»»
- «»» Также, хоть это и не требуется в задании, мы будем требовать
- от игрока, чтобы он улаживался в отведенные 30 очков и использовал их все.
- Также, только после окончания задания заметил, что 5 глава была
- про списки и словари, соответственно, автором, скорей всего,
- подразумевалось, что здесь должны использоваться словари.
- Переделывать или писать вторую версию с использованием словаря
- не буду, так как считаю, что алгоритм решения ясен.Даже будет короче.
- А в следующей главе изучите функции и попробуйте сделать это задание,
- сипользуя функции. И вы удивитесь, насколько сократится код.
- Но, следуя согласно книге, подразумевается, что мы пока не знаем о них.»»»
- # Объяснение условий игроку.
- print(«»»Вам будут представлены изначальные характеристики героя: Сила, Здоровье, Мудрость и Ловкость.
- Вам нужно будет, как в ролевой игре, распределить 30 очков между навыками»»»)
- # Объявляем переменные.
- strength = 0
- health = 0
- wisdom = 0
- agility = 0
- choice = None
</li >
- global_choice = None
- while global_choice != 0:
- # Вывод актуальной таблицы после действия.
- ost_points = (30 — strength — health — wisdom — agility)
- print(«Таблица характеристик на данный момент: n«
- «ttt1. Сила:», strength, «n«
- «ttt2. Здоровье:», health, «n«
- «ttt3. Мудрость:», wisdom, «n«
- «ttt4. Ловкость:», agility, «nn«
- «tttСвободное количество очков:», ost_points, «n«)
- # Первый выбор
- print(«Что вы хотите сделать сейчас?n«
- «ttt1. Добавить очки в одну из характеристик.n«
- «ttt2. Убрать очки из характеристики.n«
- «ttt3. Закончить распределиние очков.n«)
- global_choice = int(input())
- if global_choice == 1:
- print(«В какую из характеристик вы хотите добавить очки?n«
- «ttt1. Сила.n«
- «ttt2. Здоровье.n«
- «ttt3. Мудрость.n«
- «ttt4. Ловкость.n«)
- choice = int(input())
- if choice == 1:
- print(«Сколько очков вы хотите добавить?n«)
- scores = int(input())
- if scores >= 0 and scores <= ost_points:
- strength += scores
- else:
- print(«Недопустимое количество очков.n«)
- elif choice == 2:
- print(«Сколько очков вы хотите добавить?n«)
- scores = int(input())
- if scores >= 0 and scores <= ost_points:
- health += scores
- else:
- print(«Недопустимое количество очков.n«)
- elif choice == 3:
- print(«Сколько очков вы хотите добавить?n«)
- scores = int(input())
- if scores >= 0 and scores <= ost_points:
- wisdom += scores
- else:
- print(«Недопустимое количество очков.n«)
- elif choice == 4:
- print(«Сколько очков вы хотите добавить?n«)
- scores = int(input())
- if scores >= 0 and scores <= ost_points:
- agility += scores
- else:
- print(«Недопустимое количество очков.n«)
- # Второй выбор
- elif global_choice == 2:
- print(«Из какой характеристики вы хотите убрать очки?n«
- «ttt1. Сила.n«
- «ttt2. Здоровье.n«
- «ttt3. Мудрость.n«
- «ttt4. Ловкость.n«)
- choice = int(input())
- if choice == 1:
- print(«Сколько очков вы хотите убрать?n«)
- scores = int(input())
- if scores >= 0 and (strength — scores) >= 0:
- strength —= scores
- else:
- print(«Недопустимое количество очков.n«)
- elif choice == 2:
- print(«Сколько очков вы хотите убрать?n«)
- scores = int(input())
- if scores >= 0 and (health — scores) >= 0:
- health —= scores
- else:
- print(«Недопустимое количество очков.n«)
- elif choice == 3:
- print(«Сколько очков вы хотите убрать?n«)
- scores = int(input())
- if scores >= 0 and (wisdom — scores) >= 0:
- wisdom —= scores
- else:
- print(«Недопустимое количество очков.n«)
- elif choice == 4:
- print(«Сколько очков вы хотите убрать?n«)
- scores = int(input())
- if scores >= 0 and (agility — scores) >= 0:
- agility —= scores
- else:
- print(«Недопустимое количество очков.n«)
- # Третий выбор. Проверяем, все ли очки использованы.
- elif global_choice == 3:
- if ost_points == 0:
- break
- else:
- print(«Используйте все очки, данные вам!n«)
- print(«Ваш герой готов! Таблица его характеристик выглядит так: n«
- «ttt1. Сила:», strength, «n«
- «ttt2. Здоровье:», health, «n«
- «ttt3. Мудрость:», wisdom, «n«
- «ttt4. Ловкость:», agility, «n«)
- input(«nНажмите Enter, чтобы выйти…»)
Задача №3
- # coding=utf-8
- «»»
- Напишите программу «Кто твой папа?», в которой пользователь будет
- вводить имя человека, а программа — называть отца этого человека.
- Чтобы стало интересней, можно «научить» программу родственным
- отношениям среди литературных персонажей, исторических персонажей,
- исторических лиц и современных знаменитостей.
- Предоставьте пользователю возможность добавлять,
- заменять и удалять пары «сын-отец».»»»
- MENU = («»»
- 1 — Поиск отца человека по имени
- 2 — Изменение данных
- 3 — Удаление данных
- 4 — Добавить новые данные
- 5 — Выход
- «»»)
- family = {«Остап Бендер»: «Турецкоподанный»,
- «Люк Скайуокер»: «Дарт Вейдер»,
- «Солид Снейк»: «Биг Босс»}
- choice = None
- son = «»
- father = «»
- while choice != 5:
- print(MENU)
- choice = int(input(«Выберите пункт меню:»))
- # Поиск отца человека по имени.
- if choice == 1:
- son = input(«Введите имя человека: «)
- if son in family:
- print(«nРодителем человека по имени», son, «является», family[son])
- else:
- print(«Ошибка, такого человека нет в базе данных»)
- # Изменение данных.
- elif choice == 2:
- son = input(«Введите имя человека: «)
- if son in family:
- father = str(input(«Введите новое имя его отца: «))
- family[son] = father
- print(«nРодителем человека по имени», son, «является», family[son])
- else:
- print(«Ошибка, такого человека нет в базе данных»)
- # Удаление данных.
- elif choice == 3:
- son = input(«Введите имя человека: «)
- if son in family:
- del family[son]
- print(«nЗапись удалена»)
- else:
- print(«Ошибка, такого человека нет в базе данных»)
- # Добавить новые данные.
- elif choice == 4:
- son = input(«Введите имя человека: «)
- if son in family:
- print(«nТакая запись уже существует»)
- else:
- father = str(input(«Введите имя родителя: «))
- family[son] = father
- print(«Добавлено в базу данных»)
- # Выход.
- elif choice == 5:
- print(«До свиданья!»)
Задача №4
- # coding=utf-8
- «»»
- Доработайте программу «Кто твой папа? так, чтобы можно было,
- введя имя человека, узнать, кто его дед. Программа должна
- по-прежнему пользоваться словарем с парами «сын-отец».
- Подумайте, как включить в этот словарь несколько
- поколений. «»»
- MENU = («»»
- 1 — Поиск деда человека по имени
- 2 — Изменение данных
- 3 — Удаление данных
- 4 — Добавить новые данные
- 5 — Выход
- «»»)
- family = {«Остап Бендер»: {«Турецкоподанный»: «Отец турецкоподанного»},
- «Люк Скайуокер»: «Дарт Вейдер»,
- «Солид Снейк»: «Биг Босс»}
- choice = None
- son = «»
- father = «»
- while choice != 5:
- print(MENU)
- choice = int(input(«Выберите пункт меню:»))
- # Поиск от ца человека по имени.
- if choice == 1:
- son = input(«Введите имя человека: «)
- if son in family:
- print(«nРодителем человека по имени», son, «является», family[son[0]], «а его дедом», family[son[1]])
- else:
- print(«Ошибка, такого человека нет в базе данных»)
- # Изменение данных.
- elif choice == 2:
- son = input(«Введите имя человека: «)
- if son in family:
- father = str(input(«Введите новое имя его отца: «))
- family[son] = father
- print(«nРодителем человека по имени», son, «является», family[son])
- else:
- print(«Ошибка, такого человека нет в базе данных»)
- # Удаление данных.
- elif choice == 3:
- son = input(«Введите имя человека: «)
- if son in family:</ div>
- del family[son]
- print(«nЗапись удалена»)
- else:
- print(«Ошибка, такого человека нет в базе данных»)
- # Добавить новые данные.
- elif choice == 4:
- son = input(«Введите имя человека: «)
- if son in family:
- print(«nТакая запись уже существует»)
- else:
- father = str(input(«Введите имя родителя: «))
- family[son] = father
- print(«Добавлено в базу данных»)
- # Выход.
- elif choice == 5:
- print(«До свиданья!»)
Автор: Alek Azimov
Покоряем Python Django — модели
Пробуем создать модель данных…
в папке где находится ваш manage.py выполните команду
python manage.py startapp blg
еще не до конца понял суть команды, по факту мы создаем приложение над которым и будет вестись основная работа…
В итоге у меня создалась папка с таким содержимым… смотрите ниже
- models.CharField — поле с ограниченным количеством символов
- models.TextField — поле с неограниченным количеством, как раз подойдет для текста новости..
- models.DateTimeField — дата и время.
- models.ForeignKey — ссылка на другую модель.
Автор: Няшный Человек
Дата публикации: 2016-04-23T21:59:00.001+03:00




