Label jalan buntu

16

Diberikan masukan dari "jalan" seni ASCII, menampilkan jalan dengan semua jalan buntu berlabel.

Ini jalan:

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

Ini adalah jalan dengan jalan buntu yang berlabel huruf X:

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

Jalan buntu didefinisikan sebagai setiap ubin jalan yang berbatasan dengan n ubin jalan lain, setidaknya n-1 yang dianggap sudah mati oleh peraturan ini. "Berbatasan" ada di empat arah mata angin, jadi ubin yang berbatasan secara diagonal tidak masuk hitungan.

Aturan ini diterapkan berulang kali, karena jalan buntu yang baru dibuat dapat, dengan sendirinya, menciptakan lebih banyak jalan buntu . Perhatikan juga bahwa ubin jalan apa pun yang berbatasan hanya dengan satu ubin jalan lain dianggap buntu saat pertama kali aturan diterapkan.

Input dan output dapat berupa string tunggal (dengan garis yang dipisahkan oleh karakter apa pun yang bukan #atau .) atau array / daftar / dll. Jika bahasa Anda mendukungnya, Anda juga dapat mengambil input dengan setiap baris menjadi argumen fungsi.

Anda dapat mengasumsikan berikut tentang input:

  • Akan selalu ada setidaknya satu "loop" —yaitu, sekelompok #karakter yang dapat diikuti tanpa batas. (Kalau tidak, setiap ubin akan menjadi jalan buntu.)

  • Ini menyiratkan bahwa input akan selalu 2 × 2 atau lebih besar, karena loop terkecil adalah:

    ##
    ##
    

    (Yang, kebetulan, harus berupa output tanpa perubahan.)

  • Semua #karakter akan terhubung. Artinya, jika Anda melakukan mengisi banjir pada siapa saja #, semuanya akan terpengaruh.

Karena ini adalah , kode terpendek dalam byte akan menang.

Contoh di atas dan kisi 2 × 2 yang kecil dapat digunakan sebagai kasus uji (tidak ada banyak kasus tepi untuk dibahas dalam tantangan ini).

Gagang pintu
sumber

Jawaban:

8

CJam, 61 byte

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

Coba di sini .

Penjelasan

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.

(Martin menyelamatkan dua byte, terima kasih!)

Lynn
sumber
Itu salah satu jawaban cjam terpanjang yang pernah saya lihat. =)
DJMcMayhem
2
@DJMcGoathem Ummm ...
Martin Ender
Apakah '#dan "#"berbeda di CJam?
ETHproduk
Ya mereka. "#"sama dengan ['#].
Lynn
5

JavaScript (ES6), 110 109 byte

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 byte disimpan berkat @ edc65 !

Penjelasan

Pendekatan yang sangat sederhana untuk masalah ini. Mencari masing-masing #, dan jika ada kurang dari 2 #s di sekitarnya, gantikan dengan X. Ulangi proses ini berkali-kali sampai dijamin semua jalan buntu telah diganti dengan 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>

pengguna81655
sumber
1
Trik umum yang saya gunakan selalu untuk jenis tugas ini. Saat Anda menggunakan l dan -l dengan cara yang sama, Anda dapat menghitung l=~r.searchalih-alih l=1+r.search. (Hanya 1 byte disimpan)
edc65
@ edc65 Pintar. Terima kasih!
user81655
0

Python (3.5) 362 331 329 314 byte

terima kasih kepada @Alissa. dia membantu saya memenangkan ~ 33 byte

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

Penjelasan

d='.'
r=range

Definisi fungsi

def f(s):

Tambahkan batas '.' di kanan dan kiri papan

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

Tambahkan batas '.' di atas dan bawah

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

Fungsi Lambda untuk menguji '#'

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

Ulangi panjang input untuk memastikan kami tidak melupakan jalan buntu

 for k in r(l*c):

Ulangi kolom dan garis

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

Uji apakah kita memiliki '#' di sekitar dan di posisi

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

Ganti '#' dengan 'X'

     t[h][x]='X'

Pangkas perbatasan yang diisi dengan '.' dan bergabung dalam string

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

Pemakaian

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
Erwan
sumber
1) gunakan split()sebagai ganti splitlines(). 2) t=['.'*(c+2)]+['.'+i+'.'for i in s]+['.'*(c+2)]lebih pendek. Dan itu dapat dipersingkat bahkan lebih: d='.';t=[d*c]+t+[d*c];t=[d+i+d for i in t]3) Anda tidak perlu semua daftar (zip (....)), gunakanprint('\n'.join([''.join(i[1:-1])for i in t])
Alissa
@ Alissa terima kasih atas bantuan Anda saya menggunakan tips Anda untuk poin 1) dan 3) tetapi untuk 2) saya tidak dapat menghapus semua braket, kita perlu daftar daftar char dan bukan daftar string karena 'str' object does not support item assignment. daftar daftar memungkinkan saya untuk menggunakan t [h] [x] = 'X'
Erwan
maaf, saya melewatkan hal tentang string immutability. Anda juga dapat memindahkan semua konstanta ( r, gdan d) dari fungsi Anda (menghemat beberapa tabulasi). Mungkin beberapa bermain di sekitar split () mungkin membantu t=[d+list(i)+d for i in s.split()]:, kemudian menghitung panjang, kemudian menambahkan garis-titik ke akhir dan ke awal, dan kemudian mengubah siklus Anda untuk bekerja dengan panjang yang diperpanjang ini. Tidak yakin apakah itu akan mempersingkat kodenya, tetapi mungkin
Alissa
@Alissa saya tidak bisa mengeluarkan g dari fungsi karena menggunakan t saya akan menguji komentar Anda yang lain
Erwan