Маленький Чендлер сумує. Намалюйте йому хмару, щоб підбадьорити його


57

Маленький Чендлер сумує. Намалюйте йому хмару, щоб підбадьорити його.
Примітка: малювання хмари насправді не розвеселить його.

Коло можна визначити як 3-кортеж, (x,y,r)де x- х положення кола на декартовій площині, y- y-положення кола на декартовій площині і rє радіусом кола. xі yможе бути негативним. rзавжди позитивний. Вхід - це список кіл у вигляді пробілів, розділених 3-кортежами. Наприклад:

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

В 3,1,1означає «коло з центральною точкою на 3,11 радіус. 3,2,1.5Чи означає» окружність з центром в точці точки 3,2з радіусом 1.5.

Якщо ми намалюємо всі ці кола вхідних даних на графіку, це виглядає приблизно так (я включив лінії сітки та мітки лише для наочності; вони не потрібні):

Графік

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

Припустимо, зараз ми намалюємо лінію, яка об’їжджає «кордон», утворений цими колами, без жодної іншої лінії. Це було б як намалювати межу силуету, сформованого всіма колами. Отримана хмара виглядатиме приблизно так:

хмара

Отже ця хмара була утворена шляхом малювання лише дуг кіл на вході, які утворюють межу, в результаті чого виходить одна форма. Іншими словами, хмара утворюється лише малюванням дуг, які не знаходяться в іншому колі. Ваша програма прийме введення у формі, поясненій вище, і виведе зображення, що відображає отриману хмару. Загальна форма хмари повинна бути правильною, але від вас залежить масштаб, колір, товщина ліній та те, як вона виглядає на вершинах. Зауважте, що хмара повинна бути видимою, тому ви не можете тягнути щось на кшталт "Ця програма малює білу хмару на білому фоні", "Ця програма малює хмару в нескінченно малому масштабі", "Ця програма малює хмару з 0 товщина лінії "тощо. Також зауважте, що колір облямівки повинен відрізнятися від кольору заливки або фону.

Ще один приклад. Вхід:

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

Вихід:

хмара2

Якщо в хмарі є «дірка», слід також намалювати отвір. Вхід:

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 

Вихід:

хмара3

Ось важливе правило: ваша програма повинна малювати лише лінії, що утворюють межу. Це означає, що ви НЕ МОЖЕТЕ просто намалювати кола повністю, а потім намалювати кола трохи менше білою заливкою - оскільки цей метод все ще малює лінії, які не утворюють межі, він просто прикриває їх згодом. Метою правила було заборонити реалізацію "намалювати кола, а потім намалювати кола знову білою заливкою" або щось подібне до цього. Очікується, що відповідь фактично розрахує, де намалювати речі, перш ніж малювати.

Це кодовий гольф, тому виграє найменший кількість символів.


13
+1 для графічного запитання із об'єктивним критерієм виграшу (та першого абзацу).
Денніс

2
Як ви можете сказати, якщо ми намалюємо рядок і стермемо його згодом? Чи рендеринг вказаних рядків на внутрішні растрові карти? Якщо ні, то де межа між вектором та растровим зображенням? Якщо так, то чому б нам не зробити те ж саме з первинним полотном (про яке ми знаємо, що має подвійний буфер, щоб користувач не міг бачити наші тимчасові лінії)?
Джон Дворак

1
@JanDvorak Метою правила було запобігти виконанню реалізацій "намалювати кола, потім знову намалювати кола з білою заливкою" або що-небудь подібне до цього. Очікується, що відповідь фактично розрахує, де намалювати речі, перш ніж малювати. Я відредагую, щоб зробити це більш зрозумілим.
абсент

15
Це питання абсолютно весело, коли встановлено Cloud to Butt ( chrome.google.com/webstore/detail/cloud-to-butt-plus/… ).
Erty Seidohl

9
@SomeKittens Я її втратив у "Якщо в хмарі є" дірка ", ти також повинен намалювати отвір".
Erty Seidohl

Відповіді:


25

Mathematica 177 126 121 119

Розв’язування дискових регіонів: підхід математика

Логіка полягає в тому, щоб

  • Створіть регіон 1 (R1), кола (без їх інтер'єрів);
  • Створіть регіон 2 (R2), диски (без меж кола).
  • Створіть регіон 3 (R3 = R1-R2).
  • -

умовивід області

Саме такий підхід застосовується нижче. Це дало 3 фігури вище.

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]

Неявна область №1 - це об'єднання кіл. Неявна область №2 - це об'єднання дисків, що лежать в колі. Їх відмінність - кордон.

RegionDifference [ImplicitRegion [
(- 3 + x) ^ 2 + (-1 + y) ^ 2 == 1 || (-3 + x) ^ 2 + (-2 + y) ^ 2 == 2,25 || (-1 + х) ^ 2 + (-2 + у) ^ 2 == 0,49 || (-0,9 + х) ^ 2 + (-1,2 + у) ^ 2 == 1,44 || (-1 + x) ^ 2 + y ^ 2 == 0,64, {x, y}],
неявнийрегіон [(- 3 + x) ^ 2 + (-1 + y) ^ 2 <1 || (-3 + x) ^ 2 + (-2 + y) ^ 2 <2,25 || (-1 + х) ^ 2 + (-2 + у) ^ 2 <0,49 || (-0,9 + х) ^ 2 + (-1,2 + у) ^ 2 <1,44 || (-1 + х) ^ 2 + у ^ 2 <0,64, {x, y}]]


Розв’язання дискових регіонів: підхід інженера (119 символів)

Далі йде об'єднання областей дисків, дискретизує цю область та виявляє її межу. Точки на діаграмі розмежовують інтервали сітки Делоне. Нижче ми відображаємо дискретизовану область, щоб виділити об'єкт, що забезпечує межу інтересу (контур хмари).

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"

Межі регіону дискретні.

reg1


Розв’язання шляхом виявлення країв: підхід фотографа - 121 знак

виявлення ребер

Він малює диски чорним кольором, раструє зображення, виявляє краї та інвертує чорно-білі.

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

Поголив 5 байтів:RegionBoundary@DiscretizeRegion@RegionUnion[{#,#2}~Disk~#3&@@@ToExpression[#~s~","]&@s@InputString[s=StringSplit]]
Мартін Ендер

Потенційно s=StringSplitвсередині підказки? Спробуйте перемістити цю панель ще раз, вона повинна бути коротшою, ніж ваша поточна версія.
Мартін Ендер

27

T-SQL 235 234 229 212 171 73 байт

Це використовує просторову функціональність у SQL Server 2012+. При його запуску в SSMS (SQL Server Management Studio) виробляється просторова область результатів. Вхід із змінної @i. Я міг би її ще більше зменшити, якщо введення можна взяти з таблиці.

Оскільки введення таблиці тепер дозволено.

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

Я залишив попереднє рішення нижче.

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

Редагування : Видалити паразитное простір, надлишок в і підзапит

171: Замінено створення таблиці на CTE та @s на @.

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

Розбивка динамічного SQL

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

Я отримую повідомлення про помилку'A' has fewer columns than were specified in the column list
Jesan Fafon,

@JesanFafon Переконайтесь, що ваша вхідна змінна @i встановлена ​​правильно. 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'. На жаль, я не можу перевірити його на даний момент, і SQLfiddle не грає чудово на 2012 рік.
MickyT

Приємна робота з функціями геометрії SQL. Хороші новини! Введення за попередньою таблицею тепер явно дозволено . Створення таблиць та сукупність не потрібно включати до складу байтів.
БредК

Я пограв у декілька персонажів. Посилання не дає результату. Але він працює в MS-sql студії управління сервером. Сценарій тут , насолоджуйтесь. Не соромтеся ним користуватися
t-clausen.dk

@ t-clausen.dk спасибі за це, але оскільки я збираюся оновити його, я зміню його на дозволений ввід таблиці. Я не збирався підкопувати цю резервну копію, але ...
MickyT

23

Математика, 175 158 149 байт

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

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

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

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

Безголівки:

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
ImplicitRegionавтоматично знаходить правильні значення x та y для побудови графіків. 122 символи:s = StringSplit; RegionPlot@ ImplicitRegion[ Or @@ (((x - #)^2 + (y - #2)^2 < #3^2) & @@@ (ToExpression[#~s~","] &@(s@InputString[]))), {x, y}]
DavidC

@DavidCarraher На жаль, це спотворює співвідношення сторін зображення. (Приємно знати всі ці регіональні функції, хоча - і ті, які ви використовували - я бачив лише RegionPlotпоки що.)
Мартін Ендер,

Ви, напевно, вже відзначали, що ,AspectRatio-> 1повертає код до 149 байт, саме там, де він зараз стоїть.
DavidC

2
Це я чи це зображення схоже на Марвіна Параноїда Android?
paqogomez

16

Python 3.3 ( 183 177 164 160 байт)

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

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

Оригінал:

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

Ще:

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

Отвір:

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

1
Мені подобається, що це єдине рішення мистецтва ascii.
vmrob

немає імпорту ... вражаючий!
Річард Грін

15

Пітон - 253 249 215 199

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

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

Вихід:

три хмари

Редагування:

  • 249: Замінено sys.argv[1:]на raw_input().split(), збереження аimport sys
  • 215: Вилучено k={'color':'k'}розкіш, замінено savefigнаshow
  • 199: Замінено map(float,s.split(','))наeval(s)

11

Пітон - 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
Це має великий потенціал для подальшого гольфу, наприклад, from math import*видалення необмежених пробілів, використання лише імен змінних з однієї літери, використання розуміння списку (наприклад, cc=[z for z in a if z!=a2 and (z[0]…)]). Ознайомтесь також із порадами щодо гольфу в Python .
Wrzlprmft

Ви можете зберегти деякі символи, скориставшись однобуквенною назвою змінної замість a2.
ProgramFOX

спасибі wrzl ... Я, мабуть, почну гольф сьогодні ввечері (інші речі робити зараз, але хотів поставити частку в землю)
Річард Грін,

1
так @ProgramFOX ... це була версія, яка працювала, і я можу налагоджувати ... скорочу це сьогодні сьогодні ...
Річард Грін,

3
@JamesWilliams, якщо ви хочете взяти естафету ... будь ласка, зробіть .. Я не захисний від коду !! Не соромтеся додати це як власний запис (доки ви зараховуєте оригінал!)
Річард Грін,

9

Пітон - 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()

Кредит належить до @ richard-green (дозвіл був наданий) за оригінальне рішення, я лише трохи його відбілив.


7
добре, що отримує мій голос ...
Річард Грін,

1
Можливо, ви зможете зберегти ще трохи, імпортуючи pylabзамість них matplotlib.pyplot.
ojdo

@odjo На даний момент на мобільному телефоні, якби я користувався from pylab import *, я все-таки зможу телефонувати show()і scatter()без будь-яких посилань?
Джеймс Вільямс

1
@JamesWilliams підтверджено! Pylab - забруднювач простору імен, який включає багато функцій, схожих на MATLAB :-)
ойдо

Ви можете скоротити це, використовуючи, [eval(i)for i in raw_input().split()]як пітон evalперетворюється 1,2,3на кортеж. Ви, звичайно, також повинні будете змінити [x,y,r]на "a" (x,y,r).
KSab

7

JavaScript (E6) + HTML 322

JSFiddle

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

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

Це приймає вхід від stdin і перевіряє кожну точку на дисплеї, малюючи пікселі по черзі в міру проходження. Не зовсім ефективний, але він дотримується всіх правил.

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

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

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

Приклади зображень:

1,4,2 5,2,1 3,1,1 3.5,2,1.2 3,3,0.7, 1,2,0.7 введіть тут опис зображення

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 введіть тут опис зображення


3
@ edc65 Я не зовсім впевнений, що ти маєш на увазі. Це точно робиться - це заповнити будь-який піксель, який знаходиться між 0 і 0,1 одиницями (від 0 до 2,5 пікселів) поза колами. Ви кажете, що слід математично знайти правильні дуги для малювання? Прочитавши питання, мені не здавалося, що це було обмеженням для мене.
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)."
"

Пише файл pbm в stdout.

Тестове зображення (перетворене в png):

Друге тестове зображення (перетворене в png)

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