Petit Chandler est triste. Dessine-lui un nuage pour lui remonter le moral

57

Petit Chandler est triste. Dessine-lui un nuage pour lui remonter le moral.
Remarque: dessiner un nuage ne l'encouragera pas.

Un cercle peut être défini comme un triplet (x,y,r)xest la position x du cercle sur un plan cartésien, yla position y du cercle sur un plan cartésien et rle rayon du cercle. xet ypeut être négatif. rest toujours positif. L'entrée est une liste de cercles sous la forme de 3-tuples séparés par des espaces. Par exemple:

3,1,1 3,2,1.5 1,2,0.7 0.9,1.2,1.2 1,0,0.8

Les 3,1,1moyens "Un cercle avec un point central 3,1avec un rayon. 3,2,1.5Signifie" Un cercle avec un point central 3,2avec un rayon de 1,5.

Si nous traçons tous ces cercles de l'entrée sur un graphique, cela ressemble à ceci (j'ai inclus des lignes de grille et des étiquettes pour plus de clarté; elles ne sont pas obligatoires):

Graphique

Remarquez comme tous les cercles sont cohésifs . C'est-à-dire qu'ils se chevauchent tous de telle sorte qu'ils forment un grand groupe sans petits groupes de cercles séparés du reste. L'entrée est garantie d'être cohésive.

Supposons maintenant que nous traçons une ligne qui contourne la "frontière" formée par ces cercles, sans aucune des autres lignes. Ce serait comme dessiner la bordure de la silhouette formée par tous les cercles. Le nuage résultant ressemblerait à ceci:

nuage

Donc, ce nuage a été formé en ne dessinant que les arcs de cercle de l’entrée qui forment une bordure, ce qui donne une forme unique. En d'autres termes, le nuage est formé en dessinant uniquement les arcs qui ne se trouvent pas dans un autre cercle. Votre programme prendra en entrée sous la forme expliquée ci-dessus et produira une image qui affiche le nuage obtenu. La forme générale du nuage doit être correcte, mais l’échelle, la couleur, l’épaisseur de trait et son apparence aux sommets dépendent de vous. Notez que le nuage doit être visible, vous ne pouvez donc pas tirer quelque chose comme "Ce programme dessine un nuage blanc sur un fond blanc", "Ce programme dessine un nuage à une échelle infiniment petite", "Ce programme dessine un nuage avec 0 épaisseur de trait ", etc. Notez également que la couleur de la bordure doit être différente de celle du remplissage ou de l'arrière-plan.

Un autre exemple. Contribution:

1,4,2 5,2,1 3,1,1 3.5,2,1.2 3,3,0.7 1,2,0.7

Sortie:

cloud2

S'il y a un "trou" dans le nuage, vous devez également dessiner le trou. Contribution:

0,5,4 3,4,4 4,3,4 5,0,4 4,-3,4 3,-4,4 0,-5,4 -3,-4,4 -4,-3,4 -5,0,4 -4,3,4 -3,4,4 

Sortie:

cloud3

Voici une règle importante: votre programme ne doit dessiner que les lignes qui forment la bordure. Cela signifie que vous NE POUVEZ PAS simplement dessiner complètement les cercles, puis dessiner les cercles légèrement plus petits avec un remplissage blanc - parce que cette méthode dessine toujours des lignes qui ne forment pas de bordure, elle les recouvre ensuite. Le but de la règle était d'empêcher les implémentations de "dessiner les cercles, puis de dessiner les cercles avec un remplissage blanc", ou quelque chose de ce genre. On s'attend à ce que la réponse calcule réellement où dessiner les choses avant de les dessiner.

C'est le code de golf, donc le plus petit nombre de personnages gagne.

Absinthe
la source
13
+1 pour une question à sortie graphique avec un critère objectif gagnant (et le premier paragraphe).
Dennis
2
Comment pouvez-vous savoir si nous traçons une ligne et l'effacons ensuite? Le rendu desdites lignes sur des bitmaps internes est-il correct? Si non, où est la frontière entre un vecteur et une représentation bitmap? Si oui, pourquoi ne pas en faire de même avec le canevas principal (nous savons qu’il utilise une double mémoire tampon, de sorte que l’utilisateur ne puisse pas voir nos lignes temporaires)?
John Dvorak
1
@JanDvorak Le but de la règle était d'empêcher "d'implémenter les cercles, puis de dessiner à nouveau les cercles avec un remplissage blanc", ou quelque chose de similaire. On s'attend à ce que la réponse calcule réellement dessiner les choses avant de les dessiner. Je vais éditer pour le rendre plus clair.
absinthe
15
Cette question est absolument hilarante avec Cloud to Butt ( chrome.google.com/webstore/detail/cloud-to-butt-plus/… ) installé.
Erty Seidohl
9
@SomeKittens Je l'ai perdu à "S'il y a un" trou "dans le nuage, vous devez également dessiner le trou."
Erty Seidohl

Réponses:

25

Mathematica 177 126 121 119

Résolution par régions de disques: l'approche du mathématicien

La logique est de

  • Créez la région 1 (R1), les cercles (sans leurs intérieurs);
  • Créez la région 2 (R2), les disques (sans les bordures de cercle).
  • Créez la région 3 (R3 = R1-R2).
  • -

inférence de région

C'est précisément l'approche adoptée ci-dessous. Il a produit les 3 chiffres ci-dessus.

input = "3,1,1 3,2,1.5 1,2,0.7 0.9,1.2,1.2 1,0,0.8";
circles = ((x - #)^2 + (y - #2)^2 == #3^2) & @@@ 
     ToExpression[#~StringSplit~","] &@(StringSplit@input);
R1 = ImplicitRegion[Or @@ circles, {x, y}];
r1 = RegionPlot[R1, PlotLabel -> "R1: circles containing borders", 
   AspectRatio -> 1, PlotRange -> {{-1, 5}, {-1, 5}}];

innerDisks = ((x - #)^2 + (y - #2)^2 < #3^2) & @@@ 
     ToExpression[#~StringSplit~","] &@(StringSplit@input);
R2 = ImplicitRegion[Or @@ innerDisks, {x, y}];
r2 = RegionPlot[R2, PlotLabel -> "R2: disks within circle borders", 
   AspectRatio -> 1, PlotRange -> {{-1, 5}, {-1, 5}}];
R3 = RegionDifference[R1, R2]
r3 = RegionPlot[R3, PlotLabel -> "R3 = R1-R2", AspectRatio -> 1, 
   PlotRange -> {{-1, 5}, {-1, 5}}];
GraphicsGrid[{{r1, r2, r3}}, ImageSize -> 600]

La région implicite n ° 1 est l'union des cercles. La région implicite n ° 2 est l'union des disques situés dans les cercles. Leur différence est la frontière.

RegionDifference [
ImplicitRegion [(- - 3 + x) ^ 2 + (-1 + y) ^ 2 == 1 || (-3 + x) ^ 2 + (-2 + y) ^ 2 == 2,25 || (-1 + x) ^ 2 + (-2 + y) ^ 2 == 0,49 || (-0,9 + x) ^ 2 + (-1,2 + y) ^ 2 == 1,44 || (-1 + x) ^ 2 + y ^ 2 == 0,64, {x, y}],
Région implicite [(- - 3 + x) ^ 2 + (-1 + y) ^ 2 <1 || (-3 + x) ^ 2 + (-2 + y) ^ 2 <2,25 || (-1 + x) ^ 2 + (-2 + y) ^ 2 <0.49 || (-0.9 + x) ^ 2 + (-1.2 + y) ^ 2 <1.44 || (-1 + x) ^ 2 + y ^ 2 <0.64, {x, y}]]


Résolution par régions de disques: l'approche de l'ingénieur (119 caractères)

Ce qui suit prend l'union des régions du disque, discrétise cette région et trouve sa limite. Les points du diagramme délimitent les intervalles du maillage de Delaunay. Nous affichons la région discrétisée ci-dessous pour mettre en évidence l'objet qui fournit la limite d'intérêt (le contour du nuage).

s = StringSplit;RegionBoundary@DiscretizeRegion[RegionUnion[Disk[{#, #2}, #3] &@@@
ToExpression[#~s~","] &@(s@InputString[])]]

"3,1,1 3,2,1.5 1,2,0,7 0,9,1.2,1.2 1,0,0.8"

La limite de région est discrétisée.

reg1


Résoudre en détectant les bords: l'approche du photographe - 121 caractères

détection de bord

Il dessine les disques en noir, pixellise l'image, détecte les bords et inverse le noir et le blanc.

s=StringSplit;ColorNegate@EdgeDetect@Rasterize@Graphics[Disk[{#,#2},#3]&@@@
((ToExpression/@s[#,","])&/@s[InputString[]])]
DavidC
la source
Rasé 5 octets:RegionBoundary@DiscretizeRegion@RegionUnion[{#,#2}~Disk~#3&@@@ToExpression[#~s~","]&@s@InputString[s=StringSplit]]
Martin Ender
Potentiellement l' s=StringSplitintérieur de l'invite? Essayez de déplacer cela à nouveau devant, devrait toujours être plus courte que votre version actuelle.
Martin Ender le
27

T-SQL 235 234 229 212 171 73 octets

Cela utilise les fonctionnalités spatiales dans SQL Server 2012+. Lorsqu'il est exécuté dans SSMS (SQL Server Management Studio), il génère un volet de résultats spatiaux. L'entrée provient de la variable @i. Je pourrais le réduire davantage si les données pouvaient être extraites d'un tableau.

Depuis l'entrée de table est maintenant autorisée.

SELECT Geometry::UnionAggregate(Geometry::Point(X,Y,0).STBuffer(R))FROM A

J'ai laissé la solution précédente ci-dessous.

DECLARE @ VARCHAR(999)='WITH a AS(SELECT *FROM(VALUES('+REPLACE(@i,' ','),(')+'))A(X,Y,R))SELECT Geometry::UnionAggregate(Geometry::Point(X,Y,0).STBuffer(R))FROM a'EXEC(@)

Edit : Supprimer l'espace parasite, le surplus dans et une sous-requête

171: Création de la table remplacée par CTE et @s par @.

entrez la description de l'image ici

Décomposition du SQL dynamique

DECLARE @i VARCHAR(100) = '1,4,2 5,2,1 3,1,1 3.5,2,1.2 3,3,0.7 1,2,0.7' -- Input
DECLARE @ VARCHAR(999) = '
WITH a AS(                                       --CTE to produce rows of x,y,r 
    SELECT *FROM(VALUES('+
        REPLACE(@i,' ','),(')                    --Format @i to a value set
        +'))A(X,Y,R)
)
SELECT Geometry::UnionAggregate(                 --Aggregate Buffered Points
    Geometry::Point(X,Y,0).STBuffer(R)           --Create point and buffer
    )               
FROM a                                           --from the table variable
'
EXEC(@)                                          --Execute Dynamic sql
MickyT
la source
Je reçois une erreur en disant'A' has fewer columns than were specified in the column list
Jesan Fafon le
@JesanFafon Assurez-vous que votre variable d'entrée @i est définie correctement. DECLARE @i VARCHAR(100) = '1,4,2 5,2,1 3,1,1 3.5,2,1.2 3,3,0.7 1,2,0.7'. Malheureusement, je ne peux pas tester en ce moment et SQLfiddle ne joue pas bien pour 2012.
MickyT
Beau travail avec les fonctions de géométrie SQL. Bonnes nouvelles! La saisie par table préexistante est maintenant explicitement autorisée . La création de table et la population ne doivent pas nécessairement être incluses dans le nombre d'octets.
BradC
J'ai joué au golf quelques personnages. Le lien ne produit pas de résultat. Mais cela fonctionne dans le studio de gestion de serveur ms-sql. Le script est ici , profitez-en. N'hésitez pas à l'utiliser
t-clausen.dk
@ t-clausen.dk merci pour cela, mais comme je vais le mettre à jour, je le changerai en entrée de table autorisée. Je
n'allais
23

Mathematica, 175 158 149 octets

s=StringSplit;l=ToExpression[#~s~","]&@s@InputString[];RegionPlot[Or@@(Norm@{x-#,y-#2}<#3&@@@l),{x,m=Min@(k={{##}-#3,{##}+#3}&@@@l),M=Max@k},{y,m,M}]

Je me souviens de la discussion dans le bac à sable que cette approche était supposée être valide, mais je ne suis pas tout à fait sûr de la façon dont elle correspond à la nouvelle formulation des règles, alors @ Lilac, faites-moi savoir si vous pensez que cela enfreint les règles.

Fondamentalement, je crée une condition logique qui est vraie pour tous les points à l'intérieur du nuage et fausse pour tous les points en dehors de celui-ci. Je nourris ce à RegionPlotquoi rend ensuite la région de tous les points où l'expression est Trueainsi qu'un contour autour de lui.

entrez la description de l'image ici

Ungolfed:

s = StringSplit;
l = ToExpression[#~s~","] &@s@InputString[];
RegionPlot[
 Or @@ (Norm@{x - #, y - #2} < #3 & @@@ l), 
 {x, m = Min@(k = {{##} - #3, {##} + #3} & @@@ l), M = Max@k},
 {y, m, M}
]
Martin Ender
la source
1
ImplicitRegiontrouve automatiquement les valeurs x et y appropriées pour le traçage. 122 caractères:s = StringSplit; RegionPlot@ ImplicitRegion[ Or @@ (((x - #)^2 + (y - #2)^2 < #3^2) & @@@ (ToExpression[#~s~","] &@(s@InputString[]))), {x, y}]
DavidC
@DavidCarraher Malheureusement, cela déforme le rapport de format de l'image. (Cela fait plaisir de connaître toutes les fonctions de la région, mais aussi celles que vous avez utilisées, je ne les ai vues RegionPlotque jusqu'à présent.)
Martin Ender le
Vous avez probablement déjà remarqué que cela ,AspectRatio-> 1ramène le code à 149 octets, exactement là où il se trouve maintenant.
DavidC
2
Est-ce moi ou est-ce que cette image ressemble à Marvin l'Androïde Android?
paqogomez
16

Python 3.3 ( 183 177 164 160 octets)

B=list(map(eval,input().split()))
print("".join(" ## "[sum(any(r*r>(x-d%80/4+10)**2+(y+d//80/4-10)**2for
x,y,r in B)for d in[i,i+1,i+80])]for i in range(6400)))

Il nécessite une console large de 80 caractères, que je sais être la configuration par défaut de Windows. Cela fonctionne mieux si votre console a une police carrée. Voici quelques extraits d’entrées de test.

Original:

           ########
          ##       #
         ##         #
     #####          #
    ##   #          #
   ##               #
  ##                #
 ##                 #
 #                  #
 #                 ##
  #               ##
  #       ##      #
   #      # #    ##
   #      #  #####
   #      #
    #    ##
     #  ##
      ###

Un autre:

    ########
  ###       ##
 ##           #
 #            #
##             #
#              #
#              #
#              #
#              #
#               ##
#                 #
 #                 ##
 #                   ######
  #                        #
   ##      ###             #
     #    ## #             #
     #    #  #             #
      #  ## ##             #
       ###  #             ##
            #       #######
            #      ##
            #      #
             #    ##
              #####

Trou:

                              ############
                            ###           ##
                          ###               ##
                         ##                   #
                  ########                     #######
                ###                                   ##
              ###                                       ##
             ##                                           #
            ##                                             #
           ##                                               #
          ##                                                 #
         ##                                                   #
        ##                                                     #
       ##                                                       #
      ##                                                         #
      #                                                          #
     ##                                                           #
     #                                                            #
    ##                                                             #
    #                                                              #
    #                                                              #
    #                                                              #
    #                                                              #
    #                                                              #
    #                                                              #
   ##                                                               #
  ##                                                                 #
  #                                                                  #
 ##                                                                   #
 #                                                                    #
##                                                                     #
#                                 ####                                 #
#                                ##   #                                #
#                               ##     #                               #
#                              ##       #                              #
#                              #        #                              #
#                              #        #                              #
#                               #      ##                              #
#                                #    ##                               #
#                                 #  ##                                #
#                                  ###                                 #
 #                                                                    ##
 #                                                                    #
  #                                                                  ##
  #                                                                  #
   #                                                                ##
    #                                                              ##
    #                                                              #
    #                                                              #
    #                                                              #
    #                                                              #
    #                                                              #
    #                                                              #
     #                                                            ##
     #                                                            #
      #                                                          ##
      #                                                          #
       #                                                        ##
        #                                                      ##
         #                                                    ##
          #                                                  ##
           #                                                ##
            #                                              ##
             #                                            ##
              #                                          ##
               ##                                      ###
                 ##                                  ###
                   #######                    ########
                          #                  ##
                           ##              ###
                             ##          ###
                               ###########
récursif
la source
1
J'aime le fait que ce soit la seule solution d'art ascii.
vmrob
pas d'importations ... impressionnant!
Richard Green
15

Python - 253 249 215 199

Il s’agit d’une publicité pour l’impressionnante bibliothèque bien faite, dont les opérations de géométrie ont rendu l’écriture de la solution facile en traçant les contours de l’union des cercles se chevauchant (= points tamponnés):

from pylab import*
from shapely.geometry import*
c=Point()
for s in raw_input().split():
 x,y,r=eval(s)
 c=c.union(Point(x,y).buffer(r))
plot(*c.exterior.xy)
for i in c.interiors:
 plot(*i.xy)
show()

Sortie:

trois nuages

Édition (s):

  • 249: remplacé sys.argv[1:]par raw_input().split(), sauvegarde d'unimport sys
  • 215: k={'color':'k'}Luxe supprimé , remplacé savefigparshow
  • 199: remplacé map(float,s.split(','))pareval(s)
ojdo
la source
11

Python - 535

import math as m
import matplotlib.pyplot as l
c = "3,1,1 3,2,1.5 1,2,0.7 0.9,1.2,1.2 1,0,0.8"
a = [[float(y) for y in x.split(",")] for x in c.split(" ")]
for a2 in a:
    for x in xrange(0,200):
        q=x*m.pi/100.0
        p=(a2[0]+m.sin(q)*a2[2], a2[1]+m.cos(q)*a2[2])
        cc = []
        for z in a:            
            if z != a2:               
                if ((z[0] - p[0]) ** 2 + (z[1] - p[1]) ** 2 ) < (z[2] ** 2) :
                    cc.append(z)
        if not cc: 
            l.scatter(p[0],p[1])
l.show()
Richard Green
la source
2
Cela a beaucoup de potentiel pour jouer plus bas encore, par exemple, en from math import*supprimant les espaces non supprimés, en utilisant des noms de variable à une lettre uniquement, en utilisant la compréhension de liste (par exemple, cc=[z for z in a if z!=a2 and (z[0]…)]). Découvrez également les astuces pour jouer au golf en Python .
Wrzlprmft
Vous pouvez enregistrer certains caractères en utilisant un nom de variable d'une lettre au lieu de a2.
ProgramFOX le
merci ... je vais probablement commencer à jouer au golf ce soir (autre chose à faire maintenant mais je voulais mettre un pieu dans le sol)
Richard Green
1
oui @ProgramFOX ... c'était une version qui a fonctionné et que je pouvais déboguer .. la raccourcira ce soir ...
Richard Green
3
@ JamesWilliams si vous voulez prendre le relais ... s'il vous plaît faites-le .. je ne protège pas du code !! N'hésitez pas à l'ajouter comme votre propre entrée (tant que vous créditez l'original!)
Richard Green
9

Python - 296 249 231 223 212

from pylab import*
a=map(eval,raw_input().split())
for x,y,r in a:
 for i in range(200):
  q=i*pi/100;p=x+r*sin(q);t=y+r*cos(q);[z for z in a if z!=(x,y,r)and(z[0]-p)**2+(z[1]-t)**2<z[2]**2]or scatter(p,t)
show()

Le mérite revient à @ richard-green (la permission a été donnée) pour la solution originale, je viens de la réduire un peu.

James Williams
la source
7
bien ça me donne le droit de vote ...
Richard Green
1
Vous pourrez peut-être économiser davantage en important à la pylabplace de matplotlib.pyplot.
ojdo
@odjo Actuellement sur mobile, si je l'utilisais, from pylab import *pourrais-je quand même appeler show()et scatter()sans aucune référence?
James Williams
1
@JamesWilliams confirmé! Pylab est un pollueur d’espace de noms comprenant de nombreuses fonctions de type MATLAB :-)
ojdo
Vous pouvez raccourcir cela en utilisant [eval(i)for i in raw_input().split()]comme evaltours de python 1,2,3un tuple. Vous devrez bien sûr aussi changer le [x,y,r]en (x,y,r).
KSab
7

JavaScript (E6) + HTML 322

JSFiddle

Chaque cercle est subdivisé en environ 100 petits arcs, et chaque arc est dessiné si son point milieu n'est pas à l'intérieur d'un des autres cercles.

<canvas id='c'/>
<script>
t=c.getContext("2d"),z=99,c.width=c.height=400,
l=prompt().split(' ').map(c=>c.split(',').map(v=>40*v)),
l.map(c=>{
  for(i=z;--i+z;)
    s=4/z,r=c[2],x=c[0]+r*Math.cos(a=i*s),y=c[1]+r*Math.sin(a),
    t.beginPath(),
    l.some(q=>c!=q&(d=x-q[0],e=y-q[1],d*d+e*e<q[2]*q[2]))||t.arc(z+c[0],z+c[1],r,a-s,a+s),
    t.stroke()
})
</script>
edc65
la source
7

Python 274 octets

Cela prend les entrées de stdin et vérifie chaque point de l’affichage en dessinant les pixels un par un au fur et à mesure. Pas vraiment efficace mais il suit toutes les règles.

c=[eval(s)for s in raw_input().split()]
import pygame
S=pygame.display.set_mode((500,500))
S.fill([255]*3)
for p in((x,y)for x in range(500)for y in range(500)if 0<min((((x-250)/25.-a)**2+((y-250)/25.-b)**2)**.5-r for(a,b,r)in c)<.1):S.set_at(p,[0]*3)
pygame.display.update()

Notez que l’affichage pygame se terminera dès que le dessin sera terminé. Je ne savais pas si je devais l’inclure dans ma réponse raw_input. veulent empêcher le système d'exploitation de se plaindre de ne pas répondre et telles:

alive = True
while alive:
    pygame.display.update()
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            alive = False

Exemple d'images:

1,4,2 5,2,1 3,1,1 3.5,2,1.2 3,3,0.7, 1,2,0.7 entrez la description de l'image ici

0,5,4 3,4,4 4,3,4 5,0,4 4,-3,4 3,-4,4 0,-5,4 -3,-4,4 -4,-3,4 -5,0,4 -4,3,4 -3,4,4 entrez la description de l'image ici

KSab
la source
3
@ edc65 Je ne sais pas trop ce que vous voulez dire. Il remplit précisément les pixels compris entre 0 et 0,1 unité (entre 0 et 2,5 pixels) en dehors des cercles. Voulez-vous dire qu'il devrait trouver mathématiquement les arcs corrects à dessiner? En lisant la question, cela ne semblait pas être une restriction pour moi.
KSab
4

Perl - 430

@e=map{[map{int($_*32)}split',']}(split' ',<>);for$g(@e){for(0..3){($a[$_]>($q=$$g[$_&1]+(($_>>1)*2-1)*$$g[2]))^($_>>1)&&($a[$_]=$q)}}for(2,3){$a[$_]-=$a[$_-2]-1}for(@e){($x,$y,$r)=@$_;$x-=$a[0];$y-=$a[1];for$k($x-$r..$x+$r){for$l($y-$r..$y+$r){$i=(int(sqrt(($x-$k)**2+($y-$l)**2)+0.5)<=>$r)-1;$f[$l][$k]=($j=$f[$l][$k])<-1||$i<-1?-2:$i||$j;}}}print"P1
$a[2] $a[3]
".join("
",map{join' ',map{$_+1?0:1}@$_,('0')x($a[2]-@$_)}@f)."
"

Écrit un fichier pbm sur stdout.

Image test (convertie en png):

Deuxième image test (convertie en png)

faubi
la source