Lindungi dinding saya dari pintu sial ini

20

Gagang pintu bagus dan semuanya, tetapi ketika Anda membuka pintu, pintu itu selalu mengelupas. Saya ingin Anda mengambil input seni ASCII dari sebuah ruangan, seperti ini:

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

Dan output ruangan dengan doorstop, seperti ini:

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

Spesifikasi:

  • Ruang ASCII (input) akan terdiri dari +, -, dan |. Karakter-karakter ini murni kosmetik; mereka semua bisa saja +tetapi itu akan terlihat mengerikan. Ini juga akan berisi engsel ( X) dan pintu ( /atau \).
  • Pintu terdiri dari /atau \. Mulai dari karakter "engsel", yaitu X, mereka akan langsung diagonal (perubahan 1 in xdan 1 in y) untuk 2 atau lebih unit (karakter).
  • Untuk menemukan di mana harus meletakkan palang pintu untuk sebuah pintu (selalu ada hanya satu palang pintu per pintu), temukan pintu untuk pintu tersebut. Pintu akan selalu dimulai pada satu engsel, dan pergi dengan jumlah ruang yang sama dengan panjang pintu naik, turun, kiri, atau kanan dari sana. Ruang selanjutnya setelah itu akan selalu menjadi tembok. Misalnya, di pintu ini, pintu ditandai oleh Ds:

       \
        \
    ---DDX-----
    

    Satu pintu ditemukan, cari tahu apakah Anda harus pergi searah jarum jam atau berlawanan arah jarum jam untuk mencapai pintu. Misalnya, dalam contoh pintu di atas, Anda harus bergerak searah jarum jam, dan yang ini, Anda harus berlawanan arah jarum jam:

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

    Setelah Anda tahu ke mana harus pergi, teruslah ke sana (mengabaikan pintu) sampai Anda mencapai dinding.

    Berikut visualisasi untuk contoh pintu di atas:

    visualisasi

    Biru adalah pintu, oranye menemukan bahwa Anda harus pergi searah jarum jam, dan merah terus berjalan searah jarum jam sampai dinding tercapai.

    Setelah Anda mencapai dinding, pergi ruang (panjang pintu) dari engsel ( X) di dinding itu, pindahkan satu ruang dari dinding ke arah pintu (sehingga Anda tidak menempatkan palang pintu tepat di dinding), dan masukkan .sana. Berikut ini contoh pintu yang sama yang menunjukkan bagaimana palang pintu dipasang:

       \
        \  .
    ---DDX12---
    

    Ulangi untuk setiap pintu, dan hasilkan hasilnya! Gunakan contoh input di bagian atas posting ini sebagai test case untuk memeriksa apakah program Anda valid.

    Perhatikan bahwa Anda tidak harus memegang pintu yang tidak muat di dindingnya, seperti:

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

    Atau:

         /
        /
       /
    +-X   --
    |
    |
    
  • Ini adalah , jadi kode terpendek dalam byte akan menang.
Gagang pintu
sumber
Apa aturan untuk pintu? Mereka harus ortogonal, sama panjangnya dengan pintu mereka, dan dikelilingi oleh dinding di satu sisi, dan engsel (untuk pintu kanan) di sisi lain?
John Dvorak
@JanDvorak Ok, diedit untuk klarifikasi
Doorknob
3
Bisakah kita berasumsi bahwa dinding yang dimulai pada engsel setidaknya memiliki panjang yang sama dengan pintu dan tidak ada dinding lain (tidak dimulai pada engsel) yang mengganggu pintu tertentu?
Howard
@ Bagaimana Saya tidak yakin apa yang Anda bicarakan. Apakah Anda bertanya apakah Anda dapat menganggap bahwa dinding yang berlawanan dari pintu sama dengan pintu? Jika demikian, maka tidak, karena pintu hanya bisa berayun 90 derajat seperti yang kedua dalam test case (menghitung dengan penempatan engsel mulai dari kiri atas).
Gagang Pintu
1
Hah? Pintunya diagonal. Semua string tersebut memiliki lebar 6 karakter, jadi tidak ada kolom tengah.
Peter Taylor

Jawaban:

4

Scala, 860 byte

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

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

Menggunakan OOP jelas merupakan pendekatan yang salah di sini, di belakang. Jika saya bisa melakukannya lagi saya pasti akan pergi dengan sekelompok tabel kebenaran hardcode.

Mobil saya yang lain adalah cadr
sumber