M ve S karakterlerinden oluşan ASCII sanat pencerelerini algıla


28

Bir Pencere, kenarları boyunca tek bir karakter sınırının yanı sıra ortada dikey ve yatay vuruşların olduğu, tek yan kenar uzunluğu en az 3 olan ASCII-sanat karesidir:

#######
#  #  #
#  #  #
#######
#  #  #
#  #  #
#######

Bir MS Pencere sınırı sadece karakterlerden oluşan bir penceredir Mve S. Senin görevin bir dize alan ve giriş geçerli bir MS Penceresi ise bir yanlış değer ve bir değilse falsey değeri çıkaran bir program (veya işlev) yazmaktır.

Özellikler

  • Girdiyi yeni satırla ayrılmış bir dize veya her bir satırı temsil eden bir dizi dizi olarak alabilirsiniz.
  • Bir MS Penceresinin sınırı M ve S karakterlerinin bir karışımını içerebilir, ancak iç kısımlar daima boşluklardan oluşacaktır.
  • Yalnızca izleyen satırları olan pencereleri veya yalnızca izleyen satırları olmayan pencereleri algılamayı seçebilirsiniz, ancak ikisini birden değil.

Test Kılıfları

Truthy:

MMM
MMM
MMM

SMSMS
M M S
SMSMM
S S M
SMSMS

MMMMMMM
M  S  M
M  S  M
MSSSSSM
M  S  M
M  S  M
MMMMMMM

Falsey:

Hello, World!

MMMM
MSSM
MS M
MMMM

MMSMM
M S.M
sSSSS
M S M
MMSMM

MMMMMMM
M  M  M
MMMMMMM
M  M  M
MMMMMMM

MMMMMMM
M M M M
MMMMMMM
M M M M
MMMMMMM
M M M M
MMMMMMM

MMSSMSSMM
M   M   M
S   S   S
S   S  S
MMSSMSSMM
S   S   S
S   S   S
M   M   M
MMSSMSSMM

3
Bu, belirli bir yapıyı tespit etmek için bir karar sorunu olan ASCII sanatlarında büyük bir büküm.
xnor

4
@xnor Bunun gibi ters ASCII sanatı için farklı bir etiket isteyebileceğimizi hissediyorum.
Esolanging Fruit

2
ascii sanatına özgü olmasa da, desen eşleştirme yeni bir etiket için iyi bir seçim olabilir
Destructible Lemon

Dizenin dikdörtgen bir dizi oluşturmadığı bir test durumu veya iki ekleyebilir misiniz?
Greg Martin

1
@Mast, oldukça haklısın! Belki mücadelenin netleşmesi gerekiyor
Chris M

Yanıtlar:


1

Pyke, 34 31 bayt

lei}t\Mcn+it*i\M*+s.XM"QJ\S\M:q

Burada dene!

lei                              -         i = len(input)//2
   }t                            -        (^ * 2) - 1
     \Mc                         -       "M".center(^)
        n+                       -      ^ + "\n"
          it*                    -     ^ * (i-1)
                 +               -    ^ + V
             i\M*                -     "M"*i
                  s              -   palindromise(^)
                   .XM"          -  surround(^, "M")
                               q - ^ == V
                       QJ        -   "\n".join(input)
                         \S\M:   -  ^.replace("S", "M")


7

Grime , 39 38 bayt

1 bayt tasarruf için Zgarb teşekkürler.

e`BB/BB/W+ W/+
B=W|B/W\ * W/\ /*
W=[MS

Çevrimiçi deneyin!

Ayrı ayrı pencere bileşenlerinin kare en boy oranını zorlamak için özyinelemeli bir geleneksel olmayan kullanmaktan daha basit bir yolu olup olmadığından emin değilim, ancak bu oldukça iyi çalışıyor gibi görünüyor.

açıklama

Programı en alttan okumak en iyisidir.

W=[MS

Bu basitçe ( Wya da bir dikdörtgene uyan bir alt yordam olarak düşünebileceğiniz) bir Mya da bir ile eşleşen S( ]satırın sonunda bir örtülü olan ) tanımlar .

B=W|B/W\ * W/\ /*

Bu B, çıktının yaklaşık dörtte birine uyan bir terminali , yani sol ve üst kenarlığı olan bir pencere panelini tanımlar . Bunun gibi bir şey:

MSM
S  
M  

Bu pencere panelinin kare olmasını sağlamak için Bözyinelemeli olarak tanımlarız . Bu bir pencere karakteridir Wveya B/W\ * W/\ /*sağa ve alta bir katman ekleyendir. Bunu nasıl yaptığını görmek için, biraz sözdizimsel şekeri kaldıralım:

(B/W[ ]*)(W/[ ]/*)

Bu aynıdır, çünkü yatay birleştirme ya ABda yazılabilir A B, ancak ikincisi /birincisi daha yüksekken dikey birleştirmeden daha düşük önceliğe sahiptir. Öyleyse B/W[ ]*, Bpencere karakterli ve aşağıda bir sıra satır vardır. Ve sonra yatay W/[ ]/*olarak boşluk sütununa sahip bir pencere karakteri olan ekleriz.

Son olarak, bu nonterminalleri son pencere şekline getiriyoruz:

BB/BB/W+ W/+

Bu dört pencere paneli ve Bardından bir sıra pencere karakteri ve bir pencere karakteri sütunu. Dört pencere panelinin aynı boyutta olduğu konusunda kesin bir iddiada bulunmadığımızı unutmayın, ancak bunları dikdörtgenin içinde birleştirmek imkansızdır.

Sonunda e`başlangıçta, Grime'ye tüm girişin bu desenle eşleştiğini kontrol etmesini söyleyen bir yapılandırmadır (ve yazdırır 0veya 1buna göre).


5

JavaScript (ES6), 115 113 bayt

a=>(l=a.length)&a.every((b,i)=>b.length==l&b.every((c,j)=>(i&&l+~i-i&&l+~i&&j&&l+~j-j&&l+~j?/ /:/[MS]/).test(c)))

Girdiyi karakter dizisi olarak alır (dizi dizisi için 5 bayt ekle) ve 1veya döndürür 0. Yüksekliğin tek olduğunu doğruladıktan sonra, dizinin kare olmasını sağlamak için her satır kontrol edilir ve her karakterin, belirli bir konumda beklediğimiz karakterlerden biri olduğu doğrulanır. Düzenleme: @ PatrickRoberts sayesinde 2 bayt kaydedildi.


1 byte tasarruf (...).includes(c)etmek ~(...).search(c)için değişiklik yapabilirsiniz
Patrick Roberts

1
Aslında, daha da iyisi (...?/ /:/[MS]/).test(c), sadece 1 yerine 2 bayt tasarruf edecek şekilde değiştirebilirsiniz .
Patrick Roberts

@PatrickRoberts Sevimli, teşekkürler!
Neil

5

Perl, 124 123 119 95 93 84

Aşağıdaki Perl betiği standart girdiden bir aday MS Window okur. Daha sonra aday bir MS Window ise sıfır çıkış durumuyla ve eğer değilse sıfır olmayan çıkış durumuyla çıkar.

Biri üst, orta ve alt satır için diğeri diğer tüm satırlar için iki normal ifade üreterek ve bunlara karşı girdiyi kontrol ederek çalışır.

Teşekkürler, @Dada. Ve yeniden.

map{$s=$"x(($.-3)/2);$m="[MS]";($c++%($#a/2)?/^$m$s$m$s$m$/:/^${m}{$.}$/)||die}@a=<>

Çıkış durumuna izin verildiğinden sonuç vermekten emin değilim (Yine de ilgili meta postayı arayacak vaktim yok). Ne olursa olsun, bir kaç bayt kurtarabilirsiniz:@a=<>;$s=$"x(($.-3)/2);$m="[MS]";map{$a[$_]!~($_%($./2)?"$m$s$m$s$m":"$m${m}{$.}")&&die}0..--$.
Dada

@Dada: Teşekkürler! Bu etkileyici bir gelişme: 24 karakter. (Kodunuzda başıboş bir "$ m" vardı, bu yüzden ilk bakışta göründüğünden bile daha kısa.) Sonucun genel olarak bir çıkış koduyla bildirilmesine izin verilip verilmediğinden emin değildim, ancak "bir program yazdım ( veya işlev) "birinin bu özel durumda sonucun nasıl döndürüleceği konusunda esnek olmasını sağlamak; çıkış kodları pratik olarak * nix ortamının fonksiyon dönüş değerleridir. :-)
nwk

Bunu 26 karakter yap.
saat

1
Aslında azaltma ediyorum $.iki kez kullanmaktan kaçınmak için sonunda $.-1(o was ilk kez, özellikle de ($.-1)/2bu yüzden, bu yüzden bazı ekstra parantez gerekli) $miçinde $m${m}{$.}bir hata değildir. Ayrıca, şimdi farkettim, ancak regex'ler etrafa sarılmalı ^...$(sonunda ya da başında ek bir karakter onları başarısız kılmalı ) ya da daha kısa: neyerine kullanın !~.
Dada

Boşuna, açıkçası neonun yerine kullanamazsın !~(sadece 15 dakika uyanıkken mesaj yazmamalıyım!). Bu yüzden ^...$her iki regex de kullanmak zorunda kalacağım .
Dada

2

Mathematica, 166 bayt

Union[(l=Length)/@data]=={d=l@#}&&{"M","S"}~(s=SubsetQ)~(u=Union@*Flatten)@{#&@@(p={#,(t=#~TakeDrop~{1,-1,d/2-.5}&)/@#2}&@@t@#),p[[2,All,1]]}&&{" "}~s~u@p[[2,All,2]]&

Adsız işlev, giriş ve döndürme olarak karakter listelerinin bir listesini alarak Trueveya False. İşte daha az sayıda golf oyunu:

(t = TakeDrop[#1, {1, -1, d/2 - 0.5}] &; 
Union[Length /@ data] == {d = Length[#1]}
  &&
(p = ({#1, t /@ #2} &) @@ t[#1];
SubsetQ[{"M", "S"}, Union[Flatten[{p[[1]], p[[2, All, 1]]}]]]
  && 
SubsetQ[{" "}, Union[Flatten[p[[2, All, 2]]]]])) &

İlk satır, tbir uzunluk listesini diki bölüme ayıran işlevi tanımlar; bunlardan ilki listenin ilk, orta ve son girişleri, ikincisi ise diğerlerinin tümüdür. İkinci satır, girişin ilk etapta kare bir dizi olup olmadığını kontrol eder. Dördüncü satır t, bir kez girişin kendisinde ve bir kez girişin tüm karakterlerinde *, olması gereken karakterleri "M"veya "S"boşluk olması gereken karakterleri ayırmak için kullanılır; Sonra beşinci ve yedinci çizgiler gerçekte olması gerektiği gibi olup olmadığını kontrol eder.


2

JavaScript (ES6), 108 106 bayt

Giriş: dizelerin / Çıkış dizisinin: 0veya1

s=>s.reduce((p,r,y)=>p&&r.length==w&(y==w>>1|++y%w<2?/^[MS]+$/:/^[MS]( *)[MS]\1[MS]$/).test(r),w=s.length)

Test durumları


2

JavaScript (ES6), 140 138 141 140 bayt

Bunun bir bayt sayımı olmadığını biliyorum (-3 için Roberts Roberts sayesinde) ve M / S: +3 yerine 1 için hatalı pozitif attığını fark ettim.) Bunun için yeni m ve eğlenceli oldu ...

Her satır için bir tane olmak üzere bir dizi dizeyi kabul eder ve doğru veya yanlış döndürür. Netlik için yeni satır eklendi (bayt sayısına dahil değil).

f=t=>t.every((e,i)=>e.split`S`.join`M`==[...p=[b='M'.repeat(s=t.length),
...Array(z=-1+s/2|0).fill([...'MMM'].join(' '.repeat(z)))],...p,b][i])

Girdiyi genelleştirilmiş bir desene göre kontrol etmek yerine, aynı boyutta bir 'M' penceresi inşa ediyorum, girişte S'yi M ile değiştiriyorum ve ikisini karşılaştırıyorum.

Ungolfed

f = t => t.every( // function returns true iff every entry in t
                  // returns true below
  (e, i) => e.split`S`.join`M` // replace all S with M
                                 // to compare to mask
  == [ // construct a window of the same size made of Ms and
       // spaces, compare each row 
      ...p = [ // p = repeated vertical panel (bar above pane)
               // which will be repeated
              b = 'M'.repeat(s = t.length),
                  // b = bar of Ms as long as the input array
              ...Array(z = -1 + s/2|0).fill([...'MMM'].join(' '.repeat(z)))],
              // z = pane size; create enough pane rows with
              // Ms and enough spaces
      ...p, // repeat the panel once more
      b][i] // finish with a bar
)

console.log(f(["111","111","111"]))

console.log(f(["MMMMM","M S M","MSSSM","M S M","MSSSM"]))

Test durumları

f=t=>t.every((e,i)=>e.split`S`.join`M`==[...p=[b='M'.repeat(s=t.length),
...Array(z=-1+s/2|0).fill([...'MMM'].join(' '.repeat(z)))],...p,b][i])


truthy=`MMM
MMM
MMM

SMSMS
M M M
SMSMS
M M M
SMSMS

MMMMMMM
M  S  M
M  S  M
MSSSSSM
M  S  M
M  S  M
MMMMMMM`.split('\n\n')

falsey=`Hello, World!

MMMM
MSSM
MS M
MMMM

MMSMM
M S.M
sSSSS
M S M
MMSMM

MMMMMMM
M  M  M
MMMMMMM
M  M  M
MMMMMMM

MMMMMMM
M M M M
MMMMMMM
M M M M
MMMMMMM
M M M M
MMMMMMM`.split('\n\n')

truthy.forEach(test=>{
  console.log(test,f(test.split('\n')))
})

falsey.forEach(test=>{
  console.log(test,f(test.split('\n')))
})


1
Gelecekte f=başvurmak için , fonksiyon özyinelemeli değilse, bayt sayısına dahil edilmesi gerekmez, bu aslında 138 baytlık bir sunumdur.
Patrick Roberts

1 byte tasarruf etmek için z=-1+s/2|0ile değiştirebilirsinizz=(s-3)/2
Patrick Roberts

Ayrıca başka bir bayt kaydetmek için e.replace(/S/g,'M')==...ile değiştirebilirsinize.split`S`.join`M`==...
Patrick Roberts

Teşekkürler! z=-1+s/2|0s == 1 ve hatta s için pozitif bir tamsayı döndürmek için, yani işlev Array () öğesini kilitlemeden yanlış döndürür. Aksi halde, gerekli mantık daha uzun sürdü. Bölmek / katılmak için mükemmel bir ipucu, teşekkürler
Chris M

İyi yakalama, s=1davayı göz önünde bulundurmadım , çünkü geçersiz regex'im sessizce başarısız oluyor.
Patrick Roberts

1

JavaScript (ES6), 109 107 106 105 99 bayt

s=>!s.split`S`.join`M`.search(`^((M{${r=s.search`
`}})(
(M( {${w=(r-3)/2}})M\\5M
){${w}}))\\1\\2$`)

Düzenleme : Ooo, Arnauld değiştirerek bana 6 bayt kaydedildi s.split`\n`.lengthiçin s.search`\n`! Teşekkürler!

Bu, tek bir çok satırlı dize alır RegExpve giriş dizesinin uzunluğunu kullanarak bir tabanlı doğrulama yapar. trueVeya döndürür false. Geçerli bir pencere varsayar vardır yoktur bir eğik satırsonu.

gösteri

f=s=>!s.split`S`.join`M`.search(`^((M{${r=s.search`
`}})(
(M( {${w=(r-3)/2}})M\\5M
){${w}}))\\1\\2$`);
`MMM
MMM
MMM

SMSMS
M M M
SMSMS
M M M
SMSMS

MMMMMMM
M  S  M
M  S  M
MSSSSSM
M  S  M
M  S  M
MMMMMMM

Hello, World!

MMMM
MSSM
MS M
MMMM

MMSMM
M S.M
sSSSS
M S M
MMSMM

MMMMMMM
M  M  M
MMMMMMM
M  M  M
MMMMMMM

MMMMMMM
M M M M
MMMMMMM
M M M M
MMMMMMM
M M M M
MMMMMMM`.split`

`.forEach(test=>{console.log(test,f(test));});


Güzel yaklaşım! Eğer kullanabilir misiniz r=s.search('\n')yerine split / length?
Arnauld

@Arnauld harika öneri, teşekkürler!
Patrick Roberts

Parantez açık s=>!s.split`S`.join`M`.search([...]), sözdizimi hatalarına neden olmadan kaldırılabilir.
Ismael Miguel

@IsmaelMiguel doğru, ancak daha sonra dize örtük geçersiz kılan bir şablon olarak geçirilirRegExp
Patrick Roberts

Bu berbat ... Gerçekten beklemiyordum ...
Ismael Miguel
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.