Cercles superposés bicolores


22

Écrivez un programme ou une fonction qui accepte l'entrée suivante dans un format raisonnable de votre choix:

  • Deux entiers positifs W et H qui définissent la largeur et la hauteur de l'image que vous allez générer.

  • Deux couleurs RVB C1 et C2 qui seront utilisées pour colorer l'image.

  • Une liste de 3 tuples de la forme (r, x, y)qui définissent des cercles avec un rayon ret un centre x, ydans le plan de l'image. rest un entier positif et xet ysont des entiers quelconques. Le pixel supérieur gauche de l'image est 0, 0et l'axe des x augmente vers la droite et l'axe des y augmente vers le bas.

Générez une image aux dimensions W par H colorée avec C1 et C2 de telle sorte qu'il n'y ait pas deux régions voisines définies par tous les cercles qui se chevauchent ont la même couleur.

Par exemple: si l'entrée est

W = 300
H = 200
C1 = (255, 200, 0)
C2 = (128, 0, 255)
Circles = (25, 50, 80), (40, 80, 120), (300, -100, 6), (17, 253, 162)

alors les limites du cercle ressemblent à ceci:

exemple 1 limites de cercle

Il y a six régions distinctes et contiguës dans l'image créée par les cercles. Chaque région doit être colorée avec C1 (jaune) ou C2 (violet) de sorte qu'il n'y ait pas deux régions voisines de la même couleur.

Il y a deux façons de procéder, leur seule différence étant que les couleurs sont permutées:

exemple 1 sortie 1 exemple 1 sortie 2

Ainsi, l'une ou l'autre de ces deux images serait une sortie valide pour l'exemple d'entrée.

Quelque chose comme ça serait une sortie non valide car deux régions jaunes se voisinent.

Vos images de sortie doivent suivre ces directives:

  • Outre C1 et C2, une troisième couleur neutre, comme le noir ou le blanc, peut être utilisée pour les limites des cercles tant qu'elles n'ont pas plus de 5 pixels d'épaisseur. (Des limites noires de 1 pixel d'épaisseur sont présentes dans l'exemple ci-dessus.)

  • Les limites des cercles ne sont cependant pas nécessaires. Les régions peuvent être voisines directement:

    exemple 1 sortie 3 exemple 1 sortie 4

    Ces deux éléments sont une autre sortie valide de l'exemple ci-dessus.

  • Les cercles doivent être aussi précis que possible, en utilisant des algorithmes de dessin de cercle ou tout ce que votre bibliothèque graphique fournit.

  • En général, la perfection des pixels n'est pas requise, mais si les paramètres d'entrée sont mis à l'échelle de plus en plus grands, l'image résultante devrait devenir de plus en plus précise.

  • L'anticrénelage est autorisé mais pas obligatoire.

  • Les lignes de quadrillage ou les étiquettes d'axe, etc. en arrière-plan ne sont pas autorisées.

Le code le plus court en octets gagne.

Plus d'exemples

Tous utilisant ces entrées avec différents ensembles de cercles:

W = 100
H = 60
C1 = (255, 0, 0)
C2 = (0, 0, 255)

Dans tous les exemples, les couleurs peuvent être échangées et restent valides.

Circles =
A. empty list
B. (13, 16, 20)
C. (30, 16, 20)
D. (200, 16, 20)
E. (42, 50, 20)
F. (42, 50, 20), (17, 40, 30)
G. (42, 50, 20), (17, 20, 30)
H. (42, 50, 20), (17, 10, 30), (10, 50, 30)
I. (42, 50, 20), (17, 10, 30), (35, 50, 20)
J. (18, 36, 40), (18, 63, 40), (18, 50, 20)
K. (100, -10, -20), (60, 50, -10)
L. (18, 36, 40), (18, 63, 40), (18, 50, 20), (14, 50, 20), (5, 50, 18), (20, 0, 0), (70, 22, 0), (10000, -9970, 0), (135, 100, -80) 

A. ex A B. ex B C. ex C D. ex D
E. EXE F. ex F G. ex G H. ex H
I. ex je J. ex J K. ex K L. ex L

Assurez-vous que votre sortie se comporte de la même manière que tous ces exemples.


Cela a l'air bien, peut-on sortir en ascii, par exemple C1 est 1 et C2 est 0?
Matthew Roh

@MatthewRoh Non. Je sais que ce serait pratique mais des images sont nécessaires.
Calvin's Hobbies

1
Ok alors je suppose que je peux comptertikz
Wheat Wizard

1
@MatthewRoh, netpbm est un format d'image couramment utilisé sur ce site.
Peter Taylor

2
@Luis Ok. De petites variations d'entrée comme celle-ci ou la montée de l'axe y sont correctes.
Calvin's Hobbies

Réponses:


14

Mathematica, 165 octets

ContourPlot[Cos@Tr[Boole[Norm[{x,y}-#2]<#]Pi&@@@#4],{x,0,#},{y,0,#2},PlotPoints->5!,AspectRatio->Automatic,Frame->False,ContourShading->RGBColor@@@#3,Contours->{0}]&

Fonction pure prenant quatre arguments: la largeur, la hauteur (les deux entiers), une paire ordonnée de triplets de nombres entre 0 et 1 (représentant les deux couleurs RVB), et une liste d'éléments du formulaire {r, {x, y}}pour enregistrer les rayons et les centres de les cercles. Par exemple, le premier exemple de l'OP serait appelé avec les arguments [300, 200, {{1, 0.784, 0}, {0.5, 0, 1}}, {{25, {50, 80}}, {40, {80, 120}}, {300, {-100, 6}}, {17, {253, 162}}}]. L'axe y positif pointe vers le haut dans Mathematica.

Norm[{x,y}-#2]<# détecte si un point se trouve à l'intérieur d'un cercle donné; Boole[...]Piconvertit cela Trueou Falseen πou 0. Après avoir calculé ces πs / 0 sur tous les cercles d'entrée, les Tradditionne et Cosconvertit les multiples pairs de π en 1, les multiples impairs de π en –1. ContourPlot[...,Contours->{0}]colore ensuite la région appropriée du plan en deux couleurs selon que la valeur est supérieure ou inférieure à 0. AspectRatio->Automaticfait ressembler les cercles aux cercles; PlotPoints->5!donne une précision décente (augmentez-la 9!si vous voulez vraiment une image incroyable, loin dans le futur!); Frame->Falsese débarrasse des axes; et ContourShading->RGBColor@@@#3utilise les couleurs d'entrée pour les contours.

Exemple de sortie, avec la première paire de couleurs (car elles sont belles) mais la dernière série de cercles:

exemple de sortie


11

JavaScript / SVG / HTML5, 219 octets

f=// for demo
(w,h,b,f,a)=>`<svg width=${w} height=${h}><rect width=${w} height=${h} fill=rgb(${b}) /><path fill=rgb(${f}) fill-rule=evenodd d=${a.map(([r,x,y])=>[`M`+x,y-r+`a`+r,r,0,0,0,0,r+r+`a`+r,r,0,0,0,0,-r-r]).join``} /></svg>`
;//demo
[[`A`, []],
 [`B`, [[13, 16, 20]]],
 [`C`, [[30, 16, 20]]],
 [`D`, [[200, 16, 20]]],
 [`E`, [[42, 50, 20]]],
 [`F`, [[42, 50, 20], [17, 40, 30]]],
 [`G`, [[42, 50, 20], [17, 20, 30]]],
 [`H`, [[42, 50, 20], [17, 10, 30], [10, 50, 30]]],
 [`I`, [[42, 50, 20], [17, 10, 30], [35, 50, 20]]],
 [`J`, [[18, 36, 40], [18, 63, 40], [18, 50, 20]]],
 [`K`, [[100, -10, -20], [60, 50, -10]]],
 [`L`, [[18, 36, 40], [18, 63, 40], [18, 50, 20], [14, 50, 20], [5, 50, 18], [20, 0, 0], [70, 22, 0], [10000, -9970, 0], [135, 100, -80]]]
 ].forEach(([c, a])=>document.write(`<nobr><tt>&nbsp;${c}.&nbsp;</tt>${f(100, 60, [255, 0, 0], [0, 0, 255], a)}</nobr><wbr>`));


10

BBC Basic, 120 117 octets

Téléchargez l'interprète sur http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

I.w,h,R,G,B,r,g,b:V.22,4,19;16,r,g,b,275;16,R EORr,G EORg,B EORb,24,0;0;w;h;16
5I.r,x,y:V.25,4,x;h-y;25,154,r;0;:G.5

BBC Basic dispose d'une gamme de modes de couleur vous permettant de tracer des graphiques raster en fonction des opérations logiques de base: OR, AND, XOR etc.

Il prend également en charge la reprogrammation des palettes, ce qui signifie que, par exemple, ici, une image à 2 couleurs peut avoir ses couleurs reprogrammées à n'importe laquelle des 4096 couleurs. L'implémentation utilisée ici présente quelques différences (non documentées) par rapport à l'implémentation BBC d'origine, dans laquelle les opérateurs EOR ne seraient pas nécessaires.

Non golfé

  INPUTw,h,R,G,B,r,g,b:                           :REM Input size and colours
  VDU22,4                                         :REM Change to MODE 4 (2 colours) as the default mode gives odd behaviour
  VDU19,0,16,r,g,b,19,1,16,R EORr,G EORg,B EORb   :REM Reprogram the colours to R,G,B and R^r,G^g,B^b
  VDU24,0;0;w;h;16                                :REM Setup a graphics viewport of the right size, and "clear" it to change background colour
5 INPUTr,x,y                                      :REM take input coordinates
  VDU25,4,x;h-y;                                  :REM move to x,y (h-y required as BBC BASIC y axis increases upward, reverse of spec)
  VDU25,154,r;0;                                  :REM draw circle in "logical inverse colour" of existing pixels (this implementation seems however to XOR with colour 1 instead)
  GOTO5                                           :REM repeat infinitely until user presses escape

Écran de sortie typique

Exemple d'image agrandie par un facteur de 10 en unités / facteur de 5 en pixels (BBC basic utilise 1 pixel = 2 unités.)

entrez la description de l'image ici


10

MATL , 30 29 25 octets

2ZG:i:!J*+2&!-|i<so2&!1YG

Format d'entrée:

  • Carte de couleurs comme matrice de valeurs comprises entre 0 et 255, où chaque ligne définit une couleur
  • W
  • H
  • Vecteur de colonne de coordonnées centrales basées sur 1 en tant que valeurs complexes ( x est la partie réelle, y est la partie imaginaire)
  • Vecteur colonne de rayons.

Essayez MATL en ligne! Ou vérifiez le dernier cas de test . (L'interpréteur est encore expérimental. Vous devrez peut-être actualiser la page et réessayer si cela ne fonctionne pas).

Explication

Le code utilise des nombres complexes pour définir la grille de points et pour calculer les distances, et fait un usage intensif des opérations de tableau avec la diffusion .

2ZG    % Implicitly input matrix of colors. Set as colormap
:      % Implicitly input W. Push [1 2 ... W]
i:     % Input H. Push [1 2 ... H]
!J*    % Transpose, multiply by 1i
+      % Add element-wise with broadcast. Gives H×W grid of points as
       % complex numbers, 1-based 
2&!    % Permute first dimension with the third. Gives a 1×W×H array
-|     % Implicitly input center coordinates. Subtract grid from them,
       % element-wise with broadcast. Gives a C×H×W array, where C is the
       % number of circles
i      % Input column vector of circle radii
<      % Less than, element-wise with broadcast
so     % Sum along first dimension, modulo 2. Gives a 1×W×H array
2&!    % Permute first dimension with the third. Gives a a H×W array
1YG    % Display as scaled image

2
Je dis Enregistrer ces octets! : D
Greg Martin

1
@GregMartin Vous avez raison. Qui se soucie de l'élégance quand 4 octets peuvent être enregistrés! :-) Fait
Luis Mendo

1
@LuisMendo Plus c'est court, mieux c'est avec codegolf, peu importe à quel point il devient laid. ;)
Kevin Cruijssen

6

Python utilisant pypng , 140 138 octets

import png
f=lambda W,H,c,d,C:png.from_array([[[c,d][sum(abs(x-X+1j*(y-Y))<r for r,x,y in C)%2]for X in range(W)]for Y in range(H)],'RGB')

Exemple d'utilisation:

W = 100
H = 60
C1 = (255, 0, 0)
C2 = (0, 0, 255)
Circles = (18, 36, 40), (18, 63, 40), (18, 50, 20), (14, 50, 20), (5, 50, 18), (20, 0, 0), (70, 22, 0), (10000, -9970, 0), (135, 100, -80)
f(W, H, C1, C2, Circles).save('test.png')

Merci à xnor pour avoir économisé 2 octets.


Bienvenue au code golf! Pour vérifier si un mensonge point dans un cercle, une astuce consiste à utiliser la norme complexe: abs(x-X+1j*(y-Y))<r.
xnor

3

Math (non compétitif)

(idk comment faire LaTeX dans PPCG, donc j'ai utilisé un outil LaTeX to png)

Explication

Le produit de plusieurs équations circulaires ( (x-a)^2+(y-b)^2-r^2)> = 0 fera un graphique dont cette question a besoin. Dans l'équation, nest la taille du tableau et (x, y or r)_kest le ke (x, y, or r)élément.

Exemple

(0,0,2),(2,2,2)

(Merci WolframAlpha)

(Graphique d'inégalité par WolframAlpha)

Équation Get / Run pour WolframAlpha

Obtention du script: terminé

Script en cours d'exécution: pas encore terminé

Maintenant, faites-le fonctionner avec Mathematica ...


Je me demande si c'est valable?
Matthew Roh

Vous devez répertorier un interpréteur préexistant spécifique qui tracerait la sortie sous la forme souhaitée en fonction de cette entrée. Cela permettrait de compter les octets qu'il contient. À l'heure actuelle, le problème est que, parce qu'il n'est pas lié à un interprète, il n'est pas lié à un format spécifique pour représenter l'équation, et donc la notation est informelle et impossible à compter objectivement. Il existe de nombreux programmes pour tracer des graphiques d'équations, il peut donc être utile d'en essayer un avec un format d'entrée laconique.

@ ais523 Ohh. Je vais essayer de le faire fonctionner avec WolframAlpha.
Matthew Roh

1

Python 2.x, 166 158

import re;def f(W,H,c,d,C):print'P3',W,H,255,re.sub('[^0-9]',' ',repr([[d,c][sum([abs(x-X+1j*(y-Y))<r for r,x,y in C])%2]for Y in range(H)for X in range(W)]))

La fonction génère un fichier PPM sur la sortie standard.

Exemple:

W = 300
H = 200
C1 = (255, 200, 0)
C2 = (128, 0, 255)
Circles = [(25, 50, 80), (40, 80, 120), (300, -100, 6), (17, 253, 162)]

f(W, H, C1, C2, Circles)

Exemple


1

Lisp commun + Quicklisp + ZPNG 260 + 20 = 280 caractères

C'est le code le plus large que j'ai jamais écrit en CL, et si je ne faisais pas de golf de code, j'aurais restructuré cela pour le rendre beaucoup plus facile à lire ...

Prélude (20 caractères)

(ql:quickload 'zpng)

Golfé (260 caractères)

(lambda(w h g b c)(make-instance'zpng:png :image-data(coerce(loop :for j :below h :nconc(loop :for i :below w :append(if(evenp(count t(mapcar(lambda(c)(<(abs(complex(-(cadr c)i)(-(caddr c)j)))(car c)))c)))g b)))'(array(unsigned-byte 8)(*))):width w :height h))

Non golfé:

(Utilise defun pour permettre des tests et des noms de variable plus longs pour la lisibilité)

(defun mk-png (width height color1 color2 circles)
  (make-instance 'zpng:png
                 :image-data (coerce (loop :for j :below height
                                           :nconc (loop :for i :below width
                                                        :append (if (evenp (count t (mapcar (lambda (circ)
                                                                                              (< (abs (complex (- (cadr circ) i) (- (caddr circ) j)))
                                                                                                 (car circ)))
                                                                                            circles)))
                                                                    color1 color2)))
                                     '(array (unsigned-byte 8) (*)))
                 :width width
                 :height height))

Exemple d'utilisation:

(let ((png (mk-png 300 200 '(255 200 0) '(128 0 255) '((25 50 80) (40 80 120) (300 -100 6) (17 253 162)))))
  (zpng:write-png png #p"path/to/file.png"))

Explication

(lambda (circ)
   (< (abs (complex (- (cadr circ) i) (- (caddr circ) j)))
      (car circ)))

Renvoie vrai si le point (i, j) se situe dans le cercle donné circ. La distance euclidienne est calculée en prenant la valeur absolue du nombre complexe qui représente le vecteur de (i, j) au centre de circ.

(evenp (count t (mapcar ___
                         circles)))

Mappez cette fonction sur la liste des cercles et vérifiez si le point donné (i, j) se situe dans un nombre pair de cercles.

(if ____
     color1 color2)

Sélectionnez la couleur en fonction de ce test.

(loop :for j :below height
       :nconc (loop :for i :below width
                    :append ____))

Rassemblez une liste plate de tous les octets RVB en bouclant sur chacun (i, j) de l'image et en ajoutant les listes résultantes ensemble.

(coerce ____
         '(array (unsigned-byte 8) (*)))

Convertissez cette liste d'octets en un tableau d'octets approprié, afin que zpng puisse l'intégrer correctement.

(make-instance 'zpng:png
                :image-data ____
                :width width
                :height height)

Créez l'objet png.

(defun mk-png (width height color1 color2 circles)
   ___)

Créez la fonction pour prendre la largeur, la hauteur, deux couleurs et la liste des cercles et renvoyer l'objet png créé.


0

JavaScript (ES6), 224 octets

J'ai vu la solution JS + SVG, mais je devais juste créer une solution basée sur le canevas ;-) Il s'agit d'une fonction qui renvoie un élément de canevas. Si un élément de canevas existant peut être fourni, supprimez 40 octets.

Appelez comme f(width, height, [[r1, g1, b1], [r2, g2, b2]], [[r1, x1, y1], [r2, x2, y2], ...])

let f =
(w,h,a,c,O=document.createElement`canvas`)=>{O.width=w;O.height=h;C=O.getContext`2d`;for(y=0;y<h;y++)for(x=0;x<w;x++)C.fillStyle=`rgb(${a[c.filter(([R,X,Y])=>(X-x)**2+(Y-y)**2<R**2).length%2]})`,C.fillRect(x,y,1,1);return O}

let tests = A.innerHTML.match(/.+/g);
A.innerHTML = "";
for (let i of tests) {
  let p = document.createElement("span");
  p.innerHTML = "<br>" + i.slice(0, 3);
  p.style["font-family"] = "monospace";
  A.append(p);
  A.append(f(100, 60, [[255,0,0], [0,0,255]],
    eval(`[${ i.slice(3).replace(/\(/g, "[").replace(/\)/g, "]") }]`)
  ));
}
<div id=A>
A. 
B. (13, 16, 20)
C. (30, 16, 20)
D. (200, 16, 20)
E. (42, 50, 20)
F. (42, 50, 20), (17, 40, 30)
G. (42, 50, 20), (17, 20, 30)
H. (42, 50, 20), (17, 10, 30), (10, 50, 30)
I. (42, 50, 20), (17, 10, 30), (35, 50, 20)
J. (18, 36, 40), (18, 63, 40), (18, 50, 20)
K. (100, -10, -20), (60, 50, -10)
L. (18, 36, 40), (18, 63, 40), (18, 50, 20), (14, 50, 20), (5, 50, 18), (20, 0, 0), (70, 22, 0), (10000, -9970, 0), (135, 100, -80)
</div>

Exemple de sortie:

cercles bicolores


0

Löve2D , 353 octets.

o=love.graphics
a=arg
w,h,r,g,b,R,G,B=...c={}for i=9,#a,3 do
c[#c+1]={a[i],a[i+1],a[i+2]}end
C=o.newCanvas(w,h)o.setCanvas(C)o.clear(R,G,B)for k,v in pairs(c)do
o.stencil(function()o.circle("fill",v[2],v[3],v[1],9^3)end,"invert",1,true)end
o.setStencilTest("greater",0)o.setColor(r,g,b)o.rectangle("fill",0,0,w,h)local
C:newImageData():encode("png","c")
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.