ปกป้องกำแพงของฉันจากประตูที่น่ารำคาญเหล่านี้


20

ลูกบิดประตูนั้นยอดเยี่ยมและทั้งหมด แต่เมื่อคุณเปิดประตูมันจะบุบผนังโดยรอบ ฉันต้องการให้คุณป้อนข้อมูลศิลปะ ASCII ของห้องเช่นนี้

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

และเอาท์พุทห้องที่มี doorstops เช่นนี้

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

รายละเอียด:

  • ห้อง ASCII (input) จะประกอบด้วย+, และ- |ตัวละครเหล่านี้เป็นเครื่องสำอางอย่างหมดจด พวกเขาทั้งหมดอาจเป็น+ของ แต่นั่นจะดูน่ากลัว มันจะมีบานพับ ( X) และประตู ( /หรือ\)
  • ประตูที่ทำขึ้นจากหรือ/ \เริ่มต้นจาก "บานพับ" ตัวละครซึ่งก็คือXพวกเขาจะไปในแนวทแยงมุมโดยตรง (เปลี่ยน 1 ในxและ 1 ในy) สำหรับ 2 หรือมากกว่าหน่วย (ตัวอักษร)
  • เมื่อต้องการค้นหาตำแหน่งที่จะใส่ประตูสำหรับประตู (มีเพียงหนึ่ง doorstop ต่อประตูเสมอ) ค้นหาประตูสำหรับประตู ทางเข้าประตูจะเริ่มต้นที่บานพับหนึ่งเสมอและไปที่ช่องว่างเท่ากันตามความยาวของประตูขึ้นลงซ้ายหรือขวาจากตรงนั้น พื้นที่ถัดไปหลังจากนั้นจะเป็นกำแพง ตัวอย่างเช่นในประตูนี้ทางเข้าประตูจะถูกทำเครื่องหมายด้วยDs:

       \
        \
    ---DDX-----
    

    พบประตูหนึ่งพบว่าคุณต้องไปตามเข็มนาฬิกาหรือทวนเข็มนาฬิกาเพื่อไปที่ประตู ตัวอย่างเช่นในประตูตัวอย่างข้างต้นคุณต้องไปตามเข็มนาฬิกาและในประตูนี้คุณต้องไปทวนเข็มนาฬิกา:

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

    เมื่อคุณรู้วิธีที่จะไปให้ไปทางนั้น (ละเว้นประตู) จนกว่าคุณจะถึงกำแพง

    นี่คือการสร้างภาพข้อมูลสำหรับประตูตัวอย่างด้านบน:

    การสร้างภาพ

    สีฟ้าคือทางเข้าประตูสีส้มกำลังพบว่าคุณต้องไปตามเข็มนาฬิกาและสีแดงจะยังคงตามเข็มนาฬิกาจนกว่าจะถึงกำแพง

    เมื่อคุณไปถึงกำแพงให้ไปที่ช่องว่าง (ความยาวของประตู) จากบานพับ ( X) บนผนังนั้นให้ขยับหนึ่งช่องว่างห่างจากผนังไปทางประตู.ที่นั่น ต่อไปนี้เป็นประตูตัวอย่างที่แสดงให้เห็นว่าการวางประตูหน้าประตูเป็นอย่างไร:

       \
        \  .
    ---DDX12---
    

    ทำซ้ำทุกประตูและเอาท์พุทผลลัพธ์! ใช้ตัวอย่างอินพุตที่ด้านบนของโพสต์นี้เป็นกรณีทดสอบเพื่อตรวจสอบว่าโปรแกรมของคุณถูกต้องหรือไม่

    โปรดทราบว่าคุณไม่จำเป็นต้องจัดการกับประตูที่ไม่พอดีกับผนังเช่น:

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

    หรือ:

         /
        /
       /
    +-X   --
    |
    |
    
  • นี่คือดังนั้นโค้ดที่สั้นที่สุดเป็นไบต์จะเป็นผู้ชนะ

กฎสำหรับประตูคืออะไร พวกเขาจะต้องเป็นมุมฉากความยาวเท่ากับประตูของพวกเขาและล้อมรอบด้วยกำแพงด้านหนึ่งและบานพับ (สำหรับประตูด้านขวา) ในอีกด้านหนึ่ง?
John Dvorak

@JanDvorak Ok, แก้ไขเพื่อความกระจ่าง
Doorknob

3
เราสามารถสันนิษฐานได้ว่าผนังที่เริ่มต้นที่บานพับนั้นมีความยาวเท่ากับประตูอย่างน้อยและไม่มีผนังอื่น ๆ (ไม่เริ่มที่บานพับ) รบกวนประตูที่เฉพาะเจาะจงหรือไม่
Howard

@Howard ฉันไม่แน่ใจว่าสิ่งที่คุณกำลังพูดถึง คุณถามว่าคุณสามารถสันนิษฐานได้หรือไม่ว่าผนังฝั่งตรงข้ามจากทางเข้านั้นมีความยาวเท่ากับทางเข้าประตู ถ้าเป็นเช่นนั้นไม่เพราะประตูสามารถแกว่งได้ 90 องศาเหมือนกับประตูที่สองในกรณีทดสอบ (นับโดยการจัดตำแหน่งบานพับโดยเริ่มจากด้านบนซ้าย)
Doorknob

1
ฮะ? ประตูเป็นแนวทะแยงมุม สตริงทั้งหมดนั้นมีความกว้าง 6 ตัวอักษรดังนั้นจึงไม่มีคอลัมน์กลาง
Peter Taylor

คำตอบ:


4

สกาลา, 860 ไบต์

Golfed :

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

เลิกเล่น :

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

การใช้ OOP เป็นวิธีการที่ผิดที่นี่แน่นอนในการเข้าใจถึงปัญหาหลังเหตุการณ์ ถ้าฉันสามารถทำมันได้อีกครั้งฉันจะไปกับตารางความจริงที่ฮาร์ดโค้ดอย่างแน่นอน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.