시작과 동시에 튜터님의 호출을 받았다. 계산기 과제를 왜 이렇게 어렵게 풀었냐고 하셨다. 그리고 변수도 ll, dd 등 보기 어렵게 적어놨다는 얘기를 들었다. 그 말을 듣고 아차 싶었다. 나 혼자 보고 마는 알고리즘 풀이 같은 코드가 아닌, 과제로서 제출하고 누군가가 그걸 보고 평가해야 하는 코드라면 당연히 가독성에 신경써야했다. 심지어 튜터님은 수십명의 코드를 봐야 할 텐데 말이다. 주석 한 줄 안달아놓은 내 코드는 열자마자 닫아버리고 싶었을 것이다.
나중에 정식으로 받은 과제 피드백에서도 가독성 문제와, 간단한 문제를 어렵게 풀었다는 평을 받았다. 가독성 문제는 백번 동의하지만, 어렵게 풀었다는건 약간 억울하다. 3 + 5 형태 문자열을 통으로 받아 나누면서 각종 예외 처리하느라 길어진 거지, "연산을 선택하세요. 1:더하기 2:... / 두 숫자를 차례로 입력하세요" 식으로 했다면 간단했을 것이다. 출제자의 의도도 아마 그러했던 모양이다.
브랜치 사용법을 바탕으로, 안전하게 협업을 진행하기 위해서 main, dev, feature 브랜치로 나누어 개발하는 것을 배웠다. 단순히 merge의 단계를 나누는 것뿐만 아니라, pull request를 통해 자연스럽게 코드 리뷰를 하고 서로 피드백을 주는 과정이 생긴다는 것을 알았다. 지금껏 협업을 한다고 해도 그냥 서로 main에다 다 때려박았지, 이런 체계는 처음 알았다. (사실 관심 갖고 찾아봤으면 알았을텐데... 반성이 된다.)
사실 팀과제라지만 개인과제를 브랜치를 활용해 합쳐보는, 개인과제+깃헙 협업 기초 실습 이라고 봐야하겠다. 저번주에 강의 진도를 빨리 빼놨기에, 오늘 과제가 나오고 바로 시작했다. 메뉴가 많고, 추가될 수도 있고, 단계별로 출력물도 다르기에, 최대한 반복작업을 줄이기 위해 확장이 용이한 구조를 고민하며 작성하느라 오래걸렸다. 잘 만들었는지는 모르겠지만 일단 Lv2까지만 구현했다. 그런데 버거 클래스, 음료 클래스 등으로 설계하라는데, 그냥 다 똑같은 아이템 아닌가 하는 생각이다. 내일 데일리 스크럼에서 팀원들에게 조언을 구해봐야겠다.
문제 설명이 귀찮으니 링크 참고...
class Solution {
fun solution(num: Int): Int {
var count = 0
var a = num.toLong()
while (a != 1L) {
if (count == 500) return -1
if (a % 2 == 0L) a /= 2
else a = a * 3 + 1
++count
}
return count
}
}
풀이에 대해선 별로 설명할 게 없다. 정석대로 풀었다.
그런데 다른사람 풀이에서 처음보는 키워드를 봤다.
class Solution {
fun solution(num: Int): Int = collatzAlgorithm(num.toLong(),0)
tailrec fun collatzAlgorithm(n:Long, c:Int):Int =
when{
c > 500 -> -1
n == 1L -> c
else -> collatzAlgorithm(if( n%2 == 0L ) n/2 else (n*3)+1, c+1)
}
}
tailrec이 바로 그것이다.
'꼬리재귀'라는 것인데, 반환값에 추가 계산 없이 재귀 호출이 되면 꼬리재귀에 해당한다. tailrec은 코틀린에서 이를 파악해 재귀가 아닌 반복문으로 바꿔주는 아주 편리한 키워드이다.
엄청난 가독성을 갖추면서도 재귀의 성능상 단점을 없앴다는 점이 인상적이다.
고생많으셨어요~👍