Dessinez une image d'art ASCII simple contenant une ligne droite. C'est similaire à ceci et cela mais avec des spécifications différentes.
Contribution
Vous pouvez modifier ce format d'entrée en fonction de votre code.
- entier
width
- entier
height
- entier
x0
- entier
y0
- entier
x1
- entier
y1
Production
Une image d'art ASCII remplie de la largeur et de la hauteur spécifiées contenant une ligne de pixel (x0, y0)
en pixel (x1, y1)
.
Toute forme standard de sortie de texte est acceptable, mais n'utilisez pas de fonctions de dessin au trait intégrées.
Détails
La ligne doit être dessinée en utilisant un seul caractère imprimable (comme #
), tandis que l'arrière-plan est rempli avec un caractère différent (comme .
). Vous devez imprimer les caractères de fin nécessaires pour que la taille de l'image soit correcte.
Les coordonnées des pixels peuvent être indexées 0 ou 1 et peuvent commencer dans n'importe quel coin de l'image. La ligne doit être dessinée en imaginant une ligne de sous-pixels de largeur 0 reliant les centres des pixels de début et de fin. Chaque pixel que la ligne entre doit être rempli.
Gagnant
Règles de code-golf habituelles. Le code le plus court gagne.
Exemples
IN: width, height, x0, y0, x1, y1
IN: 7, 6, 0, 0, 6, 5
OUT:
.....##
....##.
...##..
..##...
.##....
##.....
IN: 3, 3, 1, 1, 1, 1
OUT:
...
.#.
...
IN: 3, 3, 0, 2, 2, 0
OUT:
#..
.#.
..#
IN: 6, 3, 0, 0, 5, 2
OUT:
....##
.####.
##....
IN: 4, 4, -1, -1, 0, 3
OUT:
#...
#...
#...
....
Réponses:
Mathematica,
166137 octetsVersion plus lisible:
Cela définit une fonction appelée
f
. J'ai interprété les spécifications d'entrée et de sortie assez généreusement. La fonctionf
accepte les entrées au formatf[{x0, y0}, {x1, y1}, height, width]
et la grille est indexée 1, en commençant en haut à gauche. Les sorties ressemblentavec la ligne affichée en
1
s et l'arrière-plan en0
s (montré ici pourf[{2, 6}, {4, 2}, 5, 7]
). La tâche de transformer une matrice Mathematica de1
s et0
s en une chaîne de#
s et.
s a été jouée dans de nombreux autres défis auparavant, donc je pourrais simplement utiliser une méthode standard, mais je ne pense pas que cela ajoute quelque chose d'intéressant.Explication:
L'idée générale est que si la ligne passe par un pixel, alors au moins l'un des quatre coins du pixel est au-dessus de la ligne et au moins un est en dessous. Nous vérifions si un coin est au-dessus ou au-dessous de la ligne en examinant l'angle entre les vecteurs (
{x0,y0}
vers le coin) et ({x0,y0}
vers{x1,y1}
): si cet angle est positif, le coin est au-dessus et si l'angle est négatif, le coin est en dessous.Si nous avons deux vecteurs
{a1,b1}
et{a2,b2}
, nous pouvons vérifier si l'angle entre eux est positif ou négatif en trouvant le signe du déterminant de la matrice{{a1,b1},{a2,b2}}
. (Mon ancienne méthode pour ce faire utilisait l'arithmétique des nombres complexes, ce qui était trop… eh bien, complexe.)La façon dont cela fonctionne dans le code est la suivante:
{p-l+#,p-q}&/@Tuples[.5{1,-1},2]
obtient les quatre vecteurs de{x0,y0}
et les quatre coins du pixel (avecl:={i,j}
, les coordonnées du pixel, définies précédemment), ainsi que le vecteur entre{x0,y0}
et{x1,y1}
.s@Det@...
trouve les signes des angles entre la ligne et les quatre coins (en utilisants=Sign
). Ceux-ci seront égaux à -1, 0 ou 1.Abs@Mean[...]<.6
vérifie que certains angles sont positifs et certains négatifs. Les 4 tuples de signes qui ont cette propriété ont tous des moyennes comprises entre -0,5 et 0,5 (inclus), nous comparons donc à 0,6 pour enregistrer un octet en utilisant à la<
place de<=
.Il y a toujours un problème: ce code suppose que la ligne s'étend indéfiniment dans les deux sens. Nous devons donc recadrer la ligne en multipliant par
1-Max[s[p-l]s[q-l],0]
(trouvé par essais et erreurs), qui se trouve1
à l'intérieur du rectangle défini par les extrémités de la ligne, et à l'0
extérieur.Le reste du code fait une grille de ces pixels.
(En bonus, voici une tentative antérieure avec une méthode complètement différente, pour 181 octets :)
la source
CJam, 122 octets
Essayez-le en ligne
Cela combine essentiellement deux réponses que j'ai écrites précédemment pour d'autres défis (principalement les calculs de la 2ème fonction
l
).(0, 0) est naturellement le coin supérieur gauche, pas en bas à gauche comme les exemples de l'instruction.
Aperçu:
{),V>{[I\]E.*A.+}/}:F;
définit la fonction F qui permet de générer tous les pixels (paires de coordonnées) pour une coordonnée x donnéel~]2/~@:S~'.*f*\@:A.-_:g:E;:z:D
lit et traite l'entrée, et crée une matrice de points0=:B{D~I2*)*+:U(2/B/FU2/B/:V;}fI
itère sur toutes les coordonnées x sauf la dernière, et génère tous les pixels correspondantsD~\:I;F
fait de même pour la dernière coordonnée x{_Wf>\S.<+:*},
ne conserve que les pixels qui devraient apparaître à l'intérieur de l'image{~_3$=@0tt}/
met un 0 dans la matrice pour chaque pixelN*
rejoint la matrice avec des caractères de nouvelle ligne pour l'affichagela source