Ваша задача на сегодня: нарисовать кривую дракона!
Если вы не знаете, что такое «Кривая Дракона», вот вступительное видео ViHart (очень круто, пожалуйста, смотрите!)
Ваша задача: нарисовать кривую дракона, повторенную как минимум 9 раз. Вам не нужно показывать итерации с 1 по 9, вам просто нужно показать окончательную кривую, полученную после выполнения (как минимум) 9 итераций. Кривая должна быть нарисована в виде прямых линий, соединяющих точки на кривой; выходные данные должны соответствовать одному из изображений ниже, которые показывают 9 или более итераций (вплоть до отражения, поворота, масштабирования и изменения ширины линии, цвета линии и цвета фона). Ваш вывод должен быть достаточно большим, чтобы отдельные строки и «прямоугольники», которые они образуют, можно было отличить друг от друга; если две линии не пересекаются на кривой, они не должны занимать одинаковые или смежные пиксели в выводе (между ними должен быть хотя бы один пиксель фона). Вы можете либо отобразить изображение на экране, либо сохранить изображение в файл принят. Вывод должен быть графическим - это не может быть ASCII-арт.
Самый короткий код в байтах выигрывает, однако директивы для библиотек не должны включаться в число байтов, и вы можете использовать графические библиотеки или другие библиотеки, написанные для вашего языка по вашему выбору, если они были написаны до публикации.
Пожалуйста, включите изображение вывода вашей программы.
Пропустите этот абзац, если вы смотрели видео:Для тех из вас, кто решил не смотреть видео, первые 12 итераций кривой дракона показаны ниже. Для целей этой задачи кривая дракона - это кривая, сгенерированная по следующему правилу: возьмите конечную точку текущей кривой, создайте вторую кривую, повернутую на 90 градусов вокруг этой конечной точки, чтобы конечная точка оригинала кривая является отправной точкой новой кривой, и объедините две кривые в одну кривую, где они встречаются. На изображениях, показанных ниже, каждая новая итерация генерируется путем поворота предыдущей итерации на 90 градусов по часовой стрелке вокруг конечной точки каждой итерации. Когда кривая отображается на экране, не очевидно, какой конец считается «конечной точкой», однако, когда кривая хранится как массив точек, легко определить «конечную точку» в качестве последней точки в массив.
Искусство Ascii ценится, но не принимается: это графический вывод, а не ascii-art.
источник
Ответы:
x86, MSDOS, 16 байт
Я написал это некоторое время назад, насколько мне известно, самую маленькую процедуру создания драконьего фрактала. Он не использует никаких реальных итераций, а отображает каждый отдельный дискретный пиксель внутри фрактала, показывая окончательное изображение. Он включен во многие другие крошечные произведения в этом пакете . 16-байтовая версия была концом моих усилий, чтобы получить как можно меньший фрактал дракона, начиная с 2014 года с этим 32-байтовым производством .
наговор
Код
источник
Python 2/3,
1691671501119878 байтОбратите внимание, что импорт не включен в число байтов в соответствии со спецификациями вызова.
Спасибо @AlexHall за сохранение 39 (!) Байтов и @ nedla2004 за еще 13
Начинается с создания списка или правого (90) и левого (-90) поворотов, затем проходит по списку и перемещает черепаху.
Сгенерированный выход:
РЕДАКТИРОВАТЬ: Если это слишком скучно смотреть, добавьте
speed(0)
прямо перед первымfd(5)
. Он будет работать так же, только черепаха будет двигаться намного быстрее.источник
Логотип, 43 байта
Попробуйте с переводчиком на http://www.calormen.com/jslogo/#
В нем используется тот же принцип, что и в моем предыдущем ответе по искусству ASCII, и формула в википедии, за исключением того, что я изменил направление, чтобы соответствовать изображению в вопросе:
bitand :i -:i
находит наименее значимый битi
. Мы делимi
на это, чтобы погаситьi
нужную сумму, давая требуемое нечетное числоk
. Нет необходимости различать левый и правый повороты; мы просто поворачиваем налево на несколькоk*90
градусов и полагаемся на тот факт, что вращение является операцией по модулю 360, чтобы выполнить по модулю для нас.Выход
используйте,
ht
чтобы скрыть черепаху, если требуется.Выход (модифицированный)
Ниже показано, как кривая представляет собой одну цепь.
источник
LindenMASM , 51 байт
LindenMASM был языком, который я недавно создал для испытания, и он всегда будет жить в Песочнице. Это использует концепцию систем Lindenmayer для рисования таких вещей, как кривые Дракона, фрактальные растения, треугольники Серпинского и т. Д.
Исходный код выглядит следующим образом:
Чтобы настроить это,
n = 6
например:Это создает следующее изображение через Python 3
turtle
:Для итераций может быть небольшое различие в нумерации, поскольку в системе Линденмайера первая итерация представляет собой одну строку. Вот как это выглядит
n = 10
:Просто для забавы, вот как это выглядит с 15 поколениями (с добавленной инструкцией,
MOV 2
чтобы сделать его немного меньше):Как только вы получаете до 20 поколений (с
MOV 0.5
), вы больше не можете видеть линии, и для создания требуется МНОГО шагов (пары+-
и-+
не оптимизированы). Вот что вы получаете:Обратите внимание, что текущий интерпретатор может представлять графические проблемы для меньшего количества поколений, то есть, возможно, не отображать на экране. К сожалению, когда был создан этот интерпретатор, проблем не было, возможное изменение в Python 3 могло вызвать это, или это могла быть просто моя система
источник
Недогрузка, 196 байт
Я подумал, что было бы интересно попробовать этот вызов на маломощном эзоланге; Недостаточная загрузка достаточно хороша для языка с таким небольшим количеством команд.
В результате получается файл SVG с очень сильно вложенными тегами и некоторыми ярлыками для игры в гольф. До сих пор я не нашел браузер, который мог бы отображать его (Firefox зависает на несколько минут, пытаясь загрузить его, и Firefox и Chromium дают пустой экран). Большинство программ обработки изображений также не могут загрузить его (что затрудняет его преобразование в другой формат), но мне удалось загрузить его в средство просмотра изображений Eye of Gnome (которое является частью установки по умолчанию в Ubuntu). Поэтому я сделал снимок экрана с изображением, чтобы вы могли его видеть (фактическое изображение имеет прозрачный фон, но вы не можете по-настоящему сделать его прозрачным):
Нам нужно явно указать размер изображения. Выбор подходящего ориентации для изображения, используя все при минимальном размере правовой, и делать минимальное количество итераций , предусмотренных вызовом, дает нам образ , который только вписывается в 99 пикселей в ширину, экономя байт. Приятно, когда все получается так.
Общий алгоритм, используемый для рисования изображения, состоит в том, чтобы поддерживать две переменные (Underload не называет переменные, но я думал о них как о x и y ), обе изначально были пустыми. Затем мы неоднократно заменяем ( x , y ) на ( x , повернуть налево и двигаться вперед, y ) и ( x , повернуть направо и двигаться вперед, y ). После десяти итераций и x, и y содержат кривую дракона из девяти итераций.
Также есть несколько микро-оптимизаций и трюков, связанных с недогрузкой. Чтобы избежать излишней путаницы с вершиной стека, каждую итерацию цикла, мы начинаем с объединения x и y в функцию «вернуть строку, созданную путем конкатенации: x , инструкция поворота, аргумент функции, перемещение вперед инструкция, и у . " Эта функция занимает только один пробел в стеке, поэтому мы можем продублировать ее, вызвать ее
-90
в качестве аргумента, поменять местами возвращаемое значение в дубликате и вызвать его90
в качестве аргумента, чтобы получить новые значения для x и yбез необходимости касаться более двух верхних элементов стека (которые являются наиболее доступными). Эта функция генерируется кодом во время выполнения. Сам генератор также генерируется кодом во время выполнения, чтобы позволить ему повторно использовать строку,<g transform="translate
которая также используется для установки источника изображения. Сначала мы генерируем все открытые теги, а затем, поскольку все закрывающие теги являются справедливыми</g>
, мы можем вывести 1024 закрывающих тега, просто повторяя строку, не беспокоясь о сопоставлении их с открытыми тегами. (Эффективное написание чисел в недогрузке само по себе является интересной проблемой;(:*)::*:**:*
возможно, это самый эффективный способ написать 1024, переводя в «2 в степень (1 + 2 × 2) × 2»).Underload не имеет графических библиотек, поэтому я создаю SVG, используя комбинацию рисования линий в фиксированной позиции и поворачивая изображение вокруг заданной точки; вместо того, чтобы поворачивать ручку, мы поворачиваем бумагу. Идея состоит в том, что, рисуя линию, поворачивая все изображение, рисуя другую линию, снова поворачивая изображение и т. Д., Мы можем эффективно моделировать графику черепахи без необходимости арифметики или использования каких-либо графических библиотек, поскольку все линии нарисованы в том же месте. Конечно, это означает, что у нас есть очень сильно вложенные теги поворота изображения, что сбивает с толку многих зрителей SVG.
Стилизация изображения будет учитываться в счетчике байтов, поэтому мне нужно было указать минимальную стилизацию, необходимую для отображения изображения. Это оказывается
stroke="#"
, что более или менее переводится как «линия должна быть какого-то цвета»; это кажется расширенным, чтобы нарисовать это черным. (Обычно вы бы указали цвет, скажем, «# 000».) Фон по умолчанию прозрачный. Мы не указываем ширину обводки, но выбор, выбранный Eye of Gnome, оставляет все видимым.Многие интерпретаторы с недогрузкой борются с этой программой, например, программа Try It Online дает сбой, потому что она генерирует несколько очень больших строк внутри. Оригинальный переводчик Underload работает, хотя. (Интересно, что самый первый переводчик был в сети, поэтому язык можно было использовать в Интернете, прежде чем его можно было использовать в автономном режиме.)
Что-то, что меня немного беспокоит, так это то, что здесь только 1023 сегмента линии, и мы ожидаем 1024. Возможно, один из сегментов в конце не прорисован с помощью этого алгоритма (это будет на следующей итерации вместо). Если это дисквалифицирует, может быть возможно адаптировать программу, но она может закончиться значительно дольше. (Это не значит, что этот вызов все равно выиграет соревнование; уже есть несколько более коротких заявок.)
источник
MATL , 26 байт
Если приняты разные масштабы по двум осям, код можно уменьшить до 19 байт:
Приведенные ниже цифры соответствуют версии в 26-байтовом масштабе.
Приведенный выше код создает 9-ю (основанную на 0) итерацию, то есть десятое изображение в задании:
Для других значений измените значение
9
в коде или замените егоi
на число, введенное пользователем. Например, результат для13
:объяснение
При этом используется цикл для постепенного построения массива шагов, за которыми следует кривая в комплексной плоскости. Например, первые два шага
1j
(вверх) и-1
(слева).На каждой итерации массив шагов до сих пор копируется. Копия массива переворачивается , умножается на
1j
(для поворота на 90 градусов) и соединяется с оригиналом.После цикла накопленная сумма шагов дает действительные точки, которые затем наносятся на комплексную плоскость.
источник
Mathematica 86 байт
Как это работает:
{1,-1}
выходы{1,-1}
. Это в основном "толкает его в стек". Это значение может быть вызвано с помощью%
.r=Reverse
в основном просто переименовывает функцию Reverse, потому что я использую ее дважды в коде.Graphics@Line@
Просто принимает список точек и рисует линию , соединяющую их. Реальное мясо проблемы происходит в этом сегменте кода:Nest[Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&,{{0,0},%},9]
. Позвольте мне сказать вам - этот сегмент сложен как f ****** ск. Вот чтоNest
делает:Nest[f,x,9]
выводит результат вызоваf[f[f[f[f[f[f[f[f[x]]]]]]]]]
.В моем коде, это первый аргумент
f
является:Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&
вторым аргументомx
является{{0,0},%}
(который имеет значение{{0,0},{1,-1}}
), а третий аргументn
, который только 9 (который будет просто применить первый аргумент ко второму аргументу в 9 раз).Самая сложная часть всего этого - первый аргумент:
Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&
гигантский беспорядок из почти чистого синтаксического сахара. Я действительно злоупотреблял синтаксическим сахаром Mathematica для этого. Эта строка кода представляет версию анонимной функции Mathematica, за исключением того, что для сокращения вещей я фактически определил две отдельные анонимные функции в этой анонимной функции. Да, это законно, ребята. Давайте разберемся с этим.Join
принимает два аргумента. Первый естьl=Last@#;h=#-l&/@#
, а второй естьr[r@#%&/@h]
.Первый аргумент Join: внутри «основной» анонимной функции
#
- список всех точек на текущей итерации кривой. Такl=Last@#;
означает «Возьмите точку в списке точек, которые вы получили в качестве входных данных, и назначьте эту точку переменнойl
. Следующий сегментh=#-l&/@#
немного сложнее. Это означает:« У вас есть функция. Эта функция принимает точку в качестве входных данных, вычитаетl
из нее и возвращает результат. Теперь примените эту функцию к каждому элементу в списке точек, которые вы получили в качестве входных данных, чтобы создать список смещенных точек, и назначьте этот новый список переменнойh
.Второй аргумент Join:
r[r@#%&/@h]
буквально самый сложный синтаксис, который я когда-либо писал. Я не могу поверить, что любой сегмент кода может содержать что-то вроде@#%&/@
- похоже, я проклинаю как персонаж мультфильма в середине программы! Но это можно сломать. Помните -r[x]
берет список точек и возвращает этот список в обратном порядке.r@#%&
является анонимной функцией, которая инвертирует свой ввод, затем умножает его на значение, хранящееся в%
(что есть{1,-1}
), и возвращает результат. По сути, он поворачивает свои входные данные на 90 градусов, но в коде настолько коротком, насколько я мог бы написать. Затемr@#%&/@h
означает «Вывести новый список, каждая точка которогоh
повернута на 90 градусов».Таким образом, в целом,
Join[l=Last@#;h=#-l&/@#,r[r@#*%&/@h]]&
это функция, которая принимает список точек в качестве входных данных и добавляет к тому же списку точек, повернутых на 90 градусов, чтобы получить следующую итерацию кривой. Это повторяется 9 раз, чтобы получить кривую дракона. Затем это результирующий список точек рисуется на экране в виде линии. И вывод:источник
0{,}
... работает, потому что0 x
это0
почти для любогоx
и{,}
является синтаксическим сахаром для{Null,Null}
.Python 2, 43 байта
Этот ответ составляет 43 байта без учета оператора импорта, и в основном он основан на ответе логотипа Level River St и их использовании
i/(i&-i)
в коде. Попробуйте онлайн на trinket.ioВот картина выхода.
источник
The shortest code in bytes wins, however include directives for libraries shouldn't be included in the byte count, and you may use graphics libraries or other libraries written for your language of choice if they were written before the posting.
Mathematica,
5655 байтОбъяснение: OEIS A034947
Просто для удовольствия, вот цветная версия 19-й итерации.
источник
Mathematica, 63 байта
С помощью
AnglePath
источник
HTML + JavaScript, 182
источник
Haskell + диаграммы, 179 байт
Выходные данные - это SVG-файл шириной 99 пикселей с прозрачным фоном (изображение шириной 9 пикселей будет иметь слишком толстый штрих, чтобы что-либо пересчитать). Здесь он масштабируется и составляется на белом фоне:
источник
tosh , 518 байт
tosh - это Scratch , но с текстом вместо блоков. В 518 байт этот ответ, вероятно, даже хуже, чем Java.
Этот ответ использует ту же логику, что и и ответ @ Theo's Python , но со строками «L» и «R» вместо чисел, поскольку возможности списка Царапина (и, следовательно, tosh) ужасны.
Вы можете запустить его как Scratch проект здесь . (tosh компилируется в проекты Scratch)
Объяснение:
В этой первой части программа запускается при нажатии зеленого флажка (
when flag clicked
), задает для переменной пути значение «R» и возвращает спрайт и сцену в надлежащее состояние для подготовки к рисованию.Теперь перейдем к коду генерации пути. Он использует ту же логику, что и ответ @ Theo's Python , за исключением строк «R» и «L» вместо чисел, и мы используем вложенные циклы вместо списочных представлений.
Наконец, мы рисуем путь, проходя каждую букву переменной пути и поворачивая влево или вправо в зависимости от буквы.
источник