Schützen Sie meine Wände vor diesen lästigen Türen

20

Türklinken sind großartig, aber wenn Sie eine Tür öffnen, werden die Wände rundherum eingedrückt. Sie müssen die ASCII-Kunst eines Raums wie folgt eingeben:

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

Und geben Sie den Raum mit Türstopps wie folgt aus:

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

Spezifikation:

  • Der ASCII - Raum (Eingang) wird aus +, -und |. Diese Zeichen sind rein kosmetisch; sie könnten alle +s sein, aber das würde schrecklich aussehen. Es wird auch Scharniere ( X) und Türen ( /oder \) enthalten.
  • Türen bestehen aus /oder \. Ausgehend vom "Scharnier" -Zeichen Xwerden sie direkt diagonal (Änderung von 1 in xund 1 in y) für 2 oder mehr Einheiten (Zeichen) verschoben.
  • Um herauszufinden, wo sich der Türstopper für eine Tür befindet (es gibt immer nur einen Türstopper pro Tür), suchen Sie die Türöffnung für die Tür. Die Türöffnung beginnt immer an einem Scharnier und geht von dort aus um die gleiche Anzahl von Abständen wie die Türlänge nach oben, unten, links oder rechts. Der nächste Raum danach wird immer eine Mauer sein. In dieser Tür ist die Türöffnung beispielsweise mit Ds gekennzeichnet:

       \
        \
    ---DDX-----
    

    Wenn die Türöffnung gefunden ist, finden Sie heraus, ob Sie im oder gegen den Uhrzeigersinn gehen müssen, um zur Tür zu gelangen. In der obigen Beispieltür müssen Sie beispielsweise im Uhrzeigersinn und in dieser Tür gegen den Uhrzeigersinn gehen:

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

    Wenn Sie wissen, in welche Richtung Sie gehen sollen, gehen Sie so weiter (ohne die Tür zu beachten), bis Sie eine Wand erreichen.

    Hier ist eine Visualisierung davon für die Beispieltür oben:

    Visualisierung

    Das Blau ist die Türöffnung, das Orange stellt fest, dass Sie im Uhrzeigersinn gehen müssen, und das Rot fährt im Uhrzeigersinn fort, bis eine Wand erreicht ist.

    Wenn Sie an einer Wand angelangt sind, gehen Sie vom Scharnier ( X) an dieser Wand um (die Türlänge ) Lücken, bewegen Sie sich einen Abstand von der Wand zur Tür (damit Sie den Türstopper nicht direkt an der Wand anbringen), und setzen Sie ein .Dort. Das folgende Beispiel zeigt, wie der Türstopper platziert wird:

       \
        \  .
    ---DDX12---
    

    Wiederholen Sie dies für jede Tür und geben Sie das Ergebnis aus! Verwenden Sie die Beispieleingabe oben in diesem Beitrag als Testfall, um zu überprüfen, ob Ihr Programm gültig ist.

    Beachten Sie, dass Sie keine Türen handhaben müssen, die nicht an die Wände passen, wie zum Beispiel:

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

    Oder:

         /
        /
       /
    +-X   --
    |
    |
    
  • Das ist , also gewinnt der kürzeste Code in Bytes.
Türknauf
quelle
Was sind die Regeln für Türen? Sie müssen orthogonal sein, die gleiche Länge wie ihre Türen haben und auf der einen Seite von einer Wand und auf der anderen Seite von einem Scharnier (für die rechte Tür) umgeben sein.
John Dvorak
@ JanDvorak Ok, zur Klarstellung bearbeitet
Türklinke
3
Können wir annehmen, dass die Wand, die am Scharnier beginnt, mindestens die gleiche Länge wie die Tür hat und dass keine anderen Wände (die nicht am Scharnier beginnen) diese bestimmte Tür stören?
Howard
@ Howard Ich bin nicht sicher, wovon du sprichst. Fragen Sie sich, ob Sie davon ausgehen können, dass die gegenüberliegende Wand der Tür gleich lang ist wie die Tür? Wenn ja, dann nein, da die Tür wie die zweite im Testfall nur um 90 Grad schwingen konnte (gezählt durch Anbringen des Scharniers von links oben).
Türklinke
1
Huh? Die Tür ist diagonal. Alle diese Zeichenfolgen sind 6 Zeichen breit, daher gibt es keine mittlere Spalte.
Peter Taylor

Antworten:

4

Scala, 860 Bytes

Golf gespielt :

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

Nicht golfen :

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

Die Verwendung von OOP war hier im Nachhinein definitiv der falsche Ansatz. Wenn ich es noch einmal machen könnte, würde ich definitiv ein paar hartcodierte Wahrheitstabellen nehmen.

Mein anderes Auto ist ein Cadr
quelle