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


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.