ป้ายกำกับสิ้นสุดตาย


16

เมื่อได้รับอินพุตของ "ถนน" ASCII อาร์ตเอาท์พุทถนนที่มีป้ายระบุจุดจบทั้งหมด

นี่คือถนน:

########.....######..#..###
#......#######....#..#..#.#
#.##......#...#####..#..###
#..#####..#....#..#######.#
#......#...#####.....##...#
#..###.#...#...###...#..###
##########.#..#..##..#.##.#
..#......#.######.#..#.#.#.
..#......#.#..#.#.#..#.#.#.
..######.###..##..#########

นี่คือถนนที่มีจุดจบตายติดป้ายกำกับด้วยตัวอักษรX:

########.....######..X..###
#......#######....#..X..#.#
#.XX......X...X####..X..###
#..XXXXX..X....#..#######.#
#......X...#####.....##...#
#..###.X...#...###...#..###
##########.#..X..##..#.##.X
..X......#.#XXXXX.#..#.#.X.
..X......#.#..X.X.#..#.#.X.
..XXXXXX.###..XX..######XXX

ส่วนท้ายถูกกำหนดให้เป็นรูปแบบถนนใด ๆ ที่ล้อมรอบn รูปแบบของถนนอื่น ๆ อย่างน้อยn-1ซึ่งถือว่าเป็นจุดสิ้นสุดที่ตายแล้วตามกฎนี้ "Bordering" อยู่ในทิศทางที่สำคัญทั้งสี่ดังนั้นแผ่นที่มีพรมแดนติดกันจะไม่นับ

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

อินพุตและเอาต์พุตอาจเป็นสตริงเดี่ยว (โดยมีบรรทัดคั่นด้วยอักขระใด ๆ ที่ไม่ใช่#หรือ.) หรืออาร์เรย์ / list / etc หากภาษาของคุณรองรับคุณอาจป้อนข้อมูลด้วยแต่ละบรรทัดเป็นอาร์กิวเมนต์ของฟังก์ชัน

คุณอาจสันนิษฐานต่อไปนี้เกี่ยวกับอินพุต:

  • จะมี "ลูป" อย่างน้อยหนึ่งครั้งนั่นคือกลุ่มของ#อักขระที่สามารถติดตามได้อย่างไม่สิ้นสุด (มิฉะนั้นกระเบื้องทุกแผ่นจะกลายเป็นจุดจบ)

  • นี่หมายความว่าอินพุตจะเป็น 2 × 2 หรือใหญ่กว่าเสมอเนื่องจากลูปที่เล็กที่สุดคือ:

    ##
    ##
    

    (ซึ่งบังเอิญควรส่งออกโดยไม่มีการเปลี่ยนแปลง)

  • #ตัวละครทั้งหมดจะถูกเชื่อมต่อ นั่นคือถ้าคุณต้องเติมน้ำท่วมใด ๆ#พวกเขาทั้งหมดจะได้รับผลกระทบ

เนื่องจากนี่คือรหัสที่สั้นที่สุดเป็นไบต์จะเป็นผู้ชนะ

ตัวอย่างด้านบนและตารางขนาดเล็ก 2 × 2 สามารถใช้เป็นกรณีทดสอบได้ (มีกรณีขอบจำนวนไม่มากที่จะครอบคลุมในการท้าทายนี้)

คำตอบ:


8

CJam, 61 ไบต์

q_N/{{0f+zW%}4*3ew:z3few::z{e__4=_@1>2%'#e=*"#"='X@?}f%}@,*N*

ลองมันนี่

คำอธิบาย

Outline:

    q_N/               Read input lines
        {   }@,*       Perform some operation as many times as there are bytes
                N*     Join lines

Operation:

    {0f+zW%}4*         Box the maze with zeroes
    3ew:z3few::z       Mystical 4D array neighborhood magic.
                       (Think: a 2D array of little 3x3 neighborhood arrays.)

    {                        }f%    For each neighborhood, make a new char:
     e_                                 Flatten the neighborhood
       _4=_                             Get the center tile, C
           @1>2%                        Get the surrounding tiles
                '#e=                    Count surrounding roads, n
                    *                   Repeat char C n times
                     "#"=               Is it "#"? (i.e., C = '# and n = 1)
                         'X@?           Then this becomes an 'X, else keep C.

(มาร์ตินบันทึกสองไบต์ขอบคุณ!)


นั่นเป็นหนึ่งในคำตอบ cjam ที่ยาวที่สุดที่ฉันเคยเห็น =)
DJMcMayhem

2
@DJMcGoathem Ummm ...
Martin Ender

มี'#และ"#"แตกต่างกันใน CJam?
ETHproductions

ใช่พวกเขาเป็น จะมีค่าเท่ากับ"#" ['#]
ลินน์

5

JavaScript (ES6), 110 109 ไบต์

r=>[...r].map(_=>r=r.replace(g=/#/g,(_,i)=>(r[i+1]+r[i-1]+r[i+l]+r[i-l]).match(g)[1]||"X"),l=~r.search`
`)&&r

บันทึก 1 ไบต์ต้องขอบคุณ@ edc65 !

คำอธิบาย

วิธีการแก้ปัญหาที่ง่ายมาก การค้นหาสำหรับแต่ละ#และถ้ามีน้อยกว่า 2 #s รอบ ๆ Xมันแทนที่มันด้วย ทำซ้ำขั้นตอนนี้หลายครั้งจนกว่าจะรับประกันว่าจุดจบทั้งหมดจะถูกแทนที่ด้วยXs

var solution =

r=>
  [...r].map(_=>                    // repeat r.length times to guarantee completeness
    r=r.replace(g=/#/g,(_,i)=>      // search for each # at index i, update r once done
      (r[i+1]+r[i-1]+r[i+l]+r[i-l]) // create a string of each character adjacent to i
      .match(g)                     // get an array of all # matches in the string
        [1]                         // if element 1 is set, return # (the match is a #)
        ||"X"                       // else if element 1 is undefined, return X
    ),
    l=~r.search`
`                                   // l = line length
  )
  &&r                               // return the updated r
<textarea id="input" rows="10" cols="40">########.....######..#..###
#......#######....#..#..#.#
#.##......#...#####..#..###
#..#####..#....#..#######.#
#......#...#####.....##...#
#..###.#...#...###...#..###
##########.#..#..##..#.##.#
..#......#.######.#..#.#.#.
..#......#.#..#.#.#..#.#.#.
..######.###..##..#########</textarea><br>
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>


1
เคล็ดลับทั่วไปที่ฉันใช้สำหรับงานประเภทนี้เสมอ ในขณะที่คุณใช้ทั้งลิตรและ -l ในทางเดียวกันคุณสามารถคำนวณแทนl=~r.search l=1+r.search(บันทึกเพียง 1 ไบต์)
edc65

@ edc65 Clever ขอบคุณ!
user81655

0

Python (3.5) 362 331 329 314 ไบต์

ขอบคุณ @Alissa เธอช่วยให้ฉันได้รับรางวัล ~ 33 ไบต์

d='.'
r=range
def f(s):
 t=[list(d+i+d)for i in s.split()]
 c=len(t[0])
 u=[[d]*c]
 t=u+t+u
 l=len(t)
 g=lambda h,x:t[h][x]=='#'
 for k in r(l*c):
  for h in r(1,l):
   for x in r(1,c):
    if g(h,x) and g(h+1,x)+g(h-1,x)+g(h,x+1)+g(h,x-1)<2:
     t[h][x]='X'
 print('\n'.join([''.join(i[1:-1])for i in t][1:-1]))

คำอธิบาย

d='.'
r=range

นิยามฟังก์ชั่น

def f(s):

เพิ่มเส้นขอบของ '.' ด้านขวาและด้านซ้ายของกระดาน

 t=[list(d+i+d)for i in s.split()]
 c=len(t[0])
 u=[[d]*c]

เพิ่มเส้นขอบของ '.' ด้านบนและด้านล่าง

 t=u+t+u
 l=len(t)

ฟังก์ชั่นแลมบ์ดาทดสอบ '#'

 g=lambda h,x:t[h][x]=='#'

วนรอบความยาวอินพุตเพื่อให้แน่ใจว่าเราจะไม่ลืมปลายตาย

 for k in r(l*c):

วนรอบคอลัมน์และบรรทัด

  for h in r(1,l):
   for x in r(1,c):

ทดสอบว่าเรามี '#' รอบ ๆ และบนตำแหน่ง

    if g(h,x) and g(h+1,x)+g(h-1,x)+g(h,x+1)+g(h,x-1)<2:

แทนที่ '#' โดย 'X'

     t[h][x]='X'

ครอบตัดชายแดนที่เต็มไปด้วย '.' และเข้าร่วมในสตริง

 print('\n'.join([''.join(i[1:-1])for i in t][1:-1]))

การใช้

f("########.....######..#..###\n#......#######....#..#..#.#\n#.##......#...#####..#..###\n#..#####..#....#..#######.#\n#......#...#####.....##...#\n#..###.#...#...###...#..###\n##########.#..#..##..#.##.#\n..#......#.######.#..#.#.#.\n..#......#.#..#.#.#..#.#.#.\n..######.###..##..#########")

########.....######..X..###
#......#######....#..X..#.#
#.XX......X...X####..X..###
#..XXXXX..X....#..#######.#
#......X...#####.....##...#
#..###.X...#...###...#..###
##########.#..X..##..#.##.X
..X......#.#XXXXX.#..#.#.X.
..X......#.#..X.X.#..#.#.X.
..XXXXXX.###..XX..######XXX

1) ใช้แทนsplit() splitlines()2) t=['.'*(c+2)]+['.'+i+'.'for i in s]+['.'*(c+2)]สั้นกว่า และสามารถย่อให้สั้นลงได้อีก: d='.';t=[d*c]+t+[d*c];t=[d+i+d for i in t]3) คุณไม่จำเป็นต้องใช้ทุกรายการ (zip (.... )) สิ่งใช้print('\n'.join([''.join(i[1:-1])for i in t])
Alissa

ขอบคุณ @Alissa สำหรับความช่วยเหลือของฉันใช้เคล็ดลับของคุณสำหรับจุด 1) และ 3) แต่สำหรับ 2) 'str' object does not support item assignmentฉันไม่สามารถลบวงเล็บทั้งหมดเราต้องการรายชื่อของรายการของถ่านและไม่ใช่รายการของสตริงเพราะเป็น รายการของรายการอนุญาตให้ฉันใช้ t [h] [x] = 'X'
Erwan

ขอโทษฉันพลาดสิ่งที่เกี่ยวกับการเปลี่ยนรูปสตริง นอกจากนี้คุณยังสามารถย้ายค่าคงที่ทั้งหมด ( r, gและd) ออกจากการทำงานของคุณ (ช่วยให้คุณประหยัดการจัดระเบียบบางส่วน) บางทีผู้เล่นบางคนเล่นรอบการแยก () อาจช่วย: t=[d+list(i)+d for i in s.split()]จากนั้นคำนวณความยาวจากนั้นเพิ่มจุดเส้น - ที่จุดสิ้นสุดและเริ่มต้นจากนั้นเปลี่ยนวัฏจักรของคุณเพื่อทำงานกับความยาวที่ขยายเหล่านี้ ไม่แน่ใจว่ามันจะย่อรหัส แต่อาจ
Alissa

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