Çıkmazları etiketle


16

Bir ASCII sanat "yolu" girdisi verildiğinde, tüm çıkmaz sokaklar etiketli olarak yola çıktı.

Bu bir yol:

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

Bu, çıkıntıları harfle etiketlenmiş yol X:

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

Bir çıkmaz herhangi bir yol karo olarak tanımlandığını sınırlar n en az diğer yol fayans, n-1 mütalaa edilen, çıkmaz bu kuralla zaten. "Bordering" dört kardinal yöndedir, bu nedenle çapraz olarak çevrilmiş fayanslar sayılmaz.

Bu kural tekrar tekrar uygulanır, çünkü yeni oluşturulan çıkmazlar kendileri daha fazla çıkmaz oluşturabilir . Ayrıca, yalnızca bir başka yol döşemesini sınırlayan herhangi bir yol döşemesinin , kuralın ilk kez uygulanmasında çıkmaz yol olarak kabul edildiğini unutmayın .

Giriş ve çıkış, tek bir dize (olmayan karakterlerle ayrılmış çizgilerle #veya .) veya bir dizi / liste / vb. Diliniz destekliyorsa, her satır bir işlev bağımsız değişkeni olarak da giriş yapabilirsiniz.

Giriş hakkında aşağıdakileri varsayabilirsiniz:

  • Her zaman en az bir "döngü" olacaktır - yani #sonsuza kadar takip edilebilecek bir karakter grubu . (Aksi takdirde her bir karo çıkmaz bir yer haline gelir.)

  • Bu, en küçük döngü olduğu için girişin her zaman 2 × 2 veya daha büyük olacağı anlamına gelir:

    ##
    ##
    

    (Bu arada, herhangi bir değişiklik yapılmadan çıktı alınmalıdır.)

  • Tüm #karakterler bağlanacak. Yani, herhangi bir taşkın dolgusu #yapsaydınız, hepsi etkilenecekti.

Bu , bayt cinsinden en kısa kod kazanacaktır.

Yukarıdaki örnek ve küçük 2 × 2 ızgarası test senaryoları olarak kullanılabilir (bu meydan okumayı kapsayacak çok fazla kenar vakası yoktur).

Yanıtlar:


8

CJam, 61 bayt

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

Burada deneyin .

açıklama

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 iki bayt kurtardı, teşekkürler!)


Bu şimdiye kadar gördüğüm en uzun cjam cevabından biri. =)
DJMcMayhem

2
@DJMcGoathem Ummm ...
Martin Ender

Are '#ve "#"CJam farklı?
ETHproductions

Evet, öyleler. "#"eşittir ['#].
Lynn

5

JavaScript (ES6), 110 109 bayt

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

@ Edc65 sayesinde 1 bayt kaydedildi !

açıklama

Soruna çok basit bir yaklaşım. Her birini arar #ve #etrafında 2 sn'den az varsa, yerine bir X. Tüm çıkmaz sokakların Xs ile değiştirilmesini garanti edene kadar bu işlemi birçok kez tekrarlayın .

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
Bu tür görevler için her zaman kullandığım ortak numara. Hem l hem de -l'yi aynı şekilde kullandığınızda, l=~r.searchbunun yerine hesaplayabilirsiniz l=1+r.search. (Sadece 1 bayt kaydedildi)
edc65

@ edc65 Zeki. Teşekkürler!
user81655

0

Python (3.5) 362 331 329 314 bayt

@Alissa sayesinde. o ~ 33 byte kazanmama yardım ediyor

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

açıklamalar

d='.'
r=range

İşlev tanımı

def f(s):

'.' Kenarlığı ekleyin. tahtanın sağında ve solunda

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

'.' Kenarlığı ekleyin. üstte ve altta

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

'#' Test etmek için Lambda işlevi

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

Çıkmazları unutmadığımızdan emin olmak için giriş uzunluğunu tekrarlayın

 for k in r(l*c):

Sütunlarda ve satırlarda döngü

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

Etrafta ve konumda '#' olup olmadığını test edin

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

'#' Yerine 'X' yerine

     t[h][x]='X'

'.' İle dolu kenarlığı kırpın. ve dizeye katıl

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

kullanım

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()yerine kullanın splitlines(). 2) t=['.'*(c+2)]+['.'+i+'.'for i in s]+['.'*(c+2)]daha kısadır. Ve daha da kısaltılabilir: d='.';t=[d*c]+t+[d*c];t=[d+i+d for i in t]3) tüm liste (zip (....)) şeye ihtiyacınız yok, kullanınprint('\n'.join([''.join(i[1:-1])for i in t])
Alissa

@Alissa yardımınız için teşekkürler ben 1) ve 3) için ipuçlarını kullanın ama 2) i tüm braketi kaldıramıyorum, char listesi listesi ve dize listesi değil çünkü gerekir 'str' object does not support item assignment. Listenin listesi me t [h] [x] '= X '' kullanmasını sağlar
Erwan

üzgünüm, ipin değişmezliği ile ilgili bir şeyi kaçırdım. Ayrıca tüm sabitleri hareket (edebilir r, gve d(bazı tablolama kazandırır) sizin fonksiyon dışı). Belki split () etrafında oynamanın bir kısmı yardımcı olabilir: t=[d+list(i)+d for i in s.split()]sonra uzunlukları hesaplayın, sonra sonuna sonuna kadar satır çizgileri ekleyin ve sonra bu uzatılmış uzunluklarla çalışmak için döngülerinizi değiştirin. Kodu kısaltacağından emin değilim, ama olabilir
Alissa

@Alissa g işlev dışına taşıyamaz çünkü diğer yorumunuzu test edeceğim
Erwan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.