2009 год подходит к концу, и с экономикой и всеми, мы сэкономим наши деньги и вместо того, чтобы покупать дорогие фейерверки, в этом году мы будем отмечать в ASCII-арт.
Задача
Учитывая набор фейерверков и время, сделайте снимок фейерверка в это самое время и нарисуйте его на консоли.
Лучшее решение, введенное до полуночи в канун Нового года (UTC), получит награду в размере 500 репа. Это кодовый гольф, поэтому количество персонажей сильно зависит; однако так поступают голоса сообщества, и я оставляю за собой окончательное решение относительно того, что лучше/круто/наиболее креативно и т.д.
Входные данные
Обратите внимание, что наша система координат слева-направо, снизу-вверх, поэтому все фейерверки запускаются с y
-координатом 0 (ноль).
Входные данные состоят из фейерверков формы
(x, speed_x, speed_y, launch_time, detonation_time)
где
-
x
- это позиция (столбец), в которой запускается фейерверк, -
speed_x
иspeed_y
- горизонтальная и вертикальная скорость фейерверка во время запуска, -
launch_time
- это момент, когда этот фейерверк запущен, -
detonation_time
- это момент, когда этот фейерверк взорвется.
Данные фейерверка могут быть жестко запрограммированы в вашей программе как список из 5-ти кортежей (или эквивалент на вашем языке), не считая вашего персонажа. Однако, это должно быть легко изменить эти данные.
Вы можете сделать следующие предположения:
- существует достаточное количество фейерверков (скажем, меньше сотни).
- для каждого фейерверка все пять чисел являются целыми числами в разумном диапазоне (например, для каждого из них будет достаточно 16 бит),
-
-20 <= x <= 820
-
-20 <= speed_x <= 20
-
0 < speed_y <= 20
-
launch_time >= 0
-
launch_time < detonation_time < launch_time + 50
Единственная дополнительная часть входных данных - это точка времени, которая должна быть отображена. Это неотрицательное целое число, которое предоставляется вам с помощью стандартного ввода или аргумента командной строки (в зависимости от того, что вы выберете).
Идея состоит в том, что (если ваша программа представляет собой python script, называемый firework.py
), этот bash script дает вам приятную фейерверковую анимацию:
#!/bin/bash
I=0
while (( 1 )) ; do
python firework.py $I
I=$(( $I + 1 ))
done
(не стесняйтесь помещать здесь эквивалентный .BAT файл).
Жизнь фейерверка
Жизнь фейерверка выглядит следующим образом:
- До запуска время его можно игнорировать.
- Во время запуска ракета имеет положение
(x, 0)
и вектор скорости(speed_x, speed_y)
. - Для каждого временного шага вектор скорости добавляется в позицию. С небольшим натяжением, применяемым к законам Ньютона, мы предполагаем, что скорость остается постоянной.
- Во время детонации ракета взрывается на девять искр. Все девять искр имеют такое же положение в этот момент времени (это позиция, которую имела бы ракета, если бы она не взорвалась),
но их скорости различаются. Каждая скорость основана на скорости ракеты, с -20, 0 или 20, добавленной к
speed_x
и -10, 0 или 10, добавленной кspeed_y
. Это девять возможных комбинаций. - После времени детонации сила тяжести начинает тянуться: с каждым шагом времени гравитационная постоянная, которая оказывается равной 2 (двум), вычитается из каждой искры
speed_y
. Горизонтальныйspeed_x
остается постоянным. - Для каждого временного шага после времени детонации сначала добавьте вектор скорости в позицию, , затем вычитайте 2 из
speed_y
. - Когда положение искры
y
опускается ниже нуля, вы можете забыть об этом.
Выход
Мы хотим, чтобы картина фейерверка выглядела так, как она смотрит на данный момент времени. Мы смотрим только на фрейм 0 <= x <= 789
и 0 <= y <= 239
, отображая его на вывод символов 79x24.
Итак, если ракета или искра имеют положение (247, 130), мы рисуем символ в столбце 24 (нулевой, так что это 25-й столбец), строка 13 (на основе нуля и подсчет снизу, поэтому строка 23 - 13 = 10, 11-я строка выхода).
Какой персонаж получает рисунок, зависит от текущей скорости ракеты/искры:
- Если движение горизонтально *, то есть
speed_y == 0 or abs(speed_x) / abs(speed_y) > 2
, символ "-
". - Если движение вертикально *, т.е.
speed_x == 0 or abs(speed_y) / abs(speed_x) > 2
, символ "|
". - В противном случае движение диагонально, а символ "
\
" или "/
" (вы угадаете правильный). - Если одна и та же позиция набирается более одного раза (даже если она имеет тот же символ), мы вместо этого ставим "
x
". Предположим, что у вас есть искра в(536, 119)
и одна в(531, 115)
, вы рисуете "x
", независимо от их скорости.
* update: это целые деления, поэтому наклон должен быть не менее 3 или не более 1/3 соответственно
Выход (записанный на стандартный вывод) составляет 24 строки, каждый из которых заканчивается символом новой строки. Пропущенные пробелы игнорируются, поэтому вы можете, но не нуждаться в них, набирать ширину 79. Линии могут быть не более 79 символов (исключая новую строку). Все внутренние интервалы должны быть пробелами (ASCII 32).
Примеры данных
Фейерверки:
fireworks = [(628, 6, 6, 3, 33),
(586, 7, 11, 11, 23),
(185, -1, 17, 24, 28),
(189, 14, 10, 50, 83),
(180, 7, 5, 70, 77),
(538, -7, 7, 70, 105),
(510, -11, 19, 71, 106),
(220, -9, 7, 77, 100),
(136, 4, 14, 80, 91),
(337, -13, 20, 106, 128)]
Вывод в момент времени 33:
\ | / / \ - | / - | - / \
Выход в момент времени 77:
\ \ X \
Вывод в момент времени 93:
\ | / \ / / - - - \ \ / \ \
Обновление: Я загрузил ожидаемый результат в период от 0 до 99 до firework.ü-wie-geek.de/NUMBER.html, где NUMBER - время. Он включает в себя отладочную информацию; нажмите на частицу, чтобы увидеть ее текущее положение, скорость и т.д. И да, это домен umlaut. Если ваш браузер не может справиться с этим (как, очевидно, не может переполнять стеки), попробуйте firework.xn---wie-geek-p9a.de.
Другое обновление:. Как показано в комментариях ниже, более длинный фейерверк теперь доступен на YouTube. Он был создан с измененной версией MizardX ', с общим количеством фейерверков в 170 (да, это больше, чем запрос, но программа обработала его изящно). За исключением цвета, музыки и конечного экрана, анимацию можно воссоздать с помощью любой записи в этом поле для гольфа. Итак, если вы достаточно уродливы, чтобы насладиться фейерверком ASCII (вы знаете, что вы есть): веселитесь и счастливый новый год для всех!