Una curva algebraica es un cierto "subconjunto 1D" del "plano 2D" que puede describirse como un conjunto de ceros {(x,y) in R^2 : f(x,y)=0 }
de un polinomio f
. Aquí consideramos el plano 2D como el plano real, de R^2
modo que podemos imaginar fácilmente cómo podría ser esa curva, básicamente algo que se puede dibujar con un lápiz.
Ejemplos:
0 = x^2 + y^2 -1
un círculo de radio 10 = x^2 + 2y^2 -1
una elipse0 = xy
una forma de cruz , básicamente la unión del eje x y el eje y0 = y^2 - x
una parábola0 = y^2 - (x^3 - x + 1)
una curva elíptica0 = x^3 + y^3 - 3xy
el folio de Descartes0 = x^4 - (x^2 - y^2)
un lemniscate0 = (x^2 + y^2)^2 - (x^3 - 3xy^2)
un trifolium0 = (x^2 + y^2 - 1)^3 + 27x^2y^2
un astroide
Tarea
Dado un polinomio f
(como se define a continuación) y los rangos x / y, genera una imagen en blanco y negro de al menos 100x100 píxeles que muestra la curva como una línea negra sobre un fondo blanco.
Detalles
Color : puede usar cualquiera de los otros dos colores de su elección, debería ser fácil distinguirlos.
Trama : en lugar de una imagen de píxeles, también puede mostrar esta imagen como un arte gráfico, donde los "píxeles" de fondo deben ser espacios / subrayados u otro carácter que "se vea vacío" y la línea puede estar hecha de un carácter que se vea " completo "como M
o X
o #
.
No tiene que preocuparse por los alias.
Solo necesita trazar líneas donde el signo del polinomio cambia de un lado a otro de la línea (eso significa que podría, por ejemplo, usar el algoritmo de cuadrado de marcha), no tiene que trazar correctamente "casos patológicos como 0 = x^2
donde lo hace el signo no cambia cuando va de un lado de la línea al otro, pero la línea debe ser continua y separar las regiones de los diferentes signos de f(x,y)
.
Polinomio : el polinomio se proporciona como una (m+1) x (n+1)
matriz / lista de listas de coeficientes (reales), en el siguiente ejemplo, los términos de los coeficientes se dan en su posición:
[ 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]
Si lo prefiere, puede suponer que la matriz es cuadrada (lo que siempre se puede hacer con el relleno de cero necesario), y si lo desea, también puede suponer que el tamaño de la matriz se da como entradas adicionales.
A continuación, los ejemplos de arriba se representan como una matriz definida así:
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]
Casos de prueba con rango x / rango y:
(En un formato no tan legible pero mejor para copiar y pegar disponible aquí en 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]
Tengo la inspiración para algunas curvas de este pdf.
m
xn
, sino(m+1)
x(n+1)
. ¿Qué tomamos como entrada:m, n
om+1,n+1
? ¿O podemos elegir?Respuestas:
Haskell,
283275 bytesLa función
g
debe llamarse con la matriz y los dos rangos como argumentos. La matriz es solo una lista de listas, los rangos son una lista de dos elementos.Aquí las salidas para los casos más interesantes: Tenga en cuenta que tuve que reducir el resultado de 100x100 a aproximadamente 40x40 para que quepa en la consola (simplemente cambie el 102 codificado a un número más pequeño). También tenga en cuenta que el eje y está apuntando hacia abajo.
fuente
$
para guardar un byte. Los dos lugares donde usamap
podrían estar(<$>)
, y dado que solo usae
una vez, puede extraer el(0<)
interior de su definición. Tambiéne
podría nombrarse(!)
para guardar 3 bytes.z
en la definición de lev
permite deshacerse de 4 paréntesis (alrededorz(&)
yf g
).#
de un solo carácter (por ejemplos
) y hacer que el ajuste de patrones en las listas en lugar deg
. (por ejemplos[a,b]=[a,a+(b-a)/102..b];g m u i=unlines$v[m!y<$>s u|y<-s i]
)Matlab,
11410092 bytes¿La herramienta adecuada para el trabajo? Utilizo la forma interesante que hace Matlab
printf
para generar un polinomio como una cadena. Este polinomio puede proporcionarse paraezplot
trazar la curva implícita en el dominio especificado. Para facilitar la lectura, el código se presenta con nuevas líneas después; que no es necesario y no se cuenta para el tamaño.El progreso del golf como fragmento expandible.
Mostrar fragmento de código
Salida de los casos de prueba (haga clic para una vista completa):
fuente
sprintf/ezplot
!fix
lugar defloor
podría ayudarlo a alcanzar el recuento de bytes de dos dígitos :-)[h,w]=size(A);t=0:h*w-1;
para guardar otros tres bytes!%.0f
. ¡Eso significa que puedo dejar caer el piso por completo y dejar que loprintf
arregle!Python 2, 261 bytes
Formato de entrada:
matrix,xbounds,ybounds
(p[[-1,0,1],[0,0,0],[1,0,0]],[-2,2],[-2,2]
. Ej .). Formato de salida: PGM simple .Esto estima la distancia desde cada centro de píxeles a la curva usando la aproximación de primer orden d ( x , y ) = | p ( x , y ) | / | ∇ p ( x , y ) |, donde ∇ p es el gradiente del polinomio p . (Esta es la distancia desde ( x , y ) a la intersección del plano tangente en ( x , y , p ( x , y )) con el plano xy .) Luego, los píxeles donde d (x , y) tiene menos de un ancho de píxel de la curva proporcionalmente a d ( x , y ), lo que da como resultado bonitas líneas antialias (aunque eso no es un requisito).
Aquí están los mismos gráficos con la función de distancia dividida por 16 para hacerla visible.
fuente
print
declaración para el encabezado de la imagen y unaprint
declaración en elwhile
bucle para el valor de cada píxel.Python 3.5 + MatPlotLib + Numpy, 352 bytes:
Una función con nombre. Bastante largo, pero bueno, estoy feliz de haber podido realizar la tarea. Toma 3 entradas, que son la
m by n
matriz, elx
rango y ely
rango, que deberían estar en matrices (por ejemplo,[[-1,0,1],[0,0,0],[1,0,0]],[-2,2],[-2,2]
). Emite el gráfico completado en una nueva ventana gráfica e interactiva. Jugaré golf más tiempo cuando pueda, pero por ahora, estoy contento con eso.Salidas finales para los casos de prueba:
fuente
MATL ,
6761 bytesEste código se ejecuta en la versión 18.5.0 del lenguaje, que precede al desafío. De entrada utiliza el programa opcional
m
,n
parámetros. La matriz tiene punto y coma como separadores de fila. El formato de entrada exacto (usando la parábola como ejemplo) esEl código produce una imagen con un tamaño de 255 × 255. Esto se puede probar usando @Suever 's MAT línea compilador, que, entre otras características muy interesantes, incluye la salida gráfica. Ver por ejemplo
Este compilador todavía está en una etapa experimental. Informe cualquier problema a @Suever en la sala de chat de MATL . Si el botón "Ejecutar" no funciona, intente actualizar la página y haga clic nuevamente.
Si prefiere la salida ASCII , el código debe modificarse un poco (los cambios solo afectan los primeros dos y los últimos cuatro caracteres del código anterior):
Esto produce una cuadrícula ASCII de 100 × 100 que usa caracteres
*
para representar la curva. También puedes probar esto con @Dennis '¡ Pruébalo en línea! plataforma:Tenga en cuenta que la relación de aspecto de la salida ASCII se modifica porque los caracteres son ligeramente más altos que anchos.
Explicación
El código primero calcula el polinomio de dos variables en una cuadrícula x - y . Esto hace un uso intensivo de la transmisión , computando una matriz 4D intermedia donde cada dimensión representa valores de x , valores y , exponentes x , y exponentes respectivamente.
A partir de esa función, se calcula la línea de nivel cero. Dado que el desafío especifica que solo se deben detectar cambios en los signos, se aplica el código convolución 2D con un bloque de 2 × 2 y marca un píxel como perteneciente a la línea si no los cuatro valores del bloque tienen el mismo signo.
Todos los casos de prueba
Aquí están todas las entradas en el formato apropiado, en caso de que desee probar:
fuente