직관적인 코드 vs 간결한 코드
알고리즘 풀때 코드를 종종 고치는 습관이 있는데요, 오늘도 그런 코드를 하나 만났습니다. 이 코드를 한 번 볼께요.
for i in range(N) :
if L[i] == 'B' :
blue_left+=1
if i > blue_left : # 여기가 문제
blue_cnt_left+=1
원래 처음 의식의 흐름으로 작성한 코드는 아래와 같습니다.
for i in range(N) :
if L[i] == 'B' :
if i > blue_left+1 :
blue_left+=1 # 중
blue_cnt_left+=1
else :
blue_left+=1 # 복
일단 처음에 코드를 짤 때 blue_left에는 "왼쪽에 연속된 B의 마지막 인덱스" 라는 암묵적인 의미를 부여해주었습니다.
BBBAAB 라면 blue_left = 2 가 되는거죠.
아래 코드를 보면 blue_left+1 이 있죠? "왼쪽에 연속된 B의 마지막 인덱스의 바로 다음 인덱스" 즉 "B가 새롭게 붙을 인덱스" 라는 의미가 직관적으로 와닿습니다.
그래서 if 조건문에 맞으면 다음 단계로 넘어가면서 카운트도 1 늘려주고, 조건에 부합하지 않았으면 카운트 증가 없이 다음 단계로 넘어가기 라는 의미로 코드를 짰습니다.
그런데 짜고 보니까 blue_left+=1 이 if 와 else 에 모두 들어가있길래 밖으로 빼주었습니다. 그러면 if 문 안에서 +1 연산도 안해줘도 되고, 코드가 간결해지니까요.
그런데 수정하고나니 제가 단계적이고 직관적으로 밟아간 의식의 흐름에서 도약이 생기는 느낌이 듭니다.
수정 후 코드를 의미로 따져보면 다음 단계로 미리 넘어가놓고 이전 단계의 상태에서 조건문을 처리해줘야하고, blue_left 의 암묵적 의미가 순간적으로 깨집니다. 쫓아가다가 뇌가 좀 꼬이는..
여태까지는 위에처럼 짜는게 더 멋지고 제가 좀 더 똑똑해지는 방향이라고 생각했습니다. 수학 문제 풀때 종이가 깨끗할수록 간지나는 느낌이랄까요? 그래서 항상 이런 부분들이 보이면 수정하곤 했습니다.
그런데 오늘 문득 의문이 드네요. N^0 = 1 을 증명할때 0 을 1-1 로 바꿔서 시작하는데, 그 단계를 다 빼고 N^0 = 1 만 쓰는게 과연 무슨 도움이 될까.. 수능 수학을 공부할때도 처음엔 '풀이 그거 뭐가 중요한데~' 하면서 날림으로 답만 냈다가 가면 갈수록 풀이를 논리적으로 깔끔하게 쓰는게 정답이라는걸 깨닫고 뭐랄까.. 쌤들 말 하나 틀린게 없구나 라면서 좀 더 겸손한 자세로 문제를 대하기 시작했던 기억이 나네요..ㅎㅎ
이런 암묵적 의미들을 최대한 깨지 않고 가져가는게 읽기 좋은 코드인 것 같습니다. 그리고 코드 규모가 커질수록 읽기 좋은 코드가 가장 중요하지 않을까 라는 생각이 듭니다.
아 이거랑 비슷한 고민으로 if문을 몇단계로 쪼개야되나 하는 것도 있습니다ㅠㅠ
근데 진짜 어려운건 어디까지 간결해져도 되는거지? 라는 그 선타기인 것 같습니다.