핵공습 – Alphabet War

https://bit.ly/353Y8ML

알파벳소문자들과 대괄호([, ]), 샵기호(#)로 구성되는 문자열을 입력받아 생존하는 문자들을 리턴하는 프로그램을 작성한다.

규칙

인자로 문자열 battlefield가 주어진다. 이 문자열은 전장의 상황을 묘사하고 있다.

  • 문자열은 영어 소문자와 대괄호, 샵으로만 구성된다.
  • 각 문자열은 1명의 사람을 표현한다, 샵 문자는 핵폭탄을 표현한다.
  • 대괄호로 둘러싸인 부분은 방공호를 의미한다.

공습이 시작되면 모든 핵폭탄이 일제히 폭파한다. 누가 살아남을 수 있을까?

  • 핵폭탄이 폭발하는 경우, 방공호 외부의 인원은 모두 사망한다.
  • 방공호는 핵폭탄 1개의 위력만 견딜 수 있다. 인접한 지형에서 핵폭탄이 2개 이상 터지만 방공호 내부의 인원도 모두 사망한다.
  • “인접한”이란 방공호와 연결된 땅이다. 방공호는 그와 인접한 다른 방공호들 너머의 핵폭탄에는 영향을 받지 않는다고 가정한다.

예시

abc[def]ghj : abcdefghj (폭탄이 없으므로 모두 살아남는다)
a#c[def]ghj : def  (폭탄이 1개이므로 외부 인원은 모두 사망한다)
a#c[def]g#j[mno]pqr (_#_[def]_#_ 왼쪽 방공호는 좌우 하나씩, 총 2개의 폭탄으로 인해 파괴된다)

풀이

먼저 #이 하나도 없는 경우를 생각하면 모든 알파벳문자열이 살아남는다.

전장의 구성은 땅-방공호-땅-방공호-.. 의 연쇄이며, 각각의 땅/방공호는 2개 이상의 사람 혹은 폭탄으로 구성된다. (물론 방공호 내에는 폭탄이 없다고 전제한다.) 따라서 개별 방공호에 대해서 앞/뒤 방공호까지의 범위를 잡고, 그 범위의 부분에 대해서 # 가 2개 이상인지를 파악하면 된다. #가 1개 라면 방공호 내의 문자열만 살아남으며, 2개 이상이라면 모두 사망한다.

일반 땅과 방공호를 구분하면 되려 로직이 복잡해지므로 땅-방공호를 하나의 단위로 두고 전장을 자른다음, 두 개씩 묶어서 하나의 파트로 보면 된다.

    ##abde[fgh]ijk[mn]op  
-> |--------------~~~|

방공호 속에는 폭탄이 없으므로 오른쪽 [ 이후의 문자는 무시해도 좋다. 따라서 주어진 입력을 ‘]’ 문자를 기준으로 쪼개고, 각 조각에서 그 다음조각과 연결한 문자열에서 #의 개수를 세어 생존자를 판단한다.

물론 사전에 폭탄이 0개인 경우를 따로 처리해주어야 한다.

코드

def alphabet_war(battlefield):
  if '#' not in battlefield:
    return battlefield.replace('[', '')\
             .replace(']', '')
  result = []
  sections = battlefield.split(']')
  l = len(sections)
  for (i, section) in enumerate(sections):
    part = '|'.join(sections[i:min(i+2, l)])
    if part.count('#') == 1 and '[' in section:
      result.append(section.rsplit('[', 1)[1])
  return ''.join(result)