문자열의 패 런트 제거


25

적절하게 괄호로 묶인 문자열을 입력으로 받으면 중첩 괄호를 제거하고 일치하는 괄호 내 (또는 모든 괄호 외부)에 비어 있지 않은 모든 서브 스트링의 목록을 출력하십시오. 각 하위 문자열은 정확히 일치하는 괄호 안에있는 일련의 문자 여야합니다. 하위 문자열은 깊이 순서대로 나열되어야하며 동일한 깊이의 하위 문자열은 문자열에서 나타나는 순서대로 나열되어야합니다. 입력이 항상 올바르게 괄호 안에 있다고 가정하십시오.

입력에 소문자 ASCII 문자와 괄호 만 포함되어 있다고 가정 할 수 있습니다.

답은 문자열이 주어지면 문자열 목록을 반환하는 함수 여야합니다.

예 :

                   'a(b)c(d)e' -> ['ace', 'b', 'd']
                   'a(b(c)d)e' -> ['ae', 'bd', 'c']
                  'a((((b))))' -> ['a', 'b']
                        'a()b' -> ['ab']
                            '' -> []
                           'a' -> ['a']
          '(((a(b)c(d)e)f)g)h' -> ['h', 'g', 'f', 'ace', 'b', 'd']
'ab(c(((d)ef()g)h()(i)j)kl)()' -> ['ab', 'ckl', 'hj', 'efg', 'i', 'd']

가장 적은 바이트가 이깁니다.


인가 'i''d'마지막 테스트 케이스에 올바른 순서로?
PurkkaKoodari

@ Pietu1998 i은보다 깊게 중첩되지 않습니다 d.
feersum

@feersum 아, 맞아.
PurkkaKoodari

1
다른 표준 제출 유형, 특히 전체 프로그램을 허용 하시겠습니까? 모든 언어에 기능 개념이있는 것은 아닙니다. 기본 합의에 대해서는 meta.codegolf.stackexchange.com/a/2422/8478meta.codegolf.stackexchange.com/questions/2447/…를 참조하십시오 .
Martin Ender

2
@redstonerodent 내가 사용하는 표현은 "STDIN (또는 가장 가까운 대안), 명령 줄 인수 또는 함수 인수를 통해 입력을 받고 STDOUT (또는 가장 가까운 대안), 함수 반환 값을 통해 결과를 출력하는 프로그램이나 함수를 작성할 수 있습니다. 또는 기능 (출력) 매개 변수입니다. " 그리고 귀하의 경우 "출력은 편리하고 모호하지 않은 플랫 목록 형식 일 수 있습니다."
Martin Ender

답변:


11

자바 스크립트 ES6 91 93 104 133 148

Edit2 2 바이트 저장 thx 사용자

더 많은 문자열과 더 적은 배열을 사용하여 편집

EcmaScript 6 호환 브라우저에서 아래 스 니펫 실행 테스트

f=s=>[...s].map(c=>l+=c<')'||-(o[l]=(o[l]||'')+c,c<'a'),o=[],l=0)&&(o+'').match(/\w+/g)||[]

// Less golfed

u=s=>{
  o=[]; l=0;
  [...s].map(c=>{
    if (c>'(') // letters or close bracket
      o[l]=(o[l]||'')+c, // add letter or close bracket to current level string
      l-=c<'a' // if close bracket, decrement level
    else
      ++l // open bracket, increment level
  })
  o = o+'' // collapse array to comma separated string
  return o.match(/\w+/g)||[] // fetch non empty strings into an array
}

// TEST
console.log=x=>O.innerHTML+=x+'\n'

;[ 'a(b)c(d)e'                    // ['ace', 'b', 'd']
 , 'a(b(c)d)e'                    // ['ae', 'bd', 'c']
 , 'a((((b))))'                   // ['a', 'b']
 , 'a()b'                         // ['ab']
 , ''                             // []
 , 'a'                            // ['a']
 , '(((a(b)c(d)e)f)g)h'           // ['h', 'g', 'f', 'ace', 'b', 'd']
 , 'ab(c(((d)ef()g)h()(i)j)kl)()' // ['ab', 'ckl', 'hj', 'efg', 'i', 'd']
].forEach(t=>console.log(t +" -> " + f(t)))
<pre id=O></pre>


로 2 바이트를 저장하십시오 c=>l+=c<')'||-(o[l]=(o[l]||'')+c,c<'a'),.
user81655

@ user81655 nice, thanks
edc65

8

줄리아, 117 86 83 바이트

v->(while v!=(v=replace(v,r"(\(((?>\w|(?1))*)\))(.*)",s"\g<3> \g<2>"))end;split(v))

정규식 솔루션입니다.

언 골프 드 :

function f(v)
  w=""
  while v!=w
    w=v
    v=replace(v,r"(\(((?>\w|(?1))*)\))(.*)",s"\g<3> \g<2>"))
  end
  split(v)
end

r"(\(((?>\w|(?1))*)\))(.*)"재귀 ( (?1)재귀 그룹 1) 정규식은 첫 번째 가장 균형이 잘 잡힌 괄호 (불균형 / 역 괄호를 포함하지 않음)와 일치하며 두 번째 그룹은 괄호 안에 포함 된 모든 항목 (괄호 자체는 포함하지 않음)과 세 번째 그룹은 괄호 뒤의 모든 것 (문자열이 끝날 때까지).

replace(v,r"...",s"\g<3> \g<2>")그런 다음 관련 괄호를 제거하고 두 번째 그룹을 공백의 끝으로 구분 기호로 사용하여 문자열의 끝으로 이동합니다. v == w까지 반복함으로써 괄호가 남지 않을 때까지 바꾸기가 반복되도록합니다. 일치 항목이 끝으로 이동 한 후 다음 일치 항목이 첫 번째 괄호에 적용되므로 결과는 문자열을 깊이 순서대로 나눕니다.

그런 다음 split공백이없는 문자열 배열 형식으로 문자열의 공백이 아닌 구성 요소를 모두 반환합니다.

참고 w=""ungolfed 코드에 사용됩니다 있는지 확인하기 위해 그 동안 루프가 실행 적어도 한 번, 그리고 golfed 형태로 필요하지 않습니다 (입력 문자열은 물론, 비어있는 경우 제외).

3 바이트 절약에 도움을 준 Martin Büttner에게 감사합니다.


깔끔하게, 나는 Retina에서 독립적으로 동일한 솔루션에 도달했습니다. 44 바이트이지만 풀 프로그램 솔루션은 허용되지 않습니다. : /
Martin Ender

\w대신을 사용하여 3 바이트를 저장할 수 있습니다 [^()].
Martin Ender

@ MartinBüttner-감사합니다. 나는 실제로 그것을 고려했지만, 나는 무언가를 간과하고 어떤 경우에는 실패 할까봐 걱정했다. 그래도 괜찮다고 말하면 괜찮습니다.
Glen O

6

파이썬, 147 바이트

def f(s):
 d=0;r=[['']for c in s]
 for c in s:
  if c=='(':d+=1;r[d]+=['']
  elif c==')':d-=1
  else:r[d][-1]+=c
 return[i for i in sum(r,[])if i]

단위 테스트 :

assert f('a(b)c(d)e') == ['ace', 'b', 'd']
assert f('a(b(c)d)e') == ['ae', 'bd', 'c']
assert f('a((((b))))') == ['a', 'b']
assert f('a()b') == ['ab']
assert f('') == []
assert f('a') == ['a']
assert f('(((a(b)c(d)e)f)g)h') == ['h', 'g', 'f', 'ace', 'b', 'd']
assert f('ab(c(((d)ef()g)h()(i)j)kl)()') == ['ab', 'ckl', 'hj', 'efg', 'i', 'd']

나는이 퍼즐을 좋아한다; 너무 귀엽다!


4

Pyth, 32 바이트

fTscR)uX0.<GJ-FqLH`()@[Hdk)Jzmkz

테스트 스위트

@Quuxplusone의 접근 방식을 기반으로합니다. 각 깊이에서 공백으로 구분 된 문자 목록을 작성한 다음 분할하여 빈 그룹을 필터링합니다. 작업 목록은 항상 현재 수심 목록을 항상 유지하도록 회전됩니다.


4

레티 나 , 44 41 바이트

+`\(((\w|(\()|(?<-3>.))*).(.*)
$4 $1
S_` 

-s플래그로 실행하십시오 . 마지막 줄의 끝 부분에 공백이 있습니다.

Glen O와 독립적 으로이 솔루션을 생각해 냈지만 동일합니다. 아이디어는 첫 번째 괄호 쌍을 일치시키고 제거하고 출력 끝에 (반복적으로) 내용을 삽입하는 것입니다. .NET의 정규 표현식 재귀 부족으로 인해 4 바이트 길이의 균형 그룹을 사용해야했습니다.

첫 번째 정규 표현식을 이해하지 못하면 그룹 균형 조정에 대한 SO 답변을 참조하십시오 . 입력이 제대로 괄호로 보장되어 있기 때문에, 우리는 일치에 의해 2 바이트를 저장할 수 있습니다 )으로 .대신 \). 그런 다음 나머지 문자열을와 일치시킵니다 (.*). $4 $1먼저 괄호와 내용을 생략하고 나머지 문자열을 쓴 다음 공백 후 괄호 내용을 기록합니다. 는 +`문자열 (모든 괄호가 제거 된 후에만 발생하는) 변경 멈출 때까지이 단계를 반복 망막을 알려줍니다.

빈 괄호는 두 개의 연속 된 공백을 초래하므로 마지막으로 전체 문자열을 공백으로 S`분할합니다 ( 분할 모드를 활성화하고 정규 표현식은 단일 공백입니다). 이 _옵션은 Retina에게 분할의 빈 부분을 생략하도록 지시하므로 빈 결과를 출력에 포함하지 않습니다.


3

커먼 리스프, 160

(lambda(x)(labels((g(l)(cons(#1=format()"~(~{~A~}~)"(#2=remove-if'listp l))(mapcan #'g(#2#'atom l)))))(remove""(g(read-from-string(#1#()"(~A)"x))):test'equal))))

대소 문자 변환이 필요하지 않은 경우 4 바이트가 줄어들 수 있습니다. 아이디어는 입력 문자열의 양쪽에 왼쪽과 오른쪽 괄호를 추가하고이를 목록으로 취급하고 목록의 최상위 요소를 문자열에 쓴 다음 하위 목록을 동일한 방식으로 처리하는 것입니다.


2

하스켈, 114 (112) 111 바이트

')'%(h:i:t)=("":i):t++[h]
'('%l=last l:init l
c%((h:i):t)=((c:h):i):t
g x=[a|a<-id=<<foldr(%)(x>>[[""]])x,a>""]

사용 예 : g "ab(c(((d)ef()g)h()(i)j)kl)()"-> ["ab","ckl","hj","efg","i","d"].

입력 문자열을 거꾸로 살펴 보겠습니다. 중간 데이터 구조는 문자열 목록의 목록입니다. 외부 목록은 레벨 당이고 내부 목록은 레벨 내의 그룹당입니다 [["ab"],["ckl"],["hj"],["efg","i"],["d"]]( 예 : 실제 목록 사이에는 빈 문자열이 많이 있음). 그것은 모두 입력 길이와 같은 많은 빈 문자열로 시작하지만 충분하지는 않지만 빈 목록은 필터링됩니다. 외부 목록은 (/에서 회전 )하거나 문자를 전면 요소에 추가합니다. )새로운 그룹도 시작합니다.

편집 : @ Zgarb가 저장할 바이트를 찾았습니다.


1

sed, 90 바이트

:
s/^(\w*)\((.*)\n?(.*)/\1\n\3_\2/M
s/(\n\w*_)(\w*)\)(.*)/\3\1\2/M
t
s/[_\n]+/,/g
s/,$//

-r+1 바이트로 확장 된 정규식 ( 플래그)을 사용합니다 . 또한 이것은 GNU 확장 ( 명령 의 M플래그 s)을 사용합니다.

샘플 사용법 :

$ echo 'ab(c(((d)ef()g)h()(i)j)kl)()' | sed -r -f deparenthesize.sed
ab,ckl,hj,efg,i,d

설명 : sed는 재귀 정규식과 같은 기능을 지원하지 않으므로 수동 작업이 필요합니다. 이 표현은 여러 줄로 나뉘며 각 줄은 중첩 수준을 나타냅니다. 같은 깊이 (따라서 같은 행)의 개별 표현식은로 구분됩니다 _. 스크립트는 한 번에 한 줄씩 입력 문자열을 통해 작동합니다. 나머지 입력은 항상 현재 중첩 수준에 해당하는 줄 끝에 유지됩니다.


0

파이썬, 161 바이트

다음은 한 줄 기능적인 파이썬 솔루션입니다.

p=lambda s:filter(None,sum([''.join([s[i]for i in range(len(s))if s[:i+1].count('(')-s[:i+1].count(')')==d and s[i]!=')']).split('(')for d in range(len(s))],[]))

이 과제는 https://github.com/samcoppini/Definition-book 에서 영감을 받았으며 괄호 안에 단어가 정의 된 긴 문자열을 출력합니다. 괄호를 제거하고 각 문장을 제공하는 코드를 작성하고 싶었습니다. 기능 솔루션은 너무 느려 긴 문자열에 효과적이지 않지만 @Quuxplusone의 솔루션과 같은 명령 솔루션은 훨씬 빠릅니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.