Il piccolo Chandler è triste. Disegnagli una nuvola per rallegrarlo


57

Il piccolo Chandler è triste. Disegnagli una nuvola per rallegrarlo.
Nota: disegnare una nuvola in realtà non lo rallegra.

Un cerchio può essere definito come una 3 tupla in (x,y,r)cui si xtrova la posizione x del cerchio su un piano cartesiano, yè la posizione y del cerchio su un piano cartesiano ed rè il raggio del cerchio. xe ypuò essere negativo. rè sempre positivo. L'input è un elenco di cerchi sotto forma di 3 tuple separate da spazi. Per esempio:

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

I 3,1,1mezzi "Un cerchio con centro a 3,1con 1 raggio. 3,2,1.5Significa" cerchio con centro a 3,2con 1,5 raggio.

Se disegniamo tutti questi cerchi dell'input su un grafico, sembra così (ho incluso le linee della griglia e le etichette solo per chiarezza; non sono richiesti):

Grafico

Nota come tutti i cerchi sono coerenti . Cioè, sono tutti sovrapposti insieme in modo da formare un grande gruppo senza piccoli gruppi di cerchi separati dal resto. L'ingresso è garantito per essere coerente.

Supponiamo ora di tracciare una linea che percorre il "bordo" formato da questi cerchi, senza nessuna delle altre linee. Sarebbe come disegnare il bordo della sagoma formata da tutti i cerchi. Il cloud risultante sarebbe simile al seguente:

nube

Quindi questa nuvola è stata formata disegnando solo gli archi dei cerchi nell'input che formano un bordo, risultando in una singola forma. In altre parole, la nuvola si forma disegnando solo gli archi che non si trovano all'interno di un altro cerchio. Il programma prenderà l'input nel modulo spiegato sopra e produrrà un'immagine che mostra il cloud risultante. La forma complessiva della nuvola deve essere corretta, ma la scala, il colore, lo spessore della linea e l'aspetto dei vertici dipendono da te. Nota che il cloud deve essere visibile, quindi non puoi estrarre qualcosa del tipo "Questo programma disegna una nuvola bianca su uno sfondo bianco", "Questo programma disegna una nuvola su scala infinitamente piccola", "Questo programma disegna una nuvola con 0 spessore della linea ", ecc. Si noti inoltre che il colore del bordo deve essere diverso dal colore del riempimento o dello sfondo.

Un altro esempio. Ingresso:

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

Produzione:

Cloud2

Se c'è un "buco" nella nuvola, dovresti disegnare anche il buco. Ingresso:

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 

Produzione:

Cloud3

Ecco una regola importante: il tuo programma deve tracciare solo le linee che formano il bordo. Ciò significa che NON PUOI semplicemente disegnare completamente i cerchi, e quindi disegnare i cerchi leggermente più piccoli con un riempimento bianco - poiché quel metodo disegna ancora linee che non formano un bordo, li copre solo in seguito. Lo scopo della regola era impedire le implementazioni "disegna i cerchi, quindi disegna nuovamente i cerchi con un riempimento bianco" o qualcosa di simile. La risposta dovrebbe effettivamente calcolare dove disegnare le cose prima di disegnarla.

Questo è il golf del codice, quindi vince il numero di caratteri più breve.


13
+1 per una domanda di output grafico con un criterio vincente oggettivo (e il primo paragrafo).
Dennis,

2
Come puoi sapere se tracciamo una linea e la cancelliamo in seguito? Il rendering di tali linee su bitmap interne è corretto? In caso contrario, dov'è il bordo, tra un vettore e una rappresentazione bitmap? In caso affermativo, perché non farci fare lo stesso con il canvas principale (che sappiamo essere a doppio buffer, in modo che l'utente non possa vedere le nostre linee temporanee)?
John Dvorak,

1
@JanDvorak Lo scopo della regola era impedire le implementazioni "disegna i cerchi, quindi disegna di nuovo i cerchi con un riempimento bianco" o qualcosa di simile a quello. La risposta dovrebbe effettivamente calcolare dove disegnare le cose prima di disegnarla. Modificherò per renderlo più chiaro.
assenzio

15
Questa domanda è assolutamente divertente con Cloud to Butt ( chrome.google.com/webstore/detail/cloud-to-butt-plus/… ) installato.
Erty Seidohl,

9
@SomeKittens L'ho perso in "Se c'è un" buco "nella nuvola, dovresti anche disegnare il buco."
Erty Seidohl,

Risposte:


25

Mathematica 177 126 121 119

Soluzione di Disk Regions: l'approccio del matematico

La logica è

  • Crea la Regione 1 (R1), i cerchi (senza i loro interni);
  • Crea la Regione 2 (R2), i dischi (senza i bordi del cerchio).
  • Crea regione 3 (R3 = R1-R2).
  • -

inferenza della regione

Questo è esattamente l'approccio seguito. Ha prodotto le 3 figure sopra.

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 regione implicita n. 1 è l'unione dei circoli. La regione implicita n. 2 è l'unione dei dischi che si trovano all'interno dei cerchi. La loro differenza è il confine.

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}],
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}]]


Risoluzione di Disk Regions: l'approccio dell'ingegnere (119 caratteri)

Quanto segue prende l'unione delle regioni del disco, discretizza quella regione e trova il suo confine. I punti nel diagramma delimitano gli intervalli della mesh Delaunay. Mostriamo la regione discretizzata di seguito per evidenziare l'oggetto che fornisce il confine di interesse (il contorno della nuvola).

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"

Il confine della regione è discretizzato.

reg1


Risolvendo rilevando i bordi: l'approccio del fotografo - 121 caratteri

rilevamento dei bordi

Disegna i dischi in nero, rasterizza l'immagine, rileva i bordi e inverte il bianco e nero.

s=StringSplit;ColorNegate@EdgeDetect@Rasterize@Graphics[Disk[{#,#2},#3]&@@@
((ToExpression/@s[#,","])&/@s[InputString[]])]

Rasato da 5 byte:RegionBoundary@DiscretizeRegion@RegionUnion[{#,#2}~Disk~#3&@@@ToExpression[#~s~","]&@s@InputString[s=StringSplit]]
Martin Ender,

Potenzialmente s=StringSplitall'interno del prompt? Prova a spostarlo di nuovo davanti, dovrebbe comunque essere più corto della tua versione attuale.
Martin Ender,

27

T-SQL 235 234 229 212 171 73 byte

Questo utilizza funzionalità spaziali in SQL Server 2012+. Quando viene eseguito in SSMS (SQL Server Management Studio), viene prodotto un riquadro dei risultati spaziali. L'input proviene dalla variabile @i. Potrei ridurlo ulteriormente se l'input potesse essere preso da una tabella.

Poiché l'input della tabella è ora consentito.

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

Ho lasciato la soluzione precedente qui sotto.

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(@)

Modifica : rimuove lo spazio randagio, il surplus in e la subquery

171: Sostituita la creazione della tabella con CTE e @s con @.

inserisci qui la descrizione dell'immagine

Analisi dell'SQL dinamico

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

Ricevo un errore dicendo'A' has fewer columns than were specified in the column list
Jesan Fafon,

@JesanFafon Assicurati che la variabile di input @i sia impostata correttamente. 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'. Sfortunatamente non posso provare al momento e SQLfiddle non sta giocando bene per il 2012.
MickyT

Bel lavoro con le funzioni della geometria SQL. Buone notizie! L'immissione da una tabella preesistente è ora esplicitamente consentita . La creazione e il popolamento delle tabelle non devono essere inclusi nel conteggio dei byte.
BradC,

Ho giocato a golf alcuni personaggi. Il collegamento non produce un risultato. Ma funziona in MS-sql Server Management Studio. Lo script è qui , divertiti. Sentiti libero di usarlo
t-clausen.dk il

@ t-clausen.dk grazie per quello, ma dal momento che lo aggiornerò lo cambierò in input tabella consentito. Non avevo intenzione di dragare questo backup, ma ...
MickyT

23

Mathematica, 175 158 149 byte

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}]

Ricordo dalla discussione nella sandbox che questo approccio doveva essere valido, ma non sono del tutto sicuro di come si collochi con la nuova formulazione delle regole, quindi @Lilac, fammi sapere se pensi che questo violi le regole.

Fondamentalmente, sto creando una condizione logica che è vera per tutti i punti all'interno del cloud e falsa per tutti i punti al di fuori di esso. Sto alimentando ciò a RegionPlotcui quindi viene rappresentata la regione di tutti i punti in cui si trova l'espressione Truee un contorno attorno ad essa.

inserisci qui la descrizione dell'immagine

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}
]

1
ImplicitRegiontrova automaticamente i valori X e Y corretti per la stampa. 122 caratteri:s = StringSplit; RegionPlot@ ImplicitRegion[ Or @@ (((x - #)^2 + (y - #2)^2 < #3^2) & @@@ (ToExpression[#~s~","] &@(s@InputString[]))), {x, y}]
DavidC

@DavidCarraher Sfortunatamente, questo distorce le proporzioni dell'immagine. (È bello conoscere tutte quelle funzioni della regione, anche quelle che hai usato, che ho visto solo RegionPlotfinora.)
Martin Ender,

Probabilmente hai già notato che ,AspectRatio-> 1riporta il codice a 149 byte, esattamente dove si trova ora.
DavidC,

2
Sono io o questa immagine assomiglia a Marvin il Paranoid Android?
paqogomez,

16

Python 3.3 ( 183 177 164 160 byte)

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)))

Richiede una console larga 80 caratteri, che so essere il valore predefinito in Windows. Funziona meglio se la tua console ha un carattere quadrato. Ecco alcuni estratti di alcuni degli input di test.

Originale:

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

Un altro:

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

Buco:

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

1
Adoro che questa sia l'unica soluzione di arte ascii.
vmrob,

nessuna importazione ... impressionante!
Richard Green

15

Pitone - 253 249 215 199

Questa è una pubblicità per la fantastica libreria formosa , le cui operazioni di geometria hanno reso la scrittura della soluzione semplice disegnando i contorni dell'unione di cerchi sovrapposti (= punti bufferizzati):

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()

Produzione:

tre nuvole

Edit (s):

  • 249: sostituito sys.argv[1:]da raw_input().split(), salvando aimport sys
  • 215: k={'color':'k'}lusso rimosso , sostituito savefigdashow
  • 199: sostituito map(float,s.split(','))daeval(s)

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()

2
Ciò ha molte potenzialità per essere ulteriormente from math import*scremato , ad esempio rimuovendo spazi non indicati, usando solo nomi di variabili di una lettera, usando la comprensione dell'elenco (ad es cc=[z for z in a if z!=a2 and (z[0]…)].). Dai un'occhiata anche ai suggerimenti per giocare a golf in Python .
Wrzlprmft,

È possibile salvare alcuni caratteri utilizzando un nome variabile di una lettera anziché a2.
Programma FOX il

grazie wrzl ... Probabilmente inizierò a giocare a golf stasera (altre cose da fare in questo momento ma volevo mettere un paletto nel terreno)
Richard Green

1
Si @ProgramFOX ... questa era una versione che ha lavorato e che ho potuto eseguire il debug .. lo otterrà più breve stasera ...
Richard Green

3
@JamesWilliams se vuoi prendere il testimone ... per favore, fallo .. Non sono protettivo del codice !! Sentiti libero di aggiungerlo come tua voce (a patto che tu accrediti l'originale!)
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()

Il merito va a @ richard-green (il permesso è stato dato) per la soluzione originale, l'ho appena ridotta un po '.


7
bene che ottiene il mio voto ...
Richard Green,

1
Potresti riuscire a risparmiare un po 'di più importando pylabinvece di matplotlib.pyplot.
ojdo,

@odjo Attualmente su dispositivo mobile, se avessi usato from pylab import *sarei ancora in grado di chiamare show()e scatter()senza riferimenti?
James Williams,

1
@JamesWilliams confermato! Pylab è un pollin dello spazio dei nomi, incluse molte funzioni simili a MATLAB :-)
ojdo

Puoi accorciarlo usando [eval(i)for i in raw_input().split()]le evaltrasformazioni di Python 1,2,3in una tupla. Ovviamente dovrai anche cambiare [x,y,r]in a (x,y,r).
KSab,

7

JavaScript (E6) + HTML 322

JSFiddle

Ogni cerchio è suddiviso in circa 100 piccoli archi e ogni arco viene disegnato se il suo punto medio non è all'interno di nessuno degli altri cerchi.

<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>

7

Python 274 byte

Questo prende input dallo stdin e controlla ogni punto sul display, disegnando i pixel uno per uno mentre procede. Non esattamente efficiente ma segue tutte le regole.

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()

Nota che il display di pygame si interromperà non appena il disegno sarà completo, non ero sicuro di doverlo includere come parte della mia risposta, ma per visualizzarlo puoi lanciare un raw_inputalla fine o aggiungere un piccolo loop se desidera impedire al sistema operativo di lamentarsi che non risponde e che:

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

Immagini di esempio:

1,4,2 5,2,1 3,1,1 3.5,2,1.2 3,3,0.7, 1,2,0.7 inserisci qui la descrizione dell'immagine

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 inserisci qui la descrizione dell'immagine


3
@ edc65 Non sono del tutto sicuro di cosa intendi. Ciò che fa esattamente è riempire qualsiasi pixel compreso tra 0 e 0,1 unità (tra 0 e 2,5 pixel) al di fuori dei cerchi. Stai dicendo che dovrebbe trovare matematicamente gli archi corretti da disegnare? Dal leggere la domanda non mi sembrava che fosse una restrizione per me.
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)."
"

Scrive un file pbm su stdout.

Immagine di prova (convertita in png):

Seconda immagine di prova (convertita in png)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.