Двоколірні кола, що перекриваються


22

Напишіть програму або функцію, яка приймає наступний текст у розумному форматі на ваш вибір:

  • Два натуральних числа W і H, які визначають ширину і висоту зображення, яке ви будете створювати.

  • Два кольори RGB C1 і C2, які будуть використані для фарбування зображення.

  • Список 3-х кортезів форми, (r, x, y)які визначають кола з радіусом rта центром x, yу площині зображення. rє натуральним числом xі yє будь-якими цілими числами. Лівий верхній піксель зображення - 0, 0вісь x збільшується праворуч, а вісь y збільшується вниз.

Виведіть зображення розмірами W від H, пофарбованим C1 і C2 таким чином, що жодна дві сусідні області, визначені всіма колами, що перекриваються, не мають одного кольору.

Наприклад: Якщо вхід є

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)

тоді межі кола виглядають приблизно так:

приклад 1 межі кола

На зображенні, створеному колами, є шість чітких суміжних областей. Кожна область повинна бути пофарбована С1 (жовтий) або С2 (фіолетовий), щоб жодна сусідня область не була однакового кольору.

Це можна зробити двома способами, їх різниця полягає лише в тому, що кольори поміняються:

приклад 1 вихід 1 приклад 1 вихід 2

Таким чином, будь-яке з цих двох зображень буде дійсним результатом для прикладу введення.

Що - щось на зразок цього буде недійсним виходом , так як два жовтих областей межують один з одним.

Ваші вихідні зображення повинні відповідати цим рекомендаціям:

  • Крім C1 і C2, для меж кола можна використовувати третій нейтральний колір, такий як чорний або білий, якщо вони не перевищують 5 пікселів. (Чорні межі товщиною 1 пікселя є у наведеному вище прикладі.)

  • Однак межі кіл не потрібні. Регіони можуть сусідати один з одним безпосередньо:

    приклад 1 вихід 3 приклад 1 вихід 4

    І те, і інше, є ще одним дійсним результатом для прикладу вище.

  • Кола повинні бути максимально точними, використовуючи алгоритми малювання кіл або все, що надає ваша графічна бібліотека.

  • Взагалі, вдосконалення пікселів не потрібно, але якщо параметри введення масштабуються однаково великими та більшими, отримане зображення має ставати все більш точним.

  • Дозвіл згладжування дозволено, але не потрібно.

  • Сітки або мітки осі тощо у фоновому режимі заборонені.

Виграє найкоротший код у байтах.

Більше прикладів

Усі використовують ці входи з різними наборами кіл:

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

У будь-якому прикладі кольори можуть бути замінені та залишатися дійсними.

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. колишній В C. колишня С D. колишній D
E. ex E F. колишній F G. колишній G H. ex H
I. колишній я J. колишній J K. колишній К L. ex L

Переконайтесь, що ваш результат поводиться подібним до всіх цих прикладів.


Це добре виглядає, ми можемо виводити в ascii, наприклад, C1 дорівнює 1, а C2 - 0?
Метью Ро Ро

@MatthewRoh Ні. Я знаю, що це було б зручно, але зображення потрібні.
Захоплення Кальвіна

1
Гаразд тоді я здогадуюсь, я можу порахуватиtikz
Пшеничний майстер

1
@MatthewRoh, netpbm - це часто використовуваний формат зображення на цьому сайті.
Пітер Тейлор

2
@Luis Гаразд. Невеликі вхідні варіанти, як, наприклад, або з віссю y вгору, є нормальними.
Хобі Кальвіна

Відповіді:


14

Математика, 165 байт

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

Чиста функція, що бере чотири аргументи: ширина, висота (обидва цілих числа), впорядкована пара трійки чисел між 0 та 1 (що представляють два кольори RGB) та список елементів форми {r, {x, y}}для запису радіусів та центрів кола. Наприклад, перший приклад в ОП називатиметься аргументами [300, 200, {{1, 0.784, 0}, {0.5, 0, 1}}, {{25, {50, 80}}, {40, {80, 120}}, {300, {-100, 6}}, {17, {253, 162}}}]. Позитивна вісь y спрямована вгору в Mathematica.

Norm[{x,y}-#2]<#виявляє, чи знаходиться точка всередині даного кола; Boole[...]Piперетворює те Trueабо Falseв, πабо в 0. Після обчислення цих πs / 0s по всіх вхідних колах Trдодає їх і Cosперетворює парні кратні π до 1, непарні кратні π до –1. ContourPlot[...,Contours->{0}]то пофарбуйте відповідну область площини двома кольорами залежно від того, величина більша або менша 0. AspectRatio->Automaticробить кола схожими на кола; PlotPoints->5!надає гідну точність (збільшуйте її, 9!якщо ви дійсно хочете дивовижної картини, далеко в майбутньому!); Frame->Falseпозбавляється від осей; і ContourShading->RGBColor@@@#3використовує кольори введення для контурів.

Вибірка з першою парою кольорів (оскільки вони приємні), але останній набір кіл:

вибірка вибірки


11

JavaScript / SVG / HTML5, 219 байт

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 байт

Завантажте перекладача за посиланням 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 має широкий спектр кольорових режимів, що дозволяє будувати графіку растру відповідно до основних логічних операцій: АБО, І, XOR тощо.

Він також підтримує перепрограмування піддонів, тобто, наприклад, двоколірне зображення може перефарбувати свої кольори в будь-який з 4096 кольорів. Використовувана тут реалізація має деякі (недокументовані) відмінності від оригінальної реалізації BBC, в яких оператори EOR не були б необхідними.

Безумовно

  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

Типовий екран виводу

Приклад зображення масштабується на коефіцієнт 10 в одиницях / коефіцієнт 5 в пікселях (базовий BBC використовує 1 піксель = 2 одиниці.)

введіть тут опис зображення


10

MATL , 30 29 25 байт

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

Формат введення:

  • Кольорова карта як матриця значень між 0 і 255, де кожен рядок визначає колір
  • W
  • Н
  • Вектор стовпців центральних координат на основі 1 у вигляді складних значень ( x - реальна частина, y - уявна частина)
  • Вектор стовпців радіусів.

Спробуйте в MATL Online! Або перевірити останній тестовий випадок . (Перекладач все ще експериментальний. Вам може знадобитися оновити сторінку та спробувати ще раз, якщо вона не працює).

Пояснення

Код використовує складні числа для визначення сітки точок і для обчислення відстаней і широко використовує операції масиву з мовленням .

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
Я кажу, збережіть ці байти! : D
Грег Мартін

1
@GregMartin Ви праві. Кого хвилює елегантність, коли можна зберегти 4 байти! :-) Готово
Луїс Мендо

1
@LuisMendo Чим коротше, тим краще з codegolf, яким би потворним він не був. ;)
Кевін Круїссен

6

Python, використовуючи pypng , 140 138 байт

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

Приклад використання:

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

Завдяки xnor за збереження 2 байт.


Ласкаво просимо до коду гольфу! Для перевірки , якщо точка лежить в колі, одна хитрість полягає в використанні складної норми: abs(x-X+1j*(y-Y))<r.
xnor

3

Математика (неконкурентна)

(idk, як зробити LaTeX в PPCG, тому я використовував LaTeX для інструменту PNG)

Пояснення

Добуток множинних рівнянь кола ( (x-a)^2+(y-b)^2-r^2)> = 0 складе графік, необхідний для цього питання. У рівнянні, nє розмір масиву, а (x, y or r)_kце kй (x, y, or r)елемент.

Приклад

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

(Дякую WolframAlpha)

(Сюжет нерівності Вольфрам Альфа)

Отримати / Запустити рівняння для WolframAlpha

Отримання сценарію: Завершено

Запуск сценарію: Ще не зроблено

Тепер змусьте це працювати з Mathematica ...


Цікаво, чи дійсно це?
Метью Рох

Вам знадобиться перерахувати конкретний раніше існуючий інтерпретатор, який побудував би результат у потрібній формі, враховуючи цей вхід. Це дозволило б підрахувати в ньому байти. В даний час питання полягає в тому, що оскільки він не пов'язаний з перекладачем, він не прив'язаний до конкретного формату представлення рівняння, і, таким чином, позначення є неофіційними і неможливо об'єктивно порахувати. Навколо існує багато програм для побудови графіків рівнянь, тому, можливо, варто спробувати знайти його з коротким форматом введення.

@ ais523 Ой. Я спробую зробити так, щоб це працювало з WolframAlpha.
Метью Ро Ро

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

Функція генерує файл PPM на стандартному виході.

приклад:

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)

приклад


1

Загальний Lisp + Quicklisp + ZPNG 260 + 20 = 280 знаків

Це найширший код, який я коли-небудь писав у CL, і якби я не робив гольф з кодом, я би реструктурував це, щоб зробити його набагато легшим для читання ...

Прелюдія (20 символів)

(ql:quickload 'zpng)

Гольф (260 годин)

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

Безголівки:

(Використовується розблокування, щоб дозволити тестування та довші імена змінних для читабельності)

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

Приклад використання:

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

Пояснення

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

Повертає істину, якщо точка (i, j) потрапляє в межах заданого кола. Евклідова відстань обчислюється шляхом взяття абсолютного значення комплексного числа, яке представляє вектор від (i, j) до центру окружності.

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

Позначте карту, яка функціонує в списку кіл, і перевірте, чи не входить дана точка (i, j) в парну кількість кіл.

(if ____
     color1 color2)

Виберіть колір на основі цього тесту.

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

Зберіть разом плоский список усіх байтів rgb, перекинувшись на кожне (i, j) на зображенні та додавши отримані списки разом.

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

Перетворіть цей список байтів у належний масив байт, щоб zpng міг його правильно передати.

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

Створіть об'єкт png.

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

Створіть функцію, щоб взяти ширину, висоту, два кольори та список кіл та повернути створений png-об’єкт.


0

JavaScript (ES6), 224 байти

Я бачив рішення JS + SVG, але мені просто довелося створити рішення на основі полотна ;-) Це функція, яка повертає елемент полотна. Якщо наявний елемент полотна може бути наданий, видаліть 40 байт.

Телефонуйте як 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>

Приклад виводу:

двоколірні кола


0

Löve2D , 353 байт.

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")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.