Видаліть безперешкодний прямокутник


20

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

основне зображення

Чорний та бордовий прямокутники є безперешкодними , тобто над ними немає інших прямокутників.

Напишіть програму, яка знімає подібне зображення та видаліть один-єдиний безперешкодний прямокутник, вивівши отримане зображення.

Приклад

Якщо ви запустили програму на зображенні вище і продовжували її повторно працювати на виході, вона може прогресувати так.

Виконання 1 - Чорний видалений (міг бути бордовим):

запустити 1

Виконання 2 - Maroon видалено (єдиний вибір):

запустити 2

Виконати 3 - Видалити жовтий (єдиний вибір):

запустити 3

Виконання 4 - Синій вилучено (міг бути зеленим):

запустити 4

Виконати 5 - Зняти зелений (єдиний вибір):

запустити 5

Запуск 6 - Коричневий видалено (єдиний вибір):

запустити 6

Виконати 7 - Червоний видалений (єдиний вибір):

запустити 7

Будь-які додаткові пробіги повинні створювати однакові білі зображення.

Сподіваємось, обмін стеками не втратив жодного з цих зображень.

Зображення завжди матиме білий фон, і кожен прямокутник буде унікальним кольором RGB, який не є білим.

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

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

приклад 1

На цьому зображенні червоний прямокутник можна було спочатку видалити (разом із чорним / бордовим / оранжевим / сірим):

приклад 2

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

Наприклад, ліве зображення тут може стати серединою або правою:

приклад 3 приклад 4 приклад 5

Вихідні дані не повинні мати парадоксальних перекриттів (тому створення алгоритму художника має бути можливим). Тож у цьому зображенні ( спасибі user23013 ) воно повинно бути зеленим під помаранчевим прямокутником:

приклад 6

Додаткові відомості

  • Зображення та прямокутники можуть мати будь-які розміри.
  • Прямокутники можуть стосуватися межі зображення.
  • Тут може бути до 256 3 - 1 прямокутників.
  • Якщо вхід повністю білий, вихід повинен бути також.
  • Ви можете використовувати бібліотеки зображень.
  • Вхідним документом має бути назва файлу зображення або неочищені дані зображення. Він може надходити зі stdin або командного рядка.
  • Вихід може бути записаний у той самий чи інший файл зображення, засипаний сировиною до stdout, або просто відображатися.
  • Будь загальний без втрат повноколірний формат файлу зображення допускається.

Виграє подання з найменшими байтами.



Технічно в вимогах немає нічого, що говорить про те, що вихід може не мати парадоксальних перекриттів. Чи слід додати, чи обидва тлумачення тестового випадку добре?
Джон Дворак

Чи можете ви уточнити "truecolor"?
FUZxxl


@JanDvorak Я сподівався, що це мається на увазі, але, ти маєш рацію, це незрозуміло, тому я додав до цього записку.
Захоплення Кальвіна

Відповіді:


10

CJam, 241 байт

(з видаленими новими рядками.)

rri:Hri:Vri:Q[q~]3/_Qa3*a+_|$W%:Pf{\a#}:AH/:B0ff*
P,,[AHAW%HBz:+_W%V\V]2/
ff{~@@f=/::|1#}0Ua4*t:R;
P0f<
V{H{BI=J=_2$=
0R{"I>! I+V<J>! J+H<"4/+4/z{~~}%:&1$*\)}%);2$-|t
}fJ}fI
[P,{_La#\1$0t1$f-}*;;]
{:TR=2/~\~V\-,>\f{\_3$=@~H\-,>{Tt}/t}~}/
:~Pf=:~
~]S*N

Він використовує формат файлу ppm. Приклад використання (використовуючи ImageMagick):

convert IVYvE.png -compress none ppm:-| (time /path/to/cjam-0.6.4.jar 1.cjam) |display

Ну, це занадто довго і занадто повільно ... Бігає хвилин за прикладом.

Я змінив розмір тестових випадків (і додав деякі інші), щоб полегшити тестування.

Здається, інформація про кольоровий простір втрачена, тому кольори трохи відрізняються.


2

Пітон, 690 651 610 606 594 569 байт

Сценарій читає ім'я зображення з stdin.

Він виявляє краї кожного прямокутника, сортує їх за кількістю різних кольорів, які вони містять (безперешкодні прямокутники містять лише 1 колір, а потім з’являються в кінці списку)

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

з імпорту PIL зображення як l, ImageDraw як D; з імпорту itertools *; O, R, I, Z, k = [], діапазон, l.open (raw_input ()), {}, лямбда x: -x [1 ]; (W, H), Q = I. розмір, I.load ()
для i, j у продукті (R (W), R (H)):
 c = Q [i, j]
 якщо c в Z: x, y, X, Y = Z [c]; Z [c] = [x, y, max (X, i), max (Y, j)]
 інше: Z [c] = [i, j, 0,0]
для n у перестановках (відсортовано ([(c, len ({Q [g] для g у продукті (R (x, X), R (y, Y))})) для c, (x, y, X, Y) у Z.items ()], ключ = k) [1: -1]): o = l.new (I.mode, I.size, 0xFFFFFF); [D.Draw (o) .rectangle (Z [c], fill = c) для c, _ в n]; O + = [(o, сума (abs (ab) для t, T in zip (I.getdata (), o.getdata ()) для a, b in zip (t, T)))]
max (O, ключ = k) [0]. show ()

0

Java - 1483 байти

Я не великий гольфіст з кодом, нехай це буде зрозуміло; тож багатослівність - це не зовсім вина Java ;-) Тим не менш, це здавалося справді цікавим викликом. Я вирішив це таким чином, що - я думаю - трохи нудний і багатослівний, але ей. Це працює, це (відносно) швидко і, особливо, було весело!

Ідея така: Перевірте кожен піксель починаючи з верхнього лівого кута аж до правого нижнього кута. Це білий піксель? Ігноруйте. Він кольоровий? Класно, давайте слідкуємо за цим і спробуємо визначити його межі (верхній лівий, верхній правий, нижній лівий, нижній правий).

Після цього перевірте площу кожного прямокутника. Чи містить він інший колір, ніж колір прямокутника? Потім з’ясуйте, який прямокутник належить до цього кольору та оновіть z-індекс, що перекриває прямокутник, на 1.

І нарешті, намалюйте всі прямокутники, враховуючи z-індекси. Він працює як z-індекс, який ви знаєте з CSS та інших 3D-речей. Прямокутники з найнижчим z-індексом малюються першими, найвищим z-індексом останніми.

import java.awt.*;import java.awt.image.*;import java.io.File;import java.util.*;import java.util.List;import javax.imageio.*;class A{class R{public Color k=new Color(-1);public int z;public Point a;public Point b;public Point c;public Point d;}public static void main(String[]w)throws Exception{BufferedImage i=ImageIO.read(new File(w[0]));List<R>r=new Vector<R>();for(int y=0;y<i.getHeight();y++){for(int x=0;x<i.getWidth();x++){Color c=new Color(i.getRGB(x,y));if(c.getRGB()==-1){continue;}R t=null;for(R s:r){if(s.k.equals(c)){t=s;}}if(t==null){t=new A().new R();r.add(t);}if(t.a==null){t.a=new Point(x, y);t.b=new Point(x, y);t.c=new Point(x, y);t.d=new Point(x, y);t.k=new Color(c.getRGB());}if(x<t.a.x){t.a.x=x;t.c.x=x;}if(x>t.b.x){t.b.x=x;t.d.x=x;}t.c.y=y;t.d.y=y;}}for(R s:r){List<Color>b=new Vector<Color>();for(int y=s.a.y;y<=s.c.y;y++){for(int x = s.a.x;x<=s.b.x;x++){if(i.getRGB(x, y)!=s.k.getRGB()){Color a=new Color(i.getRGB(x,y));boolean q=false;for(Color l:b){if(l.equals(a)){q=true;}}if(!q){b.add(a);} else {continue;}R f=null;for(R k:r){if(k.k.equals(a)){f=k;}}f.z=s.z+1;}}}}Collections.sort(r,new Comparator<R>(){public int compare(R a, R b){return a.z>b.z?1:(a.z==b.z?0:-1);}});for(int ii=r.size();ii>0;ii--){BufferedImage d=new BufferedImage(i.getWidth(),i.getHeight(),2);Graphics2D g=(Graphics2D)d.getGraphics();for(R s : r.subList(0, ii)){g.setColor(s.k);g.fillRect(s.a.x,s.a.y,s.b.x-s.a.x,s.c.y-s.a.y);}ImageIO.write(d,"png",new File(r.size()-ii+".png"));}}}

Повний код, який трохи - і це заниження ;-) - написаний чіткіше, можна знайти тут: http://pastebin.com/UjxUUXRp

Крім того, тепер, коли я бачу подання дієти, я міг зробити деякі частини простішими. Насправді не потрібно знаходити прямокутник, колір якого перекриває інший прямокутник. Я дійсно міг просто порахувати кількість кольорів, що «вторглись».

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