본문 바로가기

백준2713 - 규현이의 사랑을 담은 문자메시지 Python 본문

개발/algorithm

백준2713 - 규현이의 사랑을 담은 문자메시지 Python

자전하는명왕성 2023. 11. 10. 09:46
반응형

https://www.acmicpc.net/problem/2713

문제 자체가 어려운 편은 아니나, 구현 자체에 오랜 시간을 소요한 문제였다.

문자열 첫 번째에 '공백'이 나오는 가능성을 배제하고 첫 코드를 작성하여, 백준에 첫 질문을 만들게 한 문제기도 하다.

 

문제에서 하나의 테스트 케이스를 해결하는 과정을 요약하면 아래와 같다.

 

1. 공백 순서를 신경써서 행렬 높이, 행렬 너비, 문자열을 찾는다.

2. 행렬 높이 * 행렬 너비 크기의 2차원 배열을 만든다.

3. 주어진 규칙에 따라 알파벳을 정수 변환 후, 이진수로 변환한다.

이때, 하나의 알파벳이 이진 수 변환 시 길이는 5여야 하며, 이를 만족하지 않을 경우 0으로 채운다.

4. 이차원 배열을 문제에서 주어진 규칙에 따라 채운다.

5. 채운 이차원 배열을 늘어뜨린 형태의 문자열로 변환한 뒤 제출한다.

 

그리고 이를 전체 소스 코드로 보면 다음과 같다.

import sys
data_temp = sys.stdin if sys.platform == 'linux' else open('입력.txt', 'r')
input_data = data_temp.read().splitlines()

def solution (data) :
  data.pop(0)
  result = list(map(lambda x : act(x), data))
  print('\n'.join(result))

def act (_str) :
  # 문자열을 배열화
  arr = list(_str)
  # 공백을 담을 배열 (문자열에 공백이 끼어 있는 경우도 존재. 밑에서 1,2번째의 공백 인덱스만 활용)
  emptyIdx = []
  for i in range(len(_str)) :
    if _str[i] == ' ' : emptyIdx.append(i)
  
  # 배열을 자르는 시작과 끝 위치를 인자로 하여, 잘라낸 요소를 붙였을 때 숫자면 정수 반환 or 문자열 반환
  def join_list (a, b = len(arr)) :
    temp = ''.join(arr[a:b])
    return int(temp) if temp.isdigit() else temp

  # 1. 순서대로 n, m, s = 행렬 높이, 행렬 너비, 문자열
  n, m, s = join_list(0,emptyIdx[0]), join_list(emptyIdx[0] + 1, emptyIdx[1]), join_list(emptyIdx[1] + 1)
  
  # 2. 2차원 배열 선언
  matrix = [[-1 for _ in range(m)] for _ in range(n)]
  
  # 3. 알파벳을 가진 문자열을, 문제에서 제시한 이진수로 변환하여 반환하는 함수
  trans_s = transfer_str(s)
  
  # 4. 문제에서 주어진 규칙에 따라 이차원 배열을 채우는 함수
  fill_matrix(matrix, trans_s,n,m)

  # 5. 채운 이차원 배열을 늘어뜨린 형태의 문자열로 변환한 뒤 제출하는 로직
  answer = ''
  for i in matrix :
    for j in i :
      answer += j if j != -1 else '0'

  return answer

# 3. 주어진 규칙에 따라 알파벳을 정수 변환 후, 이진수로 변환하는 함수
def transfer_str (s) : 
  table = {}
  for i in range(26) :
    _bin = bin(i + 1) # bin() 2진수 변환
    table[chr(i+65)] = _bin[2:].rjust(5,'0') 
    # chr() charCode 변환 | rjust(n,m) 문자열 길이 n만큼 r방향으로 m을 채우기

  code = ''
  for v in s : 
    code += table[v] if v != ' ' else '00000'
  return code

# 4. 문제에서 주어진 규칙에 따라 이차원 배열을 채우는 함수
def fill_matrix (matrix, _s,n,m) :
  # 현재 위치
  location = [0,0]
  # 방향 순서
  direction = [[1,0],[0,1],[-1,0],[0,-1]]
  # 방향 순서 인덱스
  directionIdx = 0
  for v in _s :
    x,y = location
    matrix[y][x] = v

    dx,dy = direction[directionIdx % 4]
    nx,ny = x + dx, y + dy
    
    # 다음 위치 검증
    if location_Verify(n,m,nx,ny) and matrix[ny][nx] == -1 : 
      location = [nx, ny]
    else :
      directionIdx += 1
      dx,dy = direction[directionIdx % 4]
      nx,ny = x + dx, y + dy
      location = [nx, ny]
  return matrix

# x,y 위치가 주어질 때, 해당 위치가 이차원 배열에서 유효한지 확인하는 함수
def location_Verify (n,m,x,y) :
  return 0 <= x < m and 0 <= y < n

solution(input_data)

 

반응형
Comments