Proteggi i miei muri da queste fastidiose porte


20

Le maniglie delle porte sono fantastiche e tutte, ma quando apri una porta, ammaccano sempre le pareti attorno ad essa. Ho bisogno che tu prenda input dell'arte ASCII di una stanza, in questo modo:

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

E uscita la stanza con fermaporta, in questo modo:

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

Specifica:

  • La sala ASCII (ingresso) sarà composto da +, -e |. Questi personaggi sono puramente cosmetici; potrebbero essere tutti +s, ma sarebbe orribile. Conterrà anche cerniere ( X) e porte ( /o \).
  • Le porte sono costituite da /o \. A partire dal carattere "cerniera", ovvero X, andranno direttamente in diagonale (cambio di 1 in xe 1 in y) per 2 o più unità (caratteri).
  • Per trovare dove posizionare il fermaporta per una porta (c'è sempre solo un fermaporta per porta), trova la porta per la porta. La porta partirà sempre da una cerniera e da lì proseguirà la stessa quantità di spazi della lunghezza della porta su, giù, a sinistra o a destra. Il prossimo spazio dopo sarà sempre un muro. Ad esempio, in questa porta, la porta è contrassegnata da Ds:

       \
        \
    ---DDX-----
    

    Una volta trovata la porta, scopri se devi andare in senso orario o antiorario per raggiungere la porta. Ad esempio, in quella porta di esempio sopra, devi andare in senso orario, e in questo, devi andare in senso antiorario:

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

    Una volta che sai da che parte andare, continua così (ignorando la porta) fino a raggiungere un muro.

    Ecco una visualizzazione di questo per la porta di esempio sopra:

    visualizzazione

    Il blu è la porta, l'arancione sta scoprendo che devi andare in senso orario, e il rosso continua ad andare in senso orario fino a raggiungere un muro.

    Una volta raggiunto un muro, vai (la lunghezza della porta) spazi dalla cerniera ( X) su quel muro, sposta uno spazio dal muro verso la porta (in modo da non posizionare lo stipite proprio sul muro), e inserisci un .Là. Ecco lo stesso esempio di porta che mostra come è posizionato il fermaporta:

       \
        \  .
    ---DDX12---
    

    Ripetere l'operazione per ogni porta e produrre il risultato! Usa l'input di esempio nella parte superiore di questo post come test case per verificare se il tuo programma è valido.

    Si noti che non è necessario gestire porte che non si adattano alle loro pareti, come ad esempio:

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

    O:

         /
        /
       /
    +-X   --
    |
    |
    
  • Questo è , quindi vincerà il codice più breve in byte.

Quali sono le regole per le porte? Devono essere ortogonali, della stessa lunghezza delle loro porte e circondati da un muro su un lato e una cerniera (per la porta giusta) sull'altro lato?
John Dvorak,

@JanDvorak Ok, modificato per chiarimento
Maniglia della porta

3
Possiamo presumere che il muro che inizia dalla cerniera abbia almeno la stessa lunghezza della porta e che nessun altro muro (che non inizia dalla cerniera) interferisca con quella porta specifica?
Howard,

@Howard non sono sicuro di cosa stai parlando. Stai chiedendo se puoi supporre che la parete opposta dalla porta abbia la stessa lunghezza della porta? In tal caso, allora no, poiché la porta poteva solo oscillare di 90 gradi come la seconda nel caso di test (contando per posizionamento della cerniera a partire dall'angolo in alto a sinistra).
Maniglia della porta

1
Eh? La porta è diagonale. Tutte queste stringhe sono larghe 6 caratteri, quindi non c'è una colonna centrale.
Peter Taylor,

Risposte:


4

Scala, 860 byte

Golfato :

    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 golfato :

    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'uso di OOP è stato sicuramente l'approccio sbagliato qui, a ben vedere. Se potessi farlo di nuovo, sceglierei sicuramente un sacco di tabelle di verità codificate.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.