Une courbe algébrique est un certain "sous-ensemble 1D" du "plan 2D" qui peut être décrit comme un ensemble de zéros {(x,y) in R^2 : f(x,y)=0 }
d'un polynôme f
. Ici, nous considérons le plan 2D comme le vrai plan de R^2
sorte que nous pouvons facilement imaginer à quoi pourrait ressembler une telle courbe, essentiellement une chose que vous pouvez dessiner avec un crayon.
Exemples:
0 = x^2 + y^2 -1
un cercle de rayon 10 = x^2 + 2y^2 -1
une ellipse0 = xy
une forme de croix , essentiellement l'union de l'axe des x et de l'axe des y0 = y^2 - x
une parabole0 = y^2 - (x^3 - x + 1)
une courbe elliptique0 = x^3 + y^3 - 3xy
le folium 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 astroïde
Tâche
Étant donné un polynôme f
(tel que défini ci-dessous) et les gammes x / y, produire une image en noir et blanc d'au moins 100x100 pixels qui montre la courbe sous forme de ligne noire sur fond blanc.
Détails
Couleur : Vous pouvez utiliser deux autres couleurs de votre choix, il devrait être facile de les distinguer.
Graphique : Au lieu d'une image en pixels, vous pouvez également produire cette image en tant qu'ascii-art, où les "pixels" d'arrière-plan doivent être des espaces / soulignements ou un autre caractère qui "semble vide" et la ligne peut être faite d'un caractère qui ressemble " plein "comme M
ou X
ou #
.
Vous n'avez pas à vous soucier de l'alias.
Vous avez seulement besoin de tracer des lignes où le signe du polynôme change d'un côté à l'autre de la ligne (cela signifie que vous pouvez par exemple utiliser l'algorithme du carré de marche), vous n'avez pas à tracer correctement "les cas pathologiques comme 0 = x^2
où le signe fait ne pas changer en allant d'un côté à l'autre de la ligne. Mais la ligne doit être continue et séparer les régions des différents signes de f(x,y)
.
Polynôme : Le polynôme est donné sous forme de (m+1) x (n+1)
matrice / liste de listes de coefficients (réels), dans l'exemple ci-dessous les termes des coefficients sont donnés dans leur position:
[ 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 vous préférez, vous pouvez supposer que la matrice est carrée (ce qui peut toujours être fait avec le remplissage nul nécessaire), et si vous le souhaitez, vous pouvez également supposer que la taille de la matrice est donnée comme entrées supplémentaires.
Dans ce qui suit, les exemples ci-dessus sont représentés comme une matrice définie comme ceci:
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]
Cas de test avec plage x / plage y:
(Dans un format pas tellement lisible mais meilleur copier-coller disponible ici sur 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]
J'ai eu l'inspiration pour quelques courbes de ce pdf.
m
xn
, mais(m+1)
x(n+1)
. Que prenons-nous comme entrée:,m, n
oum+1,n+1
? Ou pouvons-nous choisir?Réponses:
Haskell,
283275octetsLa fonction
g
doit être appelée avec la matrice et les deux plages comme arguments. La matrice n'est qu'une liste de listes, les plages chacune une liste de deux éléments.Voici les sorties pour les cas les plus intéressants: Notez que j'ai dû réduire la résultante de 100x100 à environ 40x40 de sorte qu'elle s'insère dans la console (changez simplement le 102 codé en dur en un nombre plus petit). Notez également que l'axe des y pointe vers le bas.
la source
$
pour enregistrer un octet. Les deux endroits où vous utilisezmap
pourraient être(<$>)
, et puisque vous n'utilisez qu'unee
fois que vous pouvez tirer à l'(0<)
intérieur, c'est sa définition.e
Peut également être nommé(!)
pour économiser 3 octets.z
dans la définition dev
vous permet de vous débarrasser de 4 parenthèses (autourz(&)
etf g
).#
un seul caractère (par exemples
) et le faire correspondre au modèle sur les listes au lieu deg
. (par exemples[a,b]=[a,a+(b-a)/102..b];g m u i=unlines$v[m!y<$>s u|y<-s i]
)Matlab,
11410092 octetsLe bon outil pour le travail? J'utilise la manière intéressante que Matlab fait
printf
pour générer un polynôme sous forme de chaîne. Ce polynôme peut être fourni pourezplot
tracer la courbe implicite sur le domaine spécifié. Pour plus de lisibilité, le code est présenté avec des nouvelles lignes après; ce qui n'est pas nécessaire et n'est pas pris en compte dans la taille.Progression du golf sous forme d'extrait extensible.
Afficher l'extrait de code
Sortie des cas de test (cliquez pour une vue complète):
la source
sprintf/ezplot
!fix
au lieu defloor
pourrait vous aider à atteindre le nombre d'octets à deux chiffres :-)[h,w]=size(A);t=0:h*w-1;
pour enregistrer trois autres octets!%.0f
. Cela signifie que je peux laisser tomber le plancher et leprintf
réparer!Python 2, 261 octets
Format d'entrée:
matrix,xbounds,ybounds
(par exemple[[-1,0,1],[0,0,0],[1,0,0]],[-2,2],[-2,2]
). Format de sortie: PGM ordinaire .Cela estime la distance entre chaque centre de pixels et la courbe en utilisant l'approximation de premier ordre d ( x , y ) = | p ( x , y ) | / | ∇ p ( x , y ) |, où ∇ p est le gradient du polynôme p . (Il s'agit de la distance entre ( x , y ) et l'intersection du plan tangent en ( x , y , p ( x , y )) avec le plan xy .) Puis les pixels où x , d (y ) est inférieure à une largeur de pixel de la courbe proportionnellement à d ( x , y ), résultant en de belles lignes anti-crénelées (même si ce n'est pas une exigence).
Voici les mêmes graphiques avec la fonction de distance divisée par 16 pour la rendre visible.
la source
print
déclaration pour l'en-tête de l'image et uneprint
déclaration dans lawhile
boucle pour la valeur de chaque pixel.Python 3.5 + MatPlotLib + Numpy, 352 octets:
Une fonction nommée. Assez longtemps, mais bon, je suis juste content d'avoir pu accomplir la tâche. Prend 3 entrées, qui sont la
m by n
matrice, lax
plage et lay
plage, qui doivent toutes être dans des tableaux (par exemple,[[-1,0,1],[0,0,0],[1,0,0]],[-2,2],[-2,2]
). Affiche le graphique terminé dans une nouvelle fenêtre graphique interactive. Va jouer au golf plus longtemps quand je peux, mais pour l'instant, j'en suis content.Sorties finales pour les cas de test:
la source
MATL ,
6761 octetsCe code s'exécute dans la version 18.5.0 du langage, qui précède le défi. L'entrée utilise l'option
m
, lesn
paramètres. La matrice a des points-virgules comme séparateurs de lignes. Le format d'entrée exact (en utilisant la parabole comme exemple) estLe code produit une image de taille 255 × 255. Cela peut être testé en utilisant @Suever de » MATL en ligne compilateur, qui, entre autres fonctions très intéressantes, comprend la production graphique. Voir par exemple
Ce compilateur est encore à un stade expérimental. Veuillez signaler tout problème à @Suever dans le salon de discussion MATL . Si le bouton "Exécuter" ne fonctionne pas, essayez d'actualiser la page et de cliquer à nouveau.
Si vous préférez la sortie ASCII , le code doit être légèrement modifié (les changements n'affectent que les deux premiers et les quatre derniers caractères du code ci-dessus):
Cela produit une grille ASCII 100 × 100 qui utilise des caractères
*
pour représenter la courbe. Vous pouvez également tester cela avec @Dennis ' Essayez-le en ligne!Plate-forme:Notez que le rapport d'aspect de la sortie ASCII est modifié car les caractères sont légèrement plus élevés que larges.
Explication
Le code calcule d'abord le polynôme à deux variables sur une grille x - y . Cela fait un usage intensif de la radiodiffusion , en calculant un tableau 4D intermédiaire où chaque dimension représente x valeurs, valeurs y , x exposants, y exposants.
À partir de cette fonction, la ligne de niveau zéro est calculée. Étant donné que le défi spécifie que seuls les changements de signe doivent être détectés, le code applique une convolution 2D avec un bloc de 2 × 2 et marque un pixel comme appartenant à la ligne sinon les quatre valeurs du bloc ont le même signe.
Tous les cas de test
Voici toutes les entrées au format approprié, au cas où vous voudriez essayer:
la source