문제풀이 - 입실퇴실 (feat. 함수형 프로그래밍)

코지클래식·2021년 9월 18일
0

1. 문제 링크

https://programmers.co.kr/learn/courses/30/lessons/86048



2. 문제풀이 코드 & 해설

내 문제풀이 코드

python
def solution(enter, leave):
    room = []
    counter_number = [0]*len(enter)
    enter.reverse()

    def count_add(room,counter_number) :
        for j in room :
            counter_number[j-1] += 1
        counter_number[room[-1]-1] += len(room)-2

    def enter_room(room,enter) :
        room.append(enter.pop())
        count_add(room,counter_number)

    for i in leave :
        if i in room : room.remove(i)
        
        elif not (i in room) :            
            while not i in room : enter_room(room,enter)
            room.remove(i)

    return counter_number

해설 :

  1. 떠나는 사람 기준으로.. 방안에 나갈 사람이 있으면
    내보내고, 없으면 들어올 때 까지 방에 사람들을 들여보내고, 떠날 사람이 들어오면 내보낸다.
    (가장 하단의 for ~ )
  2. 사람 한 명이 방에 새로 들어가는 순간에 만나는 사람들의 카운트를 센다.
  3. 방 안에 있던 모두에게 마주친사람(counter)를 +1 하고
  4. 새로 들어간 사람에게는, 원래 방 안에 있던 사람들 만큼, 마주친사람(counter)를 추가했다.
  5. 떠날 수 있는 사람이 방에 들어오면, 방에서 내보낸다.

.. 는 논리로 문제를 풀었다.

고려해본 것

  1. 들여보낼 때 pop()으로 처리하기 위해 한번 뒤집는다.
  2. 내부 함수로 기능을 나눈다. (들여보내기, 숫자 세기)
  3. 내부 함수에는 2가지 arg만 사용한다.
  4. (i in room)을 사용하지 않고, (배열을 검색해야 하기 때문에) temp 값을 지정해서, 그 값이 i와 일치하는지 루프를 돌리는게 어떨까 했다. 그런데 테스트 코드에서는 차이가 별로 나지 않아서 ... 그냥 함축시킬 수 있는 문법으로 작성했다.
  5. 방 안에 있는 사람 리스트가 사실 list 형태로 될 필요가 없고, 순서가 없는 dict()나 set()이 더 좋을 것 같았는데 역시 성능차이가 아직은 중요하지 않은 것처럼 보이고, 무엇보다 마지막에 들어온 사람을 확인하는 기능을 room[-1]로 작성 하는게 편리했다.

Best 문제풀이 코드1

-> 구세영 , 정영준 , 김동욱 , Park-Giryun , Wonyoungpark 외 8 명님

해설 :

  1. 떠날사람이 방 안에 들어올 때 까지, 사람을 집어넣는다.
  2. 들어올 사람의 순서는 e_idx로 센다.
  3. 들어오면 내보낸다.
  4. 기존에 방에 있던 사람들에게는 count를 +1한다.
  5. 새로 방에 들어왔다 나간 사람(l)에게는 방안에 있던사람 숫자만큼 count를 더한다.

→ 여기서는 나가는 사람을 더하는 과정이 좀더 깔끔해 보인다. 또 이런 방식으로 하면 set자료형을 사용할 수 도 있을 것처럼 보인다.



3. TIL

함수형으로 기능을 나누면서 느낀 점

  1. 며칠 전부터 함수마다 책임을 나누는 형태로 코드 짜는걸 연습해 봤는데,

    오늘 역시 enter_room 까지 만들어놓고 한번 돌려서 성능 체크하고

    count_add까지 만들어서 성능 체크를 해보니 오류가 발생했다.

  2. 그런데 enter_room 함수까지는 내가 원했던 그대로 작동했기 때문에

    count_add만 변경하면 된다는 점을 깨달았고, index 부분에 1을 빼주지 않아 문제가 발생했다는 점을

    비교적 빠르게 확인할 수 있었다.

  3. 또 기존에 문제풀이를 할 때는, 어디부터 어디까지 작성하고 테스트를 돌려야할 지 몰라

    거의 전체 코드를 완성하고 나서야 문제에 대해 하나하나 코드를 다시 뜯어보는 등의 작업을 했는데,

    오늘은 문제발견 → 피드백 → 해결의 싸이클 정말 빨랐다. 물론 비교적 간단한 문제라서 그렇겠지만...

    앞으로도 열심히 써먹어야겠다.

profile
코지베어

0개의 댓글