Алгебраическая кривая - это некое «1D подмножество» «2D-плоскости», которое можно описать как набор нулей {(x,y) in R^2 : f(x,y)=0 }
полинома f
. Здесь мы рассматриваем 2D-плоскость как реальную плоскость R^2
, так что мы можем легко представить, как могла бы выглядеть такая кривая, в основном то, что можно нарисовать карандашом.
Примеры:
0 = x^2 + y^2 -1
круг радиуса 10 = x^2 + 2y^2 -1
эллипс0 = xy
крест форма, в основном , объединение оси абсцисс и ось ординат0 = y^2 - x
парабола0 = y^2 - (x^3 - x + 1)
эллиптической кривой0 = x^3 + y^3 - 3xy
лист Декарта0 = x^4 - (x^2 - y^2)
лемниската0 = (x^2 + y^2)^2 - (x^3 - 3xy^2)
трифолиум0 = (x^2 + y^2 - 1)^3 + 27x^2y^2
астроид
задача
Учитывая полином f
(как определено ниже) и диапазоны x / y, выведите черно-белое изображение размером не менее 100x100 пикселей, которое показывает кривую в виде черной линии на белом фоне.
Детали
Цвет : Вы можете использовать любые два других цвета по вашему выбору, их будет легко отличить друг от друга.
Сюжет : вместо пиксельного изображения вы также можете вывести это изображение как ascii-art, где фоновые «пиксели» должны быть пробелом / подчеркиванием или другим символом, который «выглядит пустым», а линия может быть сделана из символа, который выглядит » полный "нравится M
или X
или #
.
Вам не нужно беспокоиться о псевдонимах.
Вам нужно только построить линии, в которых знак полинома меняется с одной стороны линии на другую (это означает, что вы можете, например, использовать алгоритм квадрата шествия), вам не нужно правильно изображать «патологические случаи, например, 0 = x^2
когда знак меняет». не меняется при переходе с одной стороны линии на другую, но линия должна быть непрерывной и разделяющей области разных признаков f(x,y)
.
Полиномиальной : Полином задаются в виде (m+1) x (n+1)
матрицы / список списков (действительные) коэффициентов, в примере ниже терминов коэффициентов приведены в своей позиции:
[ 1 * 1, 1 * x, 1 * x^2, 1 * x^3, ... , 1 * x^n ]
[ y * 1, y * x, y * x^2, y * x^4, ... , y * x^n ]
[ ... , ... , ... , ... , ... , ... ]
[ y^m * 1, y^m * x, y^m * x^2, y^m * x^3 , ..., y^m * x^n]
Если вы предпочитаете, вы можете считать матрицу квадратной (что всегда можно сделать с необходимым заполнением нулями), и, если хотите, вы также можете предположить, что размер матрицы указан в качестве дополнительных входных данных.
Далее приведенные выше примеры представлены в виде матрицы, определенной следующим образом:
Circle: Ellipse: Parabola: Cross: Elliptic Curve: e.t.c
[-1, 0, 1] [-1, 0, 1] [ 0,-1] [ 0, 0] [-1, 1, 0,-1]
[ 0, 0, 0] [ 0, 0, 0] [ 0, 0] [ 0, 1] [ 0, 0, 0, 0]
[ 1, 0, 0] [ 2, 0, 0] [ 1, 0] [ 1, 0, 0, 0]
Тестовые случаи с x-range / y-range:
(В не очень удобочитаемом, но лучше копируемо-способном формате, доступном здесь, на pastebin .)
Circle:
[-1, 0, 1] [-2,2] [-2,2]
[ 0, 0, 0]
[ 1, 0, 0]
Ellipse:
[-1, 0, 1] [-2,2] [-1,1]
[ 0, 0, 0]
[ 2, 0, 0]
Cross:
[ 0, 0] [-1,2] [-2,1]
[ 0, 1]
Parabola:
[ 0,-1] [-1,3] [-2,2]
[ 0, 0]
[ 1, 0]
Elliptic Curve:
[-1, 1, 0,-1] [-2,2] [-3,3]
[ 0, 0, 0, 0]
[ 1, 0, 0, 0]
Folium of Descartes:
[ 0, 0, 0, 1] [-3,3] [-3,3]
[ 0, -3, 0, 0]
[ 0, 0, 0, 0]
[ 1, 0, 0, 0]
Lemniscate:
[ 0, 0, -1, 0, 1] [-2,2] [-1,1]
[ 0, 0, 0, 0, 0]
[ 1, 0, 0, 0, 0]
Trifolium:
[ 0, 0, 0,-1, 1] [-1,1] [-1,1]
[ 0, 0, 0, 0, 0]
[ 0, 3, 2, 0, 0]
[ 0, 0, 0, 0, 0]
[ 1, 0, 0, 0, 0]
Astroid:
[ -1, 0, 3, 0, -3, 0, 1] [-1,1] [-1,1]
[ 0, 0, 0, 0, 0, 0, 0]
[ 3, 0, 21, 0, 3, 0, 0]
[ 0, 0, 0, 0, 0, 0, 0]
[ -3, 0, 3, 0, 0, 0, 0]
[ 0, 0, 0, 0, 0, 0, 0]
[ 1, 0, 0, 0, 0, 0, 0]
У меня есть вдохновение для некоторых кривых из этого PDF.
m
хn
, а(m+1)
х(n+1)
. Что мы берем в качестве входных данных:m, n
илиm+1,n+1
? Или мы можем выбрать?Ответы:
Haskell,
283275 байтФункция
g
должна вызываться с матрицей и двумя диапазонами в качестве аргументов. Матрица - это просто список списков, каждый из которых представляет собой список из двух элементов.Вот результаты для более интересных случаев: обратите внимание, что мне пришлось уменьшить размер результата с 100x100 до 40x40, чтобы он вписался в консоль (просто измените жестко закодированный 102 на меньшее число). Также обратите внимание, что ось Y направлена вниз.
источник
$
для сохранения байта. Оба места, где вы используете,map
могут быть(<$>)
, и так как вы используете толькоe
один раз, вы можете вытащить(0<)
изнутри его определение. Такжеe
может быть названо,(!)
чтобы сохранить 3 байта.z
в определенииv
позволяет избавиться от 4 скобок (вокругz(&)
иf g
).#
в один символ (напримерs
) и использовать его в списках вместоg
. (напримерs[a,b]=[a,a+(b-a)/102..b];g m u i=unlines$v[m!y<$>s u|y<-s i]
)Matlab,
11410092 байтаПравильный инструмент для работы? Я использую интересный способ, который Matlab использует
printf
для генерации полинома в виде строки. Этот многочлен может быть представлен для того, чтобыezplot
построить неявную кривую в указанной области. Для удобства чтения код представлен после новой строки; который не нужен и не учитывается в размере.Гольф прогресс как расширяемый фрагмент.
Показать фрагмент кода
Вывод тестовых случаев (нажмите для полного просмотра):
источник
sprintf/ezplot
!fix
вместоfloor
может помочь вам достичь двухзначного числа байтов :-)[h,w]=size(A);t=0:h*w-1;
чтобы сохранить еще три байта!%.0f
. Это означает, что я могу полностью уронить пол и позволитьprintf
его починить!Python 2, 261 байт
Формат ввода:
matrix,xbounds,ybounds
(например[[-1,0,1],[0,0,0],[1,0,0]],[-2,2],[-2,2]
). Выходной формат: обычный PGM .Это оценивает расстояние от каждого центра пикселя до кривой, используя приближение первого порядка d ( x , y ) = | p ( x , y ) | / | ∇ p ( x , y ) |, где ∇ p - градиент многочлена p . (Это расстояние от ( x , y ) до пересечения касательной плоскости в точке ( x , y , p ( x , y )) с плоскостью xy .) Тогда пиксели, где d ( x , y ) меньше ширины кривой на один пиксель пропорционально d ( x , y ), что приводит к хорошим сглаженным линиям (даже если это не является обязательным требованием).
Вот же графики с функцией расстояния, разделенной на 16, чтобы сделать ее видимой.
источник
print
оператор для заголовка изображения и одинprint
оператор вwhile
цикле для значения каждого пикселя.Python 3.5 + MatPlotLib + Numpy, 352 байта:
Именованная функция. Довольно долго, но эй, я просто счастлив, что смог выполнить задачу. Принимает 3 входа, которые представляют собой
m by n
матрицу,x
-range иy
-range, которые все должны быть в массивах (например,[[-1,0,1],[0,0,0],[1,0,0]],[-2,2],[-2,2]
). Выводит заполненный график в новом графическом интерактивном окне. Буду ли это играть в гольф больше времени, когда смогу, но сейчас я доволен этим.Окончательные результаты для тестовых случаев:
источник
MATL ,
6761 байтЭтот код запускается в версии 18.5.0 языка, который предшествует вызову. Input использует Факультативный
m
,n
параметры. Матрица имеет точки с запятой в качестве разделителей строк. Точный формат ввода (используя параболу в качестве примера)Код производит изображение размером 255 × 255. Это можно проверить с помощью @Suever 's MATL Online компилятора, который, помимо других очень интересных функций, включает графический вывод. Смотри например
Этот компилятор все еще находится в экспериментальной стадии. Пожалуйста, сообщайте о любых проблемах @Suever в чате MATL . Если кнопка «Выполнить» не работает, попробуйте обновить страницу и нажать снова.
Если вы предпочитаете вывод ASCII , код необходимо немного изменить (изменения коснутся только первых двух и последних четырех символов кода выше):
Это создает сетку 100 × 100 ASCII, которая использует символ
*
для представления кривой. Вы также можете проверить это с @Dennis ' Попробуйте онлайн! Платформа:Обратите внимание, что соотношение сторон вывода ASCII изменяется, потому что символы немного выше, чем широкие.
объяснение
Сначала код вычисляет полином от двух переменных на сетке x - y . Это интенсивно использует широковещание , вычисляя промежуточный 4D массив, где каждое измерение представляет x значений, значений y , показателей x , y показателей соответственно.
Из этой функции вычисляется линия нулевого уровня. Поскольку задача указывает, что необходимо обнаруживать только изменения знака, код применяет двухмерную свертку с блоком единиц 2 × 2 и помечает пиксель как принадлежащий линии, если не четыре значения блока имеют одинаковый знак.
Все тесты
Вот все входные данные в соответствующем формате, если вы хотите попробовать:
источник