Proteger minhas paredes dessas portas traquinas


20

As maçanetas são ótimas e tudo, mas quando você abre uma porta, ela sempre amolga as paredes ao seu redor. Eu preciso que você entenda a arte ASCII de uma sala, assim:

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

E produza a sala com batentes de porta, como este:

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

Especificação:

  • O quarto ASCII (entrada) vai consistir em +, -e |. Esses personagens são puramente cosméticos; todos poderiam ser +s, mas isso pareceria horrível. Também conterá dobradiças ( X) e portas ( /ou \).
  • As portas são compostas por /ou \. A partir do caractere "dobradiça", ou seja X, eles irão diretamente na diagonal (alteração de 1 pol xe 1 pol y) por 2 ou mais unidades (caracteres).
  • Para descobrir onde colocar o batente da porta (sempre há apenas um batente por porta), encontre a porta da porta. A porta sempre começa com uma dobradiça e tem a mesma quantidade de espaços que o comprimento da porta para cima, baixo, esquerda ou direita a partir daí. O próximo espaço depois disso sempre será uma parede. Por exemplo, nesta porta, a porta é marcada por Ds:

       \
        \
    ---DDX-----
    

    Quando a porta for encontrada, descubra se você precisa ir no sentido horário ou anti-horário para chegar à porta. Por exemplo, nesse exemplo da porta acima, você deve ir no sentido horário e, neste, deve ir no sentido anti-horário:

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

    Depois de saber qual caminho seguir, continue por esse caminho (ignorando a porta) até chegar a uma parede.

    Aqui está uma visualização disso para a porta de exemplo acima:

    visualização

    O azul é a porta, o laranja descobre que você deve ir no sentido horário e o vermelho continua no sentido horário até que uma parede seja atingida.

    Quando chegar a uma parede, vá (o comprimento da porta) para os espaços da dobradiça ( X) nessa parede, afaste um espaço da parede em direção à porta (para não colocar o batente da porta na parede) e insira um .há. Aqui está o mesmo exemplo de porta mostrando como o batente da porta é colocado:

       \
        \  .
    ---DDX12---
    

    Repita para cada porta e produza o resultado! Use o exemplo de entrada na parte superior desta postagem como um caso de teste para verificar se seu programa é válido.

    Observe que você não precisa lidar com portas que não se encaixam nas paredes, como:

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

    Ou:

         /
        /
       /
    +-X   --
    |
    |
    
  • Isso é , então o código mais curto em bytes vencerá.

Quais são as regras para portas? Eles devem ser ortogonais, do mesmo comprimento que suas portas, e cercados por uma parede de um lado e uma dobradiça (para a porta direita) do outro lado?
John Dvorak

@JanDvorak Ok, editado por clarificação
maçaneta

3
Podemos assumir que a parede que começa na dobradiça tem pelo menos o mesmo comprimento da porta e que nenhuma outra parede (que não começa na dobradiça) interfere com essa porta específica?
317 Howard

@ Howard Eu não tenho certeza do que você está falando. Você está perguntando se pode assumir que a parede oposta à porta tem o mesmo comprimento da porta? Se sim, então não, pois a porta só poderia oscilar 90 graus como a segunda no caso de teste (contando pela colocação da dobradiça começando no canto superior esquerdo).
Maçaneta

1
Hã? A porta é diagonal. Todas essas strings têm 6 caracteres de largura, portanto não há uma coluna do meio.
Peter Taylor

Respostas:


4

Scala, 860 bytes

Golfe :

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

Sem golfe :

    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 foi definitivamente a abordagem errada aqui, em retrospectiva. Se eu pudesse fazê-lo novamente, eu definitivamente iria com um monte de tabelas verdade codificadas.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.