M 및 S 문자로 구성된 ASCII 아트 창 감지


28

윈도우는 홀수 변이 길이가 3 이상이고 가장자리에 단일 문자 테두리가 있고 가운데에 세로 및 가로 선이있는 ASCII 아트 사각형입니다.

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

MS Window는 테두리가 문자 M및 로만 구성된 창 S입니다. 작업은 문자열을 가져 와서 입력이 유효한 MS Window 인 경우 정확한 값을 출력하고 그렇지 않은 경우 잘못된 값을 출력하는 프로그램 (또는 함수)을 작성하는 것입니다.

명세서

  • 줄 바꿈으로 구분 된 문자열 또는 각 줄을 나타내는 문자열 배열로 입력을받을 수 있습니다.
  • MS 창의 테두리에는 M과 S 문자가 혼합되어있을 수 있지만 내부는 항상 공백으로 구성됩니다.
  • 후행 줄 바꿈이있는 창 또는 후행 줄 바꿈이없는 창만 감지 할 수 있지만 둘다는 선택할 수 없습니다.

테스트 사례

진실한 :

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

팔시 :

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
이것은 특정 구조를 감지하기위한 의사 결정 문제인 ASCII 예술에 큰 영향을 미칩니다.
xnor

4
@ xnor 역 ASCII 아트에 대해 이와 같은 다른 태그를 원할 것 같습니다.
Esolanging 과일

2
ascii art에만 해당되는 것은 아니지만 패턴 일치는 새로운 태그에 적합합니다.
Destructible Lemon

문자열이 직사각형 배열을 형성하지 않는 테스트 사례를 추가 할 수 있습니까?
Greg Martin

1
@ 마스트, 당신 말이 맞아요! 어쩌면 도전이 명확 해져야합니다
Chris M

답변:


1

파이크, 34 31 바이트

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

여기 사용해보십시오!

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

me , 39 38 바이트

1 바이트를 절약 한 Zgarb에게 감사드립니다.

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

온라인으로 사용해보십시오!

재귀 비 터미널을 사용하는 것보다 개별 창 구성 요소의 제곱 종횡비를 적용하는 간단한 방법이 있는지 확실하지 않지만 잘 작동하는 것 같습니다.

설명

프로그램을 아래에서 위로 읽는 것이 가장 좋습니다.

W=[MS

이것은 단순히 (당신이 사각형과 일치하는 서브 루틴으로 생각할 수있는)는 비단 정의 W어느 쪽 일치하는 M또는이 S(암시 적있을 ]줄의 끝을).

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

이것은 B출력의 약 1/4과 일치 하는 비 터미널 을 정의합니다. 즉, 왼쪽과 위쪽 테두리가있는 하나의 창 패널입니다. 이 같은:

MSM
S  
M  

이 창 패널을 정사각형으로 만들기 위해 B재귀 적으로 정의 합니다. 그것은 창 문자 W이거나 B/W\ * W/\ /*오른쪽과 아래쪽에 하나의 레이어를 추가하는 것입니다. 이것이 어떻게 작동하는지 알아 보려면 구문 설탕을 제거하십시오.

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

가로 연결은 AB또는 로 쓰일 수 A B있지만 후자는 세로 연결보다 우선 순위가 낮고 전자는 세로 연결보다 우선합니다 /. 그래서 B/W[ ]*A는 B윈도우 문자 아래 공간의 행. 그런 다음 W/[ ]/*공백 열이있는 창 문자 인 가로를 추가 합니다.

마지막으로 이러한 비 터미널을 최종 창 모양으로 조립합니다.

BB/BB/W+ W/+

네 개의 창 패널 B과 한 줄의 창 문자 및 한 줄의 창 문자가 있습니다. 우리는 네 개의 창 패널이 같은 크기라는 명백한 주장을하지 않지만, 그렇지 않으면 사각형으로 연결할 수 없습니다.

마지막으로, e`처음에 단지 전체 입력 (그리고 출력이 패턴과 일치 할 수 있는지 확인하기 위해 오점 지시하는 구성이다 0또는 1그에).


5

자바 스크립트 (ES6) 115 113 바이트

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

문자의 배열의 배열로 입력을 받아, 반환 (문자열 배열에 대한 5 바이트를 추가) 1또는 0. 높이가 홀수인지 확인한 후 모든 행을 검사하여 배열이 정사각형인지 확인하고 모든 문자가 해당 특정 위치에서 예상되는 문자 중 하나인지 확인합니다. 편집 : @PatrickRoberts 덕분에 2 바이트가 절약되었습니다.


1 바이트를 저장 (...).includes(c)하도록 변경할 수 있습니다~(...).search(c)
Patrick Roberts

1
실제로, 1보다 (...?/ /:/[MS]/).test(c)2 바이트를 절약 하도록 변경할 수 있습니다 .
Patrick Roberts

@PatrickRoberts Cute, 감사합니다!
Neil

5

펄, 124 123 119 95 93 84

다음 Perl 스크립트는 표준 입력에서 하나의 후보 MS Window를 읽습니다. 그런 다음 후보가 MS Window 인 경우 종료 상태가 0이고 종료되지 않은 경우 종료 상태가 0이 아닌 상태로 종료됩니다.

그것은 두 개의 정규 표현식을 생성합니다. 하나는 상단, 중간 및 하단 라인에 대한 것이고 다른 하나는 모든 라인에 대한 입력입니다.

감사합니다, @ 다다. 그리고 다시.

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

종료 상태가 허용되어 결과를 제공하는지 잘 모르겠습니다 (하지만 관련 메타 게시물을 찾을 시간이 없습니다). 어쨌든 몇 바이트를 절약 할 수 있습니다.@a=<>;$s=$"x(($.-3)/2);$m="[MS]";map{$a[$_]!~($_%($./2)?"$m$s$m$s$m":"$m${m}{$.}")&&die}0..--$.
Dada

@ 다다 : 감사합니다! 24자인 인상적인 개선입니다. (코드에 길잃은 "$ m"이있어서 처음보다 훨씬 짧습니다.) 종료 코드로 결과를보고하는 것이 일반적으로 허용되는지 확실하지 않지만 "프로그램 작성 ( 또는 함수) '를 사용하여 특정 상황에서 결과가 어떻게 반환되는지 유연하게 할 수 있습니다. 종료 코드는 실제로 * nix 환경의 함수 리턴 값입니다. :-)
nwk

26 자로 만드세요.
nwk

1
사실, 난 감소시키는거야 $.두 번 사용하지 말에 $.-1(그것이 처음 특히 이후 ($.-1)/2너무, 그래서 그것은 몇 가지 여분의 괄호가 필요) $m에서 $m${m}{$.}실수하지 않습니다. 또한, 나는 방금 지금 깨달았지만 정규 표현식은 ^...$(마지막이나 시작 부분에 여분의 문자가 실패하게) 둘러싸여 있거나 짧아야합니다. ne대신 사용하십시오 !~.
Dada

신경 쓰지 마라. 당신은 ne대신 대신 사용할 수 없다 !~(나는 단지 15 분 동안 깨어있을 때 메시지를 쓰지 않아야한다!). 따라서 ^...$두 정규식 모두 를 사용해야 합니다.
Dada

2

매스 매 티카, 166 바이트

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

이름이없는 함수는 문자 목록을 입력으로 가져 와서 리턴 True하거나 또는 False. 덜 골프 버전은 다음과 같습니다.

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

첫 번째 줄은 function을 정의합니다.이 함수 t는 길이 목록 d을 두 부분으로 구분 합니다. 첫 번째 는 목록의 첫 번째, 중간 및 마지막 항목이고 두 번째는 나머지입니다. 두 번째 줄은 입력이 사각형 배열인지 확인합니다. 네 번째 줄은t 두번 있어야하는 문자 분리하는 입력 문자열에서의 모든 *의 입력 자체 한번에 한번 "M"또는 "S"스페이스로되어있는 문자 행; 그런 다음 다섯 번째와 일곱 번째 줄은 그들이 실제로 무엇인지 확인합니다.


2

자바 스크립트 (ES6), 108 106 바이트

입력 : 문자열 배열 / 출력 : 0또는1

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)

테스트 사례


2

자바 스크립트 (ES6) 140 138 141 140 바이트

나는 이것이 바이트 수를 얻지 못한다는 것을 알고 있지만 (-3의 Patrick Roberts 덕분에 M / S 대신 1에 대해 오 탐지가 발생했다는 것을 깨달았습니다 : +3) 약간 다른 방식으로 수행했습니다. ' 나는 이것에 익숙하지 않고 재미있었습니다 ...

각 줄마다 하나씩 문자열 배열을 허용하고 true 또는 false를 반환합니다. 명확성을 위해 줄 바꿈이 추가되었습니다 (바이트 수에는 포함되지 않음).

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

일반화 된 패턴에 대해 입력을 확인하는 대신 동일한 크기의 'M'창을 구성하고 입력시 S를 M으로 바꾸고 두 값을 비교합니다.

언 골프

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

테스트 사례

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
나중에 참조 f=할 수 있도록 함수가 재귀 적이 지 않으면 바이트 수에 포함될 필요가 없으므로 실제로는 138 바이트 제출입니다.
Patrick Roberts

당신은 대체 할 수 z=-1+s/2|0z=(s-3)/2할인율 1 바이트
패트릭 로버츠

또한 대체 할 수 e.replace(/S/g,'M')==...e.split`S`.join`M`==...다른 바이트 저장
패트릭 로버츠

감사! z=-1+s/2|0s == 1 및 s에 대해 양의 정수를 반환해야합니까? 즉, 함수는 Array ()가 충돌하지 않고 false를 반환합니다. 그렇지 않으면 필요한 논리로 인해 더 길어졌습니다. 스플릿 / 조인에 대한 유용한 팁
Chris M

좋은 캐치, 나는 s=1유효하지 않은 정규 표현식이 조용히 실패하기 때문에이 사건을 고려하지 않았습니다 .
Patrick Roberts

1

자바 스크립트 (ES6), 109 (107) 106 (105) 99 바이트

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

편집 : Whoa, Arnauld는 다음으로 변경 s.split`\n`.length하여 6 바이트를 절약 했습니다.s.search`\n` ! 감사!

단일 다중 행 문자열을 RegExp사용하고 입력 문자열의 길이를 사용하여 기반 유효성 검증을 구성 합니다. 반환 true또는 false. 유효 창을 가정 없는 뒤에 줄 바꿈.

데모

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


좋은 접근 방식! r=s.search('\n')대신에 사용할 수 split / length있습니까?
Arnauld

@Arnauld 멋진 제안, 감사합니다!
Patrick Roberts

s=>!s.split`S`.join`M`.search([...])구문 오류없이 괄호를 제거 할 수 있습니다.
Ismael Miguel

수정 @IsmaelMiguel,하지만 문자열은 암시 적 무효화 템플릿으로 전달됩니다RegExp
패트릭 로버츠

그건 짜증나 ... 난 정말 기대하지
않았다
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.