เอาสี่เหลี่ยมผืนผ้าที่ไม่มีสิ่งกีดขวางออก


20

ภาพนี้สร้างขึ้นโดยการซ้อนทับสี่เหลี่ยมมุมฉาก 7 สีที่ต่างกัน:

ภาพหลัก

รูปสี่เหลี่ยมผืนผ้าสีดำและสีน้ำตาลแดงไม่มีสิ่งกีดขวางกล่าวคือไม่มีรูปสี่เหลี่ยมผืนผ้าอื่น ๆ

เขียนโปรแกรมที่ถ่ายภาพเช่นนี้และลบสี่เหลี่ยมที่ไม่มีสิ่งกีดขวางใด ๆ ออกภาพที่ได้ออกมา

ตัวอย่าง

หากคุณรันโปรแกรมของคุณบนภาพด้านบนและทำการรันซ้ำบนผลลัพธ์มันอาจจะเป็นแบบนี้

เรียกใช้ 1 - ลบสีดำ (อาจเป็นสีน้ำตาลแดง):

เรียกใช้ 1

Run 2 - Maroon ถูกลบ (ตัวเลือกเท่านั้น):

วิ่ง 2

เรียกใช้ 3 - ลบสีเหลือง (ตัวเลือกเท่านั้น):

วิ่ง 3

เรียกใช้ 4 - ลบสีน้ำเงิน (อาจเป็นสีเขียว):

เรียกใช้ 4

Run 5 - สีเขียวถูกลบ (ตัวเลือกเท่านั้น):

วิ่ง 5

เรียกใช้ 6 - ลบสีน้ำตาล (ตัวเลือกเท่านั้น):

เรียกใช้ 6

Run 7 - Red ถูกลบ (ตัวเลือกเท่านั้น):

วิ่ง 7

การวิ่งเพิ่มเติมใด ๆ ควรให้ภาพสีขาวเหมือนกัน

หวังว่า Stack Exchange จะไม่บีบอัดอิมเมจเหล่านี้ใด ๆ

ภาพจะมีพื้นหลังสีขาวอยู่เสมอและแต่ละสี่เหลี่ยมผืนผ้าจะเป็นสี RGB ที่ไม่ซ้ำใครซึ่งไม่ใช่สีขาว

คุณสามารถสันนิษฐานได้ว่าภาพสามารถตีความได้ว่าเป็นชุดของรูปสี่เหลี่ยมผืนผ้าที่ทับซ้อนกันเสมอ คุณสามารถสันนิษฐานได้ว่าสำหรับสีที่เจาะจงพิกเซลที่มีสีนั้นใกล้เคียงกับส่วนบนของภาพนั้นเป็นส่วนหนึ่งของขอบด้านบนของสี่เหลี่ยมสีนั้น สิ่งเดียวกันถือสำหรับขอบด้านล่างซ้ายและขวา

ตัวอย่างเช่นในภาพนี้ขอบด้านบนของสี่เหลี่ยมสีแดงจะอยู่ใต้ขอบด้านล่างของสี่เหลี่ยมสีเหลืองเนื่องจากสี่เหลี่ยมผืนผ้าสีส้มครอบคลุมขอบด้านบนสีแดงเก่า:

ตัวอย่างที่ 1

ในภาพนี้สี่เหลี่ยมสีแดงสามารถลบออกได้ก่อน (พร้อมด้วยสีดำ / สีน้ำตาลแดง / สีส้ม / สีเทา):

ตัวอย่างที่ 2

เมื่อลำดับสี่เหลี่ยมมุมล่างไม่ชัดเจนคุณสามารถให้ลำดับใดก็ได้

ตัวอย่างเช่นภาพซ้ายที่นี่อาจกลายเป็นตรงกลางหรือขวา:

ตัวอย่างที่ 3 ตัวอย่างที่ 4 ตัวอย่างที่ 5

เอาต์พุตไม่ควรมีการทับซ้อนที่ขัดแย้งกัน (ดังนั้นควรใช้อัลกอริธึมของจิตรกร ) ดังนั้นในภาพนี้ ( ขอบคุณผู้ใช้ 23013 ) มันจะต้องเป็นสีเขียวภายใต้สี่เหลี่ยมผืนผ้าสีส้ม:

ตัวอย่างที่ 6

รายละเอียดเพิ่มเติม

  • รูปภาพและสี่เหลี่ยมอาจมีขนาดใดก็ได้
  • สี่เหลี่ยมอาจสัมผัสกับเส้นขอบภาพ
  • อาจมีได้ถึง 256 3 - 1 สี่เหลี่ยม
  • หากอินพุตเป็นสีขาวทั้งหมดผลลัพธ์ก็ควรจะเป็นเช่นกัน
  • คุณอาจใช้ไลบรารีรูปภาพ
  • อินพุตควรเป็นชื่อไฟล์ภาพหรือข้อมูลภาพดิบ มันสามารถมาจาก stdin หรือบรรทัดคำสั่ง
  • เอาต์พุตสามารถถูกเขียนไปยังไฟล์รูปภาพเดียวกันหรือไฟล์อื่น, แบบ raw ที่เขียนไปยัง stdout, หรือแสดงแบบง่ายๆ
  • อนุญาตให้ใช้ไฟล์ภาพtruecolorแบบ lossless ทั่วไป

การส่งที่มีจำนวนไบต์น้อยที่สุดจะเป็นผู้ชนะ



ในทางเทคนิคไม่มีสิ่งใดในข้อกำหนดที่ระบุว่าผลลัพธ์อาจไม่มีทับซ้อนที่ขัดแย้งกัน มันควรจะเพิ่มหรือตีความทั้งสองกรณีทดสอบตกลง?
John Dvorak

คุณช่วยอธิบาย“ truecolor” ได้ไหม?
FUZxxl


@JanDvorak ฉันหวังว่ามันจะบอกเป็นนัย แต่คุณพูดถูกมันไม่ชัดเจนดังนั้นฉันจึงได้เพิ่มบันทึกเกี่ยวกับมัน
งานอดิเรกของ Calvin

คำตอบ:


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

Python, 690 651 610 606 594 569 ไบต์

สคริปต์อ่านชื่อภาพจาก stdin

มันตรวจจับขอบของทุกรูปสี่เหลี่ยมผืนผ้าเรียงลำดับตามจำนวนสีที่แตกต่างกันที่พวกเขามี (รูปสี่เหลี่ยมผืนผ้าที่ไม่มีสิ่งกีดขวางมีเพียง 1 สีจากนั้นปรากฏที่ท้ายรายการ)

รายการนี้ใช้เพื่อวาดภาพใหม่ ลำดับการวาดใหม่จะตัดสินใจโดยการเลือกการเรียงสับเปลี่ยนของรายการที่จะสร้างภาพออกที่มีความแตกต่างของพิกเซลน้อยที่สุดกับอินพุต

จาก PIL import ภาพเป็น l, ImageDraw เป็น D; จาก itertools import *; O, R, I, Z, k = [], ช่วง, l.open (raw_input ()), {}, lambda x: -x [1 ] (W, H), Q = I.size, I.load ()
สำหรับ i, j ในผลิตภัณฑ์ (R (W), R (H)):
 c = Q [i, เจ]
 ถ้า c ใน Z: x, y, X, Y = Z [c]; Z [c] = [x, y, สูงสุด (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 ()], key = k) [1: -1]): o = l.new (I.mode, I.size, 0xFFFFFF); [D.Draw (o). สี่เหลี่ยมผืนผ้า (Z) [c], เติม = c) สำหรับ c, _ in n]; O + = [(o, ผลรวม (abs (ab)) สำหรับ t, T in zip (I.getdata (), o.getdata ()) สำหรับ a, b ใน zip (t, T)))]
สูงสุด (O คีย์ = k) [0] .show ()

0

Java - 1483 ไบต์

ฉันไม่ใช่นักกอล์ฟที่เก่งรหัสให้ชัดเจน ดังนั้นการใช้คำฟุ่มเฟือยจึงไม่ใช่ความผิดทั้งหมดของ Java ;-) อย่างไรก็ตามนี่เป็นความท้าทายที่สนุกจริงๆ ฉันแก้ไขมันในแบบที่ฉันคิดว่ามันน่าเบื่อและ verbose แต่เฮ้ มันใช้งานได้มันเร็วพอสมควรและสนุกมาก!

แนวคิดมีดังต่อไปนี้: ตรวจสอบแต่ละพิกเซลจากเริ่มต้นที่มุมซ้ายบนไปจนถึงล่างขวา มันเป็นพิกเซลสีขาวหรือไม่? ไม่สนใจ มันเป็นสีหรือไม่ เยี่ยมลองติดตามมันและพยายามหาขอบเขต (ซ้ายบนขวาบนล่างซ้ายล่างขวา)

เมื่อเสร็จแล้วให้ตรวจสอบพื้นที่ของสี่เหลี่ยมผืนผ้าแต่ละอัน มันมีสีที่แตกต่างจากสีของสี่เหลี่ยมผืนผ้าหรือไม่? จากนั้นหาสิ่งที่สี่เหลี่ยมผืนผ้าเป็นของสีนั้นและอัพเดทดัชนี z ที่ซ้อนทับกัน 1

และสุดท้ายวาดสี่เหลี่ยมทั้งหมดโดยคำนึงถึงดัชนี z ใช้งานได้จริงเหมือนกับดัชนี z ที่คุณรู้จักจาก CSS และเนื้อหา 3 มิติอื่น ๆ สี่เหลี่ยมที่มีดัชนีซีต่ำที่สุดจะถูกวาดก่อนเป็นอันดับแรกดัชนีซีสูงสุด

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"));}}}

รหัสที่สมบูรณ์ซึ่งเป็นบิต - และนั่นคือ understatement ;-) - เขียนชัดเจนยิ่งขึ้นสามารถพบได้ที่นี่: http://pastebin.com/UjxUUXRp

นอกจากนี้เมื่อฉันเห็นการยอมแพ้ของผู้อดสูฉันก็สามารถทำให้บางส่วนง่ายขึ้น ไม่จำเป็นต้องค้นหาสี่เหลี่ยมที่มีสีซ้อนทับสี่เหลี่ยมผืนผ้าอื่น ฉันสามารถนับจำนวนสีที่ 'บุกรุก' ได้อย่างแน่นอน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.