Bảo vệ tường của tôi khỏi những cánh cửa phiền phức


20

Doorknobs là tuyệt vời và tất cả, nhưng khi bạn mở một cánh cửa, nó luôn làm lõm các bức tường xung quanh nó. Tôi cần bạn tham gia vào nghệ thuật ASCII của một căn phòng, như thế này:

+---------+--X  --X    --+-----+
|       \     \   |\     |   \ |
|        \     \  | \    |    \|
|         X       |  \   |     X
|      /  |       |   \  X      
|     /   |     \       /       
|    /    |      \     /       |
+---X   --+-------X------+-----+

Và xuất phòng với các ô cửa, như thế này:

+---------+--X  --X    --+-----+
|       \  .  \   |\     |   \.|
|        \     \  | \   .|    \|
|         X       |  \   |     X
|      /  |       |.  \  X      
|     /  .|     \       /       
|.   /    |     .\     /       |
+---X   --+-------X------+-----+

Đặc điểm kỹ thuật:

  • Phòng ASCII (đầu vào) sẽ bao gồm +, -|. Những nhân vật này hoàn toàn là mỹ phẩm; tất cả họ có thể là +s nhưng điều đó sẽ trông thật kinh khủng. Nó cũng sẽ chứa bản lề ( X) và cửa ( /hoặc \).
  • Cửa được tạo thành từ /hoặc \. Bắt đầu từ ký tự "bản lề", nghĩa là Xchúng sẽ đi trực tiếp theo đường chéo (thay đổi 1 trong xvà 1 in y) cho 2 hoặc nhiều đơn vị (ký tự).
  • Để tìm nơi đặt cửa chặn cho một cánh cửa (luôn luôn chỉ có một cửa chặn mỗi cửa), hãy tìm cửa cho cửa. Các ô cửa sẽ luôn bắt đầu ở một bản lề và đi cùng một khoảng trống khi chiều dài của cửa lên, xuống, sang trái hoặc phải từ đó. Không gian tiếp theo sau đó sẽ luôn là một bức tường. Ví dụ, trong cánh cửa này, ô cửa được đánh dấu bằng Ds:

       \
        \
    ---DDX-----
    

    Một ô cửa được tìm thấy, tìm hiểu xem bạn cần đi theo chiều kim đồng hồ hay ngược chiều kim đồng hồ để đến cửa. Ví dụ, trong cửa ví dụ ở trên, bạn phải đi theo chiều kim đồng hồ, và trong cái này, bạn phải đi ngược chiều kim đồng hồ:

       \ <-
        \  )
    -----X  ---
    

    Một khi bạn biết con đường nào để đi, hãy tiếp tục đi theo con đường đó (bỏ qua cánh cửa) cho đến khi bạn đến được một bức tường.

    Đây là một hình ảnh trực quan cho cửa ví dụ ở trên:

    hình dung

    Màu xanh là ô cửa, màu cam đang phát hiện ra rằng bạn phải đi theo chiều kim đồng hồ và màu đỏ đang tiếp tục đi theo chiều kim đồng hồ cho đến khi đạt được một bức tường.

    Khi bạn đến được bức tường, hãy đi (chiều dài của cánh cửa) các khoảng trống từ bản lề ( X) trên bức tường đó, di chuyển một khoảng cách từ bức tường về phía cửa (vì vậy bạn không đặt cửa chặn ngay trên tường) và chèn một .ở đó Đây là cánh cửa ví dụ tương tự cho thấy cách đặt cửa:

       \
        \  .
    ---DDX12---
    

    Lặp lại cho mọi cánh cửa, và đưa ra kết quả! Sử dụng ví dụ đầu vào ở đầu bài này làm trường hợp kiểm tra để kiểm tra xem chương trình của bạn có hợp lệ không.

    Lưu ý rằng bạn không phải xử lý các cửa không khớp với tường của họ, chẳng hạn như:

    |     /
    |    /
    |   /
    |  /
    +-X    --
    

    Hoặc là:

         /
        /
       /
    +-X   --
    |
    |
    
  • Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ giành chiến thắng.

Các quy tắc cho các ô cửa là gì? Chúng phải trực giao, cùng chiều dài với cửa ra vào và được bao quanh bởi một bức tường ở một bên và bản lề (đối với cửa bên phải) ở phía bên kia?
John Dvorak

@JanDvorak Ok, được chỉnh sửa để làm rõ
Doorknob

3
Chúng ta có thể cho rằng bức tường bắt đầu từ bản lề ít nhất có cùng chiều dài với cửa và không có bức tường nào khác (không bắt đầu từ bản lề) cản trở cánh cửa cụ thể đó không?
Howard

@Howard Tôi không chắc bạn đang nói về cái gì. Bạn đang hỏi liệu bạn có thể cho rằng bức tường đối diện từ ô cửa có cùng chiều dài với ô cửa không? Nếu vậy, thì không, vì cánh cửa chỉ có thể xoay 90 độ như cái thứ hai trong trường hợp thử nghiệm (tính theo vị trí bản lề bắt đầu từ trên cùng bên trái).
Doorknob

1
Huh? Cửa có đường chéo. Tất cả các chuỗi đó đều rộng 6 ký tự, vì vậy không có cột giữa.
Peter Taylor

Câu trả lời:


4

Scala, 860 byte

Golfed :

    object D extends App{val s=args(0)split("\n")
    val r=Seq(P(1,0),P(1,-1),P(0,-1),P(-1,-1),P(-1,0),P(-1,1),P(0,1),P(1,1))
    var m=r(0)
    val e=s.map(_.toCharArray)
    case class P(x:Int,y:Int){def u=x==0||h
    def h=y==0
    def p(o:P)=P(x+o.x,y+o.y)
    def o="\\/".contains(c)
    def w="-|+".contains(c)
    def c=try s(y)(x) catch {case _=>'E'}
    def n=r.filter(!_.u).map(d => d.j(p(d))).sum
    def j(t:P):Int=if(t.o)1+j(p(t))else 0
    def q=if(c=='X'){m=this
    r.filter(_.u).map{d=>if(p(d).c==' '&&p(P(d.x*(n+1),d.y*(n+1))).w)d.i}}
    def i:Unit=Seq(r++r,(r++r).reverse).map(l=>l.drop(l.indexOf(this)+1)).map(_.take(4)).filter(_.exists(a=>a.p(m)o))(0).grouped(2).foreach{p=>if(p(1)p(m)w){p(0)add;return}}
    def add=if(r.filter(_.h).map(p(_)p(m)).exists(_.w))e(y*m.n+m.y)(x+m.x)='.'else e(y+m.y)(x*m.n+m.x)='.'}
    val f=args(0).size
    Array.tabulate(f,f){(i,j)=>P(i,j)q} 
    e.map(_.mkString).map(println)}

Chưa chơi gôn :

    object DoorknobCleanVersion extends App {
            val s = args(0) split ("\n")

            val r = Seq(P(1, 0), P(1, -1), P(0, -1), P(-1, -1), P(-1, 0), P(-1, 1), P(0, 1), P(1, 1))
            val HorizontalDirections = r.filter(_.isHorizontal)

            var hinge = r(0)
            val result = s.map(_.toCharArray)

            type I = Int
            case class P(x: Int, y: Int) {
                    def isCardinal = x == 0 || isHorizontal
                    def isHorizontal = y == 0

                    override def toString = x + "," + y

                    def p(o: P) = P(x + o.x, y + o.y)

                    def isDoor = Seq('\\', '/').contains(charAt)
                    def isWall = Seq('-', '|', '+').contains(charAt)

                    def charAt = try s(y)(x) catch { case _ => 'E' }

                    def doorLength = r.filter(!_.isCardinal).map(d => d.recursion2(p(d))).sum

                    def recursion2(currentPosition: P): Int =
                            if (currentPosition.isDoor)
                                    1 + recursion2(p(currentPosition))
                            else
                                    0

                    def findDoorway =
                            if (charAt == 'X') {
                                    hinge = this
                                    r.filter(_.isCardinal).map { d =>
                                            if (p(d).charAt == ' ' && p(P(d.x * (doorLength + 1), d.y * (doorLength + 1))).isWall)
                                                    d.getCorrectRotation2
                                    }
                            }

                    def getCorrectRotation2: Unit = Seq(r ++ r, (r ++ r).reverse).map(l => l.drop(l.indexOf(this) + 1))
                            .map(_.take(4))
                            .filter(_.exists(a => a.p(hinge)isDoor))(0)
                            .grouped(2)
                            .foreach {
                                    p =>
                                            if (p(1) p (hinge)isWall) {
                                                    p(0)add;
                                                    return
                                            }
                            }

                    def add =
                            if (HorizontalDirections.map(p(_) p (hinge)).exists(_.isWall))
                                    result(y * hinge.doorLength + hinge.y)(x + hinge.x) = '.'
                            else
                                    result(y + hinge.y)(x * hinge.doorLength + hinge.x) = '.'

            }

            val size = args(0).size
            Array.tabulate(size, size) { (i, j) => P(i, j).findDoorway }

            result.map(_.mkString).map(println)
    }

Sử dụng OOP chắc chắn là cách tiếp cận sai ở đây, trong nhận thức muộn màng. Nếu tôi có thể làm điều đó một lần nữa, tôi chắc chắn sẽ đi với một loạt các bảng chân lý được mã hóa cứng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.