singalen: (sun)
[personal profile] singalen
Этим летом на ICFPC team Grobocode вышла в виде нас с [livejournal.com profile] sanyok_ua.
Хорошо помог [livejournal.com profile] vbayda. [livejournal.com profile] nataly_scheg помогала отлаживать математику.
Выступала команда в основном из посёлка Морское под Судаком.

Надо было управлять космическим кораблём! Круто! Пришлось срочно осваивать орбитальную механику.
Подробно условия задачи можно прочесть в отчёте [livejournal.com profile] _adept_-а; в двух словах - надо было переходить с орбиты на орбиту, в т.ч. для встречи со спутниками, экономить топливо, корректироваться, а потом - даже дозаправляться.

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

День первый


Саша написал интерпретатор VM, я - загрузчик. К счастью, динамическое управление памятью не понадобилось.
Как оказалось потом, Вова тоже написал VM, на Пайтоне. Потом это нам помогло, когда искали баги в своей.
Я написал векторную арифметику.

Наша VM на Java занимает 300+ строк - втрое больше, чем у Дмитрия на Хаскелле. Что показательно.

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

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

День второй


Наутро второго дня я придумал приличное API: интерфейс IOrbit, который умеет:
* конструироваться по двум точкам (и времени старта);
* конструироваться по точке, скорости и времени старта;
* отвечать, в какой точке будет спутник на этой орбите в заданный момент времени;
* отвечать, в какой момент времени спутник будет в данной точке;
* вычислять, по часовой или против вращается спутник;
* вычислять вектор скорости в любой точке орбиты
* ещё хотелось бы, чтобы орбиты умели вычислять точку пересечения, но до этого мы не дошли;

Эту математику Саша и отлаживал до ночи, и до конца третьего дня в ней чего-то не хватало. Он зарылся в книги по орбитальной механике и рассказал, что уравнения Кеплера точно не решаются, но есть приблизительные методы.

Я наконец написал писалку решения (решения принимались в виде бинарных файлов с управляющими последовательностями, специального формата).

У Саши заработала управляющая последовательность общего вида - но без согласования периодов обращения нашего и цели. А значит, только для 1й задачи. И, кстати, только для одного её варианта... Но, тем не менее, виртуалка, моделирующая спутник, выдала положительны счёт.
Это уже можно было отсылать как "гол престижа".

Форма отсылка показала "CRASHED!", что, как сказали на jabber.ru, означает, что отправлено решение неверного формата.

День третий


В 17:00 сели на автобус и поехали в Симферополь. Стали думать - как забить гол позора, т.е. отправить-таки решение.
Пригрузили Вову задачей - поискать проблемы в формате сабмита.
В 18:00 Саше пришла мысль, которая крутилась и у меня на задворках сознания - надо бы после каждого управляющего кода, на следующем тике, выдавать в порт 0.
Попробовали, пострадали над GPRS-модемом - и наше решение приняли!

На этом успехи закончились.

Хотя ещё до окончания, 21:00, мы сидели в кафе и отлаживали управляющую последовательность с универсальными орбитами - и "почти было отладили". По моей оценке, отладки было ещё часа на два :)

Слили чисто. Полно идей и материала, и ни одной полностью рабочей реализации.

Работа над ошибками


1. Такие вещи пишутся в юнит-тестах. Изначально.

2. Не застревать. Застрял - переключись, расскажи всё товарищу, если самого не осенит - передай ему.

3. Брать больше народу :) Мы могли бы раскидать разные компоненты человек на 6.
Даже шутка родилась: поскольку оба менеджеры, звоним на работу и говорим "Есть срочная задача на овертайм для 19 девелоперов!"

4. Поднимаем и отлаживаем сетку заранее. Не полагаемся на wi-fi ноутов, приносим свитч или AP.

5. Ни в коем случае не работаем в кругу семьи, лучше сразу бросить. Состояние потока теряется очень легко и часто. Работаем в офисе.

Несортовые заметки


Орбитальная механика в первом приближении достаточно проста и элегантна. Усложнять задачу организаторы стали только в последней, 4й задаче, когда добавилось притяжение Луны. Говорят, орбиты всё равно остались эллиптическими - понадобились только минимальные коррекции.
А ведь могли бы учитывать, что Земля - не материальная точка, и не шар... Гравитационный разворот пробовать...

В 4м задании, оказывается, был ещё один жёсткий прикол - переход с орбиты "по часовой" на орбиту "против". Лучше всего делается с очень вытянутой орбиты, в апогее - когда почти вся энергия орбиты потенциальная, а остаток кинетической погасить дешевле всего.
А суммарная энергия спутника на орбите, конечно, всегда константа.

Ещё напишу в комменты всякого.
This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting
OSZAR »