이 성가신 문에서 내 벽을 보호


20

손잡이는 훌륭하지만 모두 문을 열면 항상 주변 벽이 움푹 들어갑니다. 다음과 같이 방의 ASCII 아트를 입력해야합니다.

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

그리고 다음과 같이 문을 정지시켜 방을 출력하십시오 :

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

사양:

  • 아스키 실 (입력)으로 구성된다 +, -그리고 |. 이 캐릭터는 순전히 장식 적입니다. 그들은 모두 +s 가 될 수 있지만 끔찍하게 보일 것입니다. 또한 경첩 ( X)과 문 ( /또는 \)이 포함됩니다.
  • 문은 /또는으로 구성 \됩니다. "hinge"문자부터 시작하여 2 개 이상의 단위 (문자)에 대해 X대각선으로 직접 이동합니다 (1 in x및 1 in 변경 y).
  • 문에 문정지를 배치 할 위치를 찾으려면 (문마다 항상 하나의 문정지가 있음) 문에 대한 출입구를 찾으십시오. 출입구는 항상 하나의 경첩에서 시작하여 출입문의 길이와 위, 아래, 왼쪽 또는 오른쪽과 같은 양의 공간으로 이동합니다. 그 후의 다음 공간은 항상 벽입니다. 예를 들어이 문에서 출입구는 Ds 로 표시됩니다 .

       \
        \
    ---DDX-----
    

    출입구가 발견되면 문에 도달하기 위해 시계 방향 또는 시계 반대 방향으로 이동해야하는지 확인하십시오. 예를 들어 위의 예시 문에서 시계 방향으로 이동해야하며이 문에서는 시계 반대 방향으로 이동해야합니다.

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

    갈 길을 알고 나면 벽에 닿을 때까지 계속 문을 무시하십시오.

    위의 예시 문에 대한 시각화는 다음과 같습니다.

    심상

    파란색은 출입구이고 주황색은 시계 방향으로 가야한다는 것을 발견하고 빨간색은 벽에 도달 할 때까지 시계 방향으로 계속 진행합니다.

    벽에 도달하면 벽의 경첩 ( X)에서 (문의 길이) 공간으로 이동하여 벽에서 문쪽으로 한 공간을 이동하여 문을 바로 벽에 배치하지 마십시오. .그곳에. 문정지가 어떻게 배치되는지 보여주는 문 예는 다음과 같습니다.

       \
        \  .
    ---DDX12---
    

    모든 문에 대해 반복하고 결과를 출력하십시오! 이 게시물 상단의 예제 입력을 테스트 사례로 사용하여 프로그램이 유효한지 확인하십시오.

    벽에 맞지 않는 문은 다음과 같이 처리 할 필요가 없습니다.

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

    또는:

         /
        /
       /
    +-X   --
    |
    |
    
  • 이것은 이므로 바이트 단위의 가장 짧은 코드가 승리합니다.

출입구에 대한 규칙은 무엇입니까? 그것들은 직각이어야하고, 문들과 같은 길이 여야하고, 한쪽면에 벽으로 둘러싸이고 다른 쪽면에 힌지 (오른쪽 문용)로 둘러싸여 야합니까?
John Dvorak

해명을 편집 @JanDvorak 좋아,
손잡이

3
경첩에서 시작하는 벽의 길이가 문과 길이가 같고 다른 벽 (힌지에서 시작하지 않음)이 특정 문을 방해하지 않는다고 가정 할 수 있습니까?
Howard

@Howard 나는 당신이 무슨 말을하는지 모르겠습니다. 출입구의 반대쪽 벽과 출입구의 길이가 같다고 가정 할 수 있습니까? 그렇다면 문은 테스트 케이스의 두 번째 문과 같이 90 도만 움직일 수 있기 때문입니다 (왼쪽 상단에서 시작하는 힌지 배치로 계산).
Doorknob

1
응? 문은 대각선입니다. 이 문자열은 모두 6 자이므로 가운데 열이 없습니다.
피터 테일러

답변:


4

스칼라, 860 바이트

골프 :

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

언 골프 :

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

여기에서 OOP를 사용하는 것은 분명히 잘못된 접근법이었습니다. 내가 다시 할 수 있다면 분명히 하드 코딩 된 진리표와 함께 갈 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.