Kotlin 사전캠프 TIL 12일차

노재원·2024년 4월 3일
0

내일배움캠프

목록 보기
12/90

정보처리기사 실기도 준비하기

Level 4 전체 발표는 내일이라 오늘은 여유롭게 자습시간을 가질 수 있었다. 아마 내일도 발표 시간을 제외하면 시간이 남을 것 같다. 그래서 하기 싫지만 정보처리기사 문제도 풀어보기 시작했다.

굳이 내일배움캠프 기간에 겹치는데 신청해야하나 싶다가도 실기를 지난 3월에 신청해두긴 했다. 문제의 운빨에 따라 한 방에 붙을 수도 있다고 하니 시행횟수로 부딪혀서 합격해버리는게 차라리 나중에 부담이 덜하고 지금 희미하게나마 남아있는 필기 지식들이 도움이 될 테니 고생이더라도 실기를 같이 준비해야겠다.


그리고 TIL 게시글들의 요약을 좀 수정하기로 했다. 지금은 그냥 게시글의 150자를 자동으로 채워주니 그대로 게시중인데 일기 쓰는 습관때문에 TIL도 이 서론처럼 일기 스타일이라 제목에 키워드를 적기는 좀 그렇고 요약부에 핵심 키워드를 적어줘야 나중에 TIL을 돌아볼 때 엉뚱한 소리를 덜 볼 수 있을 것 같다.

일기처럼 안쓰고 배운 것만 적을까도 싶었지만 그러면 TIL을 적는데 내가 너무 재미가 없다. 본 캠프때는 좀 더 내용이 많아질 테니 그 때가서 고민하자. 지금 내가 하는 건 배운 내용을 위키처럼 정리하려는 건 아니니까..


부족한 금액 계산하기

새로 생긴 놀이기구는 인기가 매우 많아 줄이 끊이질 않습니다. 이 놀이기구의 원래 이용료는 price원 인데, 놀이기구를 N 번 째 이용한다면 원래 이용료의 N배를 받기로 하였습니다. 즉, 처음 이용료가 100이었다면 2번째에는 200, 3번째에는 300으로 요금이 인상됩니다.
놀이기구를 count번 타게 되면 현재 자신이 가지고 있는 금액에서 얼마가 모자라는지를 return 하도록 solution 함수를 완성하세요.
단, 금액이 부족하지 않으면 0을 return 하세요.

문제 링크

fun solution(price: Int, money: Int, count: Int): Long = 
	((1..count).sumOf { price.toLong() * it } - money).coerceAtLeast(0)

찾아 본 함수중 sumOf가 가장 의도에 적합해보여서 sumOf를 사용해 요금의 합을 계산하고 최종 모자란 금액의 처리에는 coerceAtLeast 함수가 있어서 적절하게 사용했다.
(sumBy는 Int로만 사용 가능한 것 같아 컴파일이 안됐다.)

coerce는 영어로 강제하다, 지배하다라는 뜻을 지녔다고 한다. 그러니 coerceAtLeast 또는 coerceAtMost를 사용하면 값의 최소 또는 최대 값을 조건문, 대입문 없이 메소드 체이닝으로 처리 가능하니 쓰기 좋아보인다.
(추가로 최소 최대 범위를 같이 지정할 수 있는 coerceIn도 있다.)


이걸 사용하기 전에는 변수에 담을 수 밖에 없나 싶었는데 적절한 함수가 있어 다행이었다.
하지만 다른 답안을 찾아보니 기존에 내가 알던 함수로도 충분히 처리 가능했었다.

fun solution3(price: Int, money: Int, count: Int): Long =
	(1..count).sumOf { price.toLong() * it }.let { if (money > it) 0 else it - money }

let을 사용하면 수신객체로 수식의 값을 처리에 다시 이용할 수 있으니 그냥 다른 방법을 몰랐다면 let으로 처리했어도 되는 문제였다.

그리고 어째서인지 let으로 처리한 방법이 실행 시간도 더 짧았는데 조사해보면 coerceAtLeast도 간결한 구문에 처리도 간단하다고 해서 실행시간 차이가 왜 나는 건지 정확한 이유는 끝내 찾아보지 못했다.
(gpt는 coerceAtLeast가 더 짧을 것이라고 예측했다.)


추가로 처음엔 map으로 처리하려다가 foldreduce로 넘어가고 잠시 후 더 간단한 방법이 있을 것 같아 찾아보다가 sumOf를 사용한 건데 map은 애초에 덜 적합하고 fold를 사용한 방법만 추가로 작성했다.

fun solution2(price: Int, money: Int, count: Int): Long = 
	((1..count).fold(0L) { total, num -> price.toLong() * num + total } - money).coerceAtLeast(0)

fold를 사용하면 람다 내에서 Parameter를 추가로 명시해줘야 하는게 좀 거슬렸다. total에 접근해야 하고 초기값도 변경이 필요하다면 적절히 사용했겠지만 이번 경우는 sumOf를 사용하는게 의도에 더 적합해보였다. (실행 시간도 sumOf보다 근소하게 느렸다.)

그리고 reduce는 내가 count를 범위 삼았기 때문에 reduce의 방식인 첫번째 값을 초기값으로 지정하게 되면 원하는 결과가 애초에 나오지 않아 고려 대상은 아니었다.

0개의 댓글