Protège mes murs de ces portes embêtantes

20

Les poignées de porte sont superbes et tout, mais lorsque vous ouvrez une porte, elle enfonce toujours les murs autour d'elle. J'ai besoin que vous preniez connaissance de l'art ASCII d'une pièce, comme ceci:

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

Et sortez la pièce avec des butées de porte, comme ceci:

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

Spécification:

  • La salle ASCII (entrée) sera composé de +, -et |. Ces personnages sont purement cosmétiques; ils pourraient tous être +s mais cela aurait l'air horrible. Il contiendra également des charnières ( X) et des portes ( /ou \).
  • Les portes sont constituées de /ou \. En partant du caractère "charnière", c'est-à- Xdire qu'ils iront directement en diagonale (changement de 1 pouce xet 1 pouce y) pour 2 unités ou plus (caractères).
  • Pour trouver où placer le butoir d'une porte (il n'y a toujours qu'un seul butoir par porte), recherchez le seuil de la porte. La porte commencera toujours par une charnière et ira de la même quantité d'espace que la longueur de la porte vers le haut, le bas, la gauche ou la droite à partir de là. L'espace suivant après cela sera toujours un mur. Par exemple, dans cette porte, la porte est marquée par Ds:

       \
        \
    ---DDX-----
    

    Une fois la porte trouvée, découvrez si vous devez aller dans le sens horaire ou antihoraire pour atteindre la porte. Par exemple, dans cet exemple de porte ci-dessus, vous devez aller dans le sens horaire, et dans celui-ci, vous devez aller dans le sens antihoraire:

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

    Une fois que vous savez où aller, continuez comme ça (en ignorant la porte) jusqu'à ce que vous atteigniez un mur.

    Voici une visualisation de cela pour l'exemple de porte ci-dessus:

    visualisation

    Le bleu est la porte, l'orange constate que vous devez aller dans le sens horaire, et le rouge continue dans le sens horaire jusqu'à ce qu'un mur soit atteint.

    Une fois que vous atteignez un mur, passez (la longueur de la porte) des espaces de la charnière ( X) sur ce mur, éloignez-vous d'un espace du mur vers la porte (afin de ne pas placer le butoir de porte directement sur le mur) et insérez un .Là. Voici le même exemple de porte montrant comment le butoir de porte est placé:

       \
        \  .
    ---DDX12---
    

    Répétez l'opération pour chaque porte et affichez le résultat! Utilisez l'exemple d'entrée en haut de cet article comme cas de test pour vérifier si votre programme est valide.

    Notez que vous n'avez pas à manipuler des portes qui ne tiennent pas sur leurs murs, telles que:

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

    Ou:

         /
        /
       /
    +-X   --
    |
    |
    
  • Il s'agit de , donc le code le plus court en octets gagnera.
Poignée de porte
la source
Quelles sont les règles pour les portes? Ils doivent être orthogonaux, de la même longueur que leurs portes et entourés d'un mur d'un côté et d'une charnière (pour la porte de droite) de l'autre côté?
John Dvorak
@JanDvorak Ok, édité pour clarification
Poignée de porte
3
Pouvons-nous supposer que le mur commençant à la charnière est au moins de la même longueur que la porte et qu'aucun autre mur (ne commençant pas à la charnière) n'interfère avec cette porte spécifique?
Howard
@Howard, je ne sais pas de quoi vous parlez. Demandez-vous si vous pouvez supposer que le mur opposé à la porte est de la même longueur que la porte? Si c'est le cas, alors non, car la porte ne pouvait pivoter que de 90 degrés comme la seconde dans le cas de test (en comptant par le placement des charnières en partant du haut à gauche).
Poignée de porte
1
Hein? La porte est diagonale. Toutes ces chaînes ont une largeur de 6 caractères, il n'y a donc pas de colonne du milieu.
Peter Taylor

Réponses:

4

Scala, 860 octets

Golfé :

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

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

L'utilisation de la POO était définitivement la mauvaise approche ici, avec le recul. Si je pouvais le refaire, j'irais certainement avec un tas de tables de vérité codées en dur.

Mon autre voiture est un cadr
la source