Protege mis paredes de estas puertas molestas

20

Los pomos de las puertas son geniales, pero cuando abres una puerta, siempre abolla las paredes a su alrededor. Necesito que ingreses el arte ASCII de una habitación, así:

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

Y haga salir la habitación con topes de puerta, así:

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

Especificación:

  • La habitación ASCII (entrada) constará de +, -, y |. Estos personajes son puramente cosméticos; todos podrían ser +s pero eso se vería horrible. También contendrá bisagras ( X) y puertas ( /o \).
  • Las puertas están formadas por /o \. A partir del carácter "bisagra", es decir X, irán directamente en diagonal (cambio de 1 pulg. xY 1 pulg. y) Para 2 o más unidades (caracteres).
  • Para encontrar dónde colocar el tope de una puerta (siempre hay solo un tope por puerta), busque la puerta de entrada para la puerta. La puerta siempre comenzará en una bisagra, y tendrá la misma cantidad de espacios que la longitud de la puerta hacia arriba, abajo, izquierda o derecha desde allí. El siguiente espacio después de eso siempre será un muro. Por ejemplo, en esta puerta, la entrada está marcada con Ds:

       \
        \
    ---DDX-----
    

    Una vez que se encuentra la puerta, averigüe si necesita ir en sentido horario o antihorario para llegar a la puerta. Por ejemplo, en esa puerta de ejemplo anterior, debe ir en el sentido de las agujas del reloj, y en esta, debe ir en sentido contrario a las agujas del reloj:

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

    Una vez que sepa qué camino tomar, siga por ese camino (ignorando la puerta) hasta llegar a una pared.

    Aquí hay una visualización de eso para la puerta de ejemplo anterior:

    visualización

    El azul es la puerta, el naranja está descubriendo que debes ir en el sentido de las agujas del reloj, y el rojo continúa yendo en el sentido de las agujas del reloj hasta llegar a una pared.

    Una vez que llegue a una pared, vaya (la longitud de la puerta) espacios desde la bisagra ( X) en esa pared, aleje un espacio de la pared hacia la puerta (para que no coloque el tope de la puerta en la pared) e inserte un .allí. Aquí está el mismo ejemplo de puerta que muestra cómo se coloca el tope:

       \
        \  .
    ---DDX12---
    

    ¡Repita para cada puerta y obtenga el resultado! Use la entrada de ejemplo en la parte superior de esta publicación como un caso de prueba para verificar si su programa es válido.

    Tenga en cuenta que no tiene que manejar puertas que no encajan en sus paredes, como por ejemplo:

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

    O:

         /
        /
       /
    +-X   --
    |
    |
    
  • Este es el , por lo que ganará el código más corto en bytes.
Pomo de la puerta
fuente
¿Cuáles son las reglas para las puertas? ¿Deben ser ortogonales, del mismo largo que sus puertas, y rodeados por una pared en un lado y una bisagra (para la puerta derecha) en el otro lado?
John Dvorak
@JanDvorak Ok, editado para la clarificación
Pomo
3
¿Podemos suponer que la pared que comienza en la bisagra tiene al menos la misma longitud que la puerta y que ninguna otra pared (que no comience en la bisagra) interfiere con esa puerta específica?
Howard
@Howard No estoy seguro de lo que estás hablando. ¿Está preguntando si puede suponer que la pared opuesta a la puerta tiene la misma longitud que la puerta? Si es así, entonces no, ya que la puerta solo podría girar 90 grados como la segunda en el caso de prueba (contando por la colocación de la bisagra comenzando desde la parte superior izquierda).
Pomo de la puerta
1
¿Eh? La puerta es diagonal. Todas esas cadenas tienen 6 caracteres de ancho, por lo que no hay una columna central.
Peter Taylor

Respuestas:

4

Scala, 860 bytes

Golfizado :

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

Sin golf :

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

Usar OOP fue definitivamente el enfoque equivocado aquí, en retrospectiva. Si pudiera hacerlo nuevamente, definitivamente iría con un montón de tablas de verdad codificadas.

Mi otro auto es un cadr
fuente