Напишите самую короткую программу, чтобы превратить любое произведение искусства ASCII в анимированную снежную сцену, которая начинает формироваться из падающего снега ( пример JavaScript без игры в гольф, последнее обновление 2011-12-19).
Спецификация ввода : Ваша программа должна принимать произвольные комбинации пробелов, звездочек и переносов. Ввод будет содержать не более 23 строк и 80 символов в строке. Пустых строк не будет, но строки могут состоять только из пробелов. Один завершающий перевод строки будет включен и должен игнорироваться.
Вывод : Вывод символов ASCII (пробелы, звездочки) и управляющих кодов (возврат каретки, перевод строки, коды выхода ANSI и т. Д.) Для текстовой консоли операционной системы или эмулятора терминала, пока пользователь не завершит программу вручную. Вы можете считать, что окно терминала имеет размер 80x24 символа, если ваша операционная система разрешает эту настройку.
Правила :
- Анимация должна быть плавной и быстрой (желательно 15 кадров в секунду).
- Плотность снега должна составлять от 5% до 15%.
- Не более одного экрана снега может прокручиваться в секунду. (Это означает, что за любой второй период времени может быть добавлено не более 24 строк нового снега.)
- На снегу не должно быть никаких явных следов, поскольку он входит в верхнюю часть экрана; это должно выглядеть случайно.
- Программа должна заполнить все строки экрана снегом как можно быстрее при запуске; начальное заполнение отдельных строк экрана не должно быть очевидным для зрителя.
- Нижний левый угол входного изображения ASCII должен находиться в нижнем левом углу экрана (рисунок 1 для дальнейшего пояснения).
- Область внутри или под искусством ASCII не должна быть постоянно заполнена звездочками. Однако звездочки могут (но не обязаны) прокручивать эту область.
- Снег не должен накапливаться в нижней части экрана или поверх существующего снега, за исключением случаев, указанных во входных данных.
- Нижние пробелы должны быть заполнены перед верхними, так как заполнение пробелов в обратном порядке делает анимацию рождественской елки сильно отличающейся от вывода моего исходного кода. (добавлено 2011-12-20)
Счастливых праздников!
Рисунок 1: маркированные области экрана 80x24
---------------------------New snow added on this line--------------------------
|
|
----------------------------------------------------------+ |
**** | |
Snow MUST fall Snow MAY fall ----------------> **** | |
through this through these **** **** | Snow MUST fall |
area. areas of a **** **** | through this |
completed \---------> **** ****| area. |
ASCII art scene. \ *** **** ****| |
area \ \ ******* **** ****| |
\ \ ******** *** ***| (ALL CAPS terms |
(located in \ \--> ********* *** | have standard |
lower left \ ******* ****** MAY | RFC 2119 |
corner of \ ************* ** fall | meanings.) |
screen) \ *********** here | |
*** +---> **** *** | |
*** | **************** *** | |
| Snow MUST fall *** | **************** *** | |
| through this *** +---> *** | |
| area. *** | **************** *** | |
--+---------------------+*** +---> ***+----+------------------+--
| Snow MUST NOT |****************************| Snow MUST NOT |
V accumulate here. |****************************| accumulate here. V
Пример ввода
Код Гольф Баннер
****** ******* ******** ******** ****** ******* ** ********
** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ****** ** **** ** ** ** ******
** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** ** ** **
****** ******* ******** ******** ****** ******* ******** **
Логотип переполнения стека
****
****
**** ****
**** ****
**** ****
*** **** ****
******* **** ****
******** *** ***
********* ***
******* ******
************* **
***********
*** **** ***
*** **************** ***
*** **************** ***
*** ***
*** **************** ***
*** ***
****************************
****************************
Новогодние елки
*
*** *
* ***** ***
*** ******* * *****
***** ********* *** *
* *********** *****
* ************* *******
* *** *************** * *
*** ***** ***************** ***
***** ******* ******************* *****
******* * ********************* *******
********* * *********
* *
Ответы:
Perl, 196/239 символов
Это решение отличается от вашего примера JS тем, что шаблон заполняется сверху вниз, а не снизу вверх, но я предполагаю, что это нормально, поскольку вы ничего не сказали об этом в правилах.
Тривиальное сокращение на 1 символ может быть получено путем замены
\e
буквенным символом ESC, но это делает код намного сложнее для чтения и редактирования.Обновление: Я сделал удается придумать версию , которая заполняет шаблон из снизу вверх, и не позволяет снег падать через заполненные части рисунка, как и в примере реализации JS, по цене 43 дополнительных символов:
Замена
($s[$_]&=~$f[$_])
на только$s[$_]
что сэкономит 11 символов, позволяя падающему снегу проходить через заполненные части шаблона (что соответствует спецификации, но не реализации примера).Хорошо, так как я все еще продолжаю лидировать в гонке через неделю, думаю, я должен объяснить, как работает мое решение, чтобы стимулировать конкуренцию. (Примечание. Это объяснение относится к заполнению сверху вниз по 196 символам. Я могу изменить его, чтобы позже включить другую версию.)
Прежде всего, одна большая хитрость, на которой основано мое решение, заключается в том, что из-за того, как расположены коды символов ASCII, 1-бит в коде ASCII для пробела просто является подмножеством битов в коде для кода. звездочка.
Таким образом, следующие выражения верны:
" " & "*" eq " "
и" " | "*" eq "*"
. Это то, что позволяет мне использовать побитовые строковые операции для объединения статических и движущихся частей сцены без необходимости зацикливания на отдельных символах.Итак, со всем этим, давайте пройдемся по коду. Вот его версия для игры в гольф:
Первая строка устанавливает массивы
@f
(для «фиксированных») и@p
(для «шаблонов»).@f
сформирует фиксированную часть дисплея и начнёт содержать только пробелы, в то время как@p
, что не показано напрямую, содержит шаблон ввода; По мере продолжения анимации мы будем добавлять все больше и больше звездочек,@f
пока в итоге она не будет выглядеть точно так же@p
.В частности,
@f = ($" x 80) x 23
устанавливает@f
24 строки по 80 пробелов в каждой. ($"
это специальная переменная Perl, значением которой по умолчанию является пробел.) Затем мы берем этот список, добавляем к нему строки ввода с помощью оператора readline<>
, берем последние 24 строки этого комбинированного списка и присваиваем его@p
: компактный способ заполнить@p
пустыми строками, чтобы шаблон появился там, где и должен. Наконец, мыchomp
вводим строки,@p
чтобы удалить любые завершающие символы новой строки, чтобы они не вызывали проблем позже.Теперь давайте посмотрим на основной цикл. Оказывается, это
{...;redo}
более короткий способ написать бесконечный цикл, чемwhile(1){...}
или дажеfor(;;){...}
, особенно если мы пропустили точку с запятой раньше,redo
потому что она следует сразу заif
блоком.Первая строка основного цикла представляет массив
@s
(конечно, для «снега»), к которому добавляется случайная 80-символьная строка из 90% пробелов и 10% звездочек на каждой итерации. (Чтобы сохранить несколько символов, на самом деле я никогда не добавляю лишних строк в конец@s
массива, поэтому он становится все длиннее и длиннее. В конечном итоге это приведет к остановке программы, поскольку массив становится слишком длинным, чтобы поместиться в памяти, но это это займет гораздо больше времени, чем большинство людей будут смотреть эту анимацию. Добавлениеpop@s;
заявления до того, какselect
это исправит это за счет семи символов.)Остальная часть основного цикла заключена в
if
блок, поэтому он запускается только после того, как@s
массив содержит не менее 24 строк. Это простой способ соответствовать спецификации, который требует, чтобы весь дисплей был заполнен падающим снегом с самого начала, а также немного упрощает побитовые операции.Далее следует
foreach
цикл, который в версии для гольфа на самом деле представляет собой единое утверждение сfor 0..23
модификатором. Поскольку содержание цикла, вероятно, нуждается в некотором объяснении, я собираюсь распаковать его немного ниже:Прежде всего,
$_
это переменная счетчика цикла по умолчанию в Perl, если не указана другая переменная. Здесь он работает от 0 до 23, то есть по 24 строкам в рамке дисплея.$foo[$_]
обозначает элемент, проиндексированный$_
в массиве@foo
.В первой строке цикла «de-golfed» мы печатаем либо новую строку (удобно полученную из
$/
специальной переменной), либо, когда$_
равен 0, строку"\e[H"
, где\e
обозначает символ ESC. Это код управления терминалом ANSI, который перемещает курсор в верхний левый угол экрана. Технически, мы могли бы опустить это, если бы мы предполагали определенный размер экрана, но я сохранил его в этой версии, поскольку это означает, что мне не нужно изменять размер моего терминала для запуска анимации.В
$t = $f[$_]
строке мы просто сохраняем текущее значение$f[$_]
во «временной» переменной (следовательно$t
), прежде чем потенциально изменить его в следующей строке, где$s[$_] & $p[$_]
дается пересечение (поразрядное И) падающего снега и входного шаблона, а также|=
оператор ИЛИ это в фиксированной выходной линии$f[$_]
.В строке ниже это
$t ^ $f[$_]
дает побитовое значение XOR предыдущего и текущего значений$f[$_]
, то есть список битов, которые мы изменили в предыдущей строке, если таковые имеются, и отрицание любой из входных строк с отрицанием~
вывода. Таким образом, мы получаем битовую маску со всеми битами, установленными в 1, кроме тех, к которым мы только что добавили$f[$_]
в предыдущей строке. И добавление этой битовой маски$s[$_]
удаляет эти биты из нее; фактически это означает, что когда падающая снежинка заполняет отверстие в фиксированном узоре, она удаляется из массива падающего снега.Наконец,
print $f[$_] | $s[$_]
(который в версии для гольфа реализован простым объединением двух предыдущих строк в ИЛИ) просто печатает объединение (побитовое ИЛИ) фиксированных и движущихся снежинок на текущей строке.Еще одна вещь, которую нужно объяснить, это
select '', '', '', 0.1
нижняя внутренняя петля. Это просто отличный способ спать 0,1 секунды в Perl; по какой-то глупой исторической причине стандартнаяsleep
команда Perl имеет разрешение в одну секунду, и импорт лучшегоsleep
изTime::HiRes
модуля занимает больше символов, чем злоупотребление 4-аргументомselect
.источник
say
), за счет 2 дополнительных символов. Я не думаю, что смогу изменить порядок заполнения очень легко; моя реализация довольно фундаментально связана с этим.HTML и JavaScript, 436 символов
Добавьте его к входу:
Смотрите его для каждого примера: код гольфа , логотип Stack Overflow , новогодние елки . Пользователям Internet Explorer необходимо запустить версию 9 и установить для «Режима документа» значение «Стандарты IE9» (с использованием инструментов разработчика F12), чтобы эта отправка работала корректно.
источник
Питон, 299 символов
Это должно соответствовать правилам, при условии, что перевод строки включен в лимит в 80 символов.
источник
a
и таким образом портит индексацию. Я просто попытался это, и это выглядит как замена%e
с%e.rstrip()
на линии 6 исправляет проблему. (Конечно, может быть более короткое исправление; я не очень хорош в питон-гольфе.)Ява, 625 символов
Простое решение на Java.
источник
"\033[H"
должна это сделать).