주어지는 두 정수 배열의 행과 열이 같은 원소들을 더한 배열을 구하면 되는 문제였다. 2중 for
문을 사용하는 방법도 있겠지만, for
문 기피증이 있는 나는 (이유는 없다) forEach
나 map
을 사용해 풀고싶었다. 그래서 가독성은 좀 안좋지만 2중으로 mapIndexed
를 사용해 풀었는데, 세상에나 2차원 IntArray
로 쉽게 바꿀 수 있는 게 아니었다.
arr1.mapIndexed { i, a -> a.mapIndexed { j, aa -> aa + arr2[i][j] } }
// List<Array<Int>> 타입
주석에서처럼, 내부 원소가 Int형인 Array가 들어가 있는 리스트로 변환이 되는데 이를 Array<IntArray>
로 변환해야 했다. 찾아보니 먼저 내부의 Array<Int>
타입을 IntArray
로 바꿔주고, 다시 toTypedArray
를 통해 변환하는 방법이 있었다.
toTypedArray()
: 원래 컬렉션의 요소 타입과 동일한 요소 타입을 가진 배열을 생성해준다.
arr1.mapIndexed { i, a -> a.mapIndexed { j, aa -> aa + arr2[i][j] }.toIntArray() }.toTypedArray()
꼭 이런 형태여야 할까? 싶어서 toIntArray
만 두 번 써보기도 하고, toTypedArray
만 써보기도 하고 여러가지 해봤지만 위와 같은 형태만 성공을 했다. 문제에서 Array<IntArray>
타입을 원했기 때문에 당연한 사실이긴 하다.. 그래도 궁금한걸
풀고나서 보니, 배열을 생성할 때 초기화 단계에서 끝내버린 사람도 있었다. 아직 배열 초기화까지 써보지는 않았는데, 알아두면 도움이 될 것 같다.
Array(arr1.size) { row ->
IntArray(arr1[0].size) { col ->
arr1[row][col] + arr2[row][col] } }
2차원 배열을 초기화 하는 건 아직 너무 어려워 보이지만..! 익숙해질 수 있겠지..!
드디어 처음으로..! 사용자의 입력을 받는 코드를 작성해봤다. 사실 작성은 아니고 문제 풀이란에 미리 적혀져 있었다. 그 코드 중에서 !!
가 사용되었는데, 대충 느낌상 옵셔널을 푸는 것 같지만 조금 더 정리된 문장으로 기억해두고 싶어서 알아보았다.
val (n, m) = readLine()!!.split(' ').map(String::toInt)
readLine()
함수가 항상 null
이 아닌 값을 반환한다고 가정하고, 그렇지 않을 경우에는 예외를 발생시키는 방법이라고 한다. 사용자의 입력이 없을 수 있으니 readLine()
함수는 입력 값을 Nullable
로 다루는 것 같다. 역시나 코틀린 문서를 확인해보면, String?
타입인 걸 확인할 수 있다!
fun readLine(): String?
주어지는 두 수의 최대 공약수와 최소 공배수를 구하는 문제를 풀어보았다. 사실 이전에 파이썬으로 한 번 푼 적이 있었던 문제였는데, 문제는 기억이 안난다는 거다. 다행히 주석으로 유클리드호제법을 적어놔서 휴지통에 있던 기억을 겨우겨우 복원해 풀어보았다.
def solution(n, m):
# 유클리드호제법 - 최대공약수
gcd = lambda a, b: gcd(b, a%b) if a%b else b
return [gcd(n, m), n*m/gcd(n, m)]
코드를 확인해보니 대충 유클리드호제법이 무엇인지 알 것 같다.
두 수 a와 b의 최대 공약수는 b와 a를 b로 나눈 나머지의 최대 공약수와 같고, 이를 나머지가 0이 될 때까지 반복하면 a와 b의 최대 공약수를 구할 수 있다.
참고로 최소 공배수는 두 수의 곱을 최대공약수로 나누면 된다. 나는 까먹어서 또 찾아보았다. ㅎ..
아무튼 최대 공약수는 코틀린의 재귀 함수를 사용해 풀어보았다. 알게 된 지 얼마 안됐는데 생각보다 금방 사용하게 돼서 전에 미리 알아보길 잘 한 것 같다.
tailrec fun gcd(x: Int, y: Int): Int = if (x % y == 0) y else gcd(y, x%y)
그런데 세상에나, 어차피 y
에 들어오는 건 나머지기 때문에 조건을 아예 if (y == 0)
으로 해도 되는 거였다! 이렇게 또 알아간다..
10진수를 3진수로 변환한 후, 거꾸로 뒤집은 수의 10진수를 구하는 문제였다. 나는 코틀린에 3진수로 변환하는 함수가 따로 없는 줄 알고 너무나 정직하게 풀어버렸다.
fun solution(n: Int): Int {
var s = ""
var div = n
// 3진수 변환 (거꾸로)
while (div != 0) {
s += (div%3).toString()
div /= 3
}
return s.toInt(3)
}
사실 3진수를 10진수로 변환하는 함수도 없을 것 같아서 반복문을 쓰려다가 혹시…? 하는 마음에 찾아봤더니 toInt(변환할진법)
를 사용하면 가능하대서 이걸 이용해 풀었는데…
toString()
도.. 같은 방식으로.. 사용이.. 가능하다..
n.toString(3).reversed().toInt(3)
오늘도 어김없이 뒤통수를 맞은 나다. 그래. 모르면 당해야지. 다음엔 안당할 자신 있다.