✏20240102 화요일
- my_string에 대해서 isDigit()를 사용해 숫자를 판별하여 filter로 거른 후, 남아있는 것들에 대해서 sumOf를 통해 숫자로 바꾼 후 그 합산을 반환했다.
class Solution {
fun solution(my_string: String): Int {
return my_string.filter { it.isDigit() }.sumOf{it.digitToInt()}
}
}
📖숨어있는 숫자의 덧셈(1)문제의 다른 사람 풀이
class Solution {
fun solution(my_string: String): Int =
my_string.filter(Char::isDigit)
.sumOf(Char::digitToInt)
}
- 똑같은 원리의 풀이지만, 모양이 달라서 가져와보았다.
- :: (더블콜론) : 참조
- 여기서는 :: 을 통해 함수를 참조하였다. 이외에도 클래스,메소드 등 참조가 가능하다.
- filter를 통해 각 요소를 char로 받고, 그에 대해 isDigit(digitToInt)를 참조하는 방식.
- 참조 또한 낯선 모양이기 때문에 주기적으로 눈에 익혀둬야 할 것 같다.
- my_string에 대하여, isUpperCase( )를 통해 대문자인지 아닌지 판별하고, 대문자라면 소문자로, 소문자라면 대문자로 변환하도록 toLowerCase( ), toUpperCase( )를 사용했다.
- 마지막으로 리스트로 되어있는 타입을 joinToString("")을 사용하여 문자열로 변환하여 반환하였다.
class Solution {
fun solution(my_string: String): String = my_string
.map{if(it.isUpperCase()) it.toLowerCase() else it.toUpperCase()}
.joinToString("")
}
- isDigit( )처럼, 대문자와 소문자도 판별할 수 있는 함수가 있다.
- isUpperCase( ) : 대문자인지 판별하여 true,false 반환.
- isLowerCase( ) : 소문자인지 판별하여 true,false 반환.
- 이렇게 아예 판별을 할 수 있게 is~( )로 묶여나온 함수들이 많이 있는 것 같다. 그냥 is자체가 판별식 역할을 할 수 도 있게 활용되는 것 같은데, is에 대해서 기억하고 있으면 많은 곳에서 유용할 것 같다.
- 문자열 rsp에 대하여 map안에서 when을 통해, 각 상황에 맞는 반환값이 오도록 한 후, joinToString("")을 통해 다시 문자열로 합쳐주었다.
class Solution {
fun solution(rsp: String): String = rsp.map{
when(it) {
'2' -> '0'
'0' -> '5'
else -> '2'
}
}.joinToString("")
}
- "(쌍따옴표)를 쓰면 String으로 인식하고, '(싱글쿼터)를 사용해야 Char로 인식해준다는 것을.. 이 문제를 풀며 새삼 깨달았다. when안에서 value로 작성한 it에 대해, it의 타입과 맞춰주지 않으면 오류가 나는 것은 당연하지만.. 좀 더 유의해야겠다.
✏20240103 수요일
- if문을 통해 짝수를 구분하여 짝수이면 "입력한숫자 is even", 홀수이면 "입력한숫자 is odd"가 출력되도록 한다.
fun main(args: Array<String>) {
val a = readLine()!!.toInt()
if(a % 2 == 0) println("$a is even") else println("$a is odd")
}
- 쉬운 문제임에도 들고온 이유는.. return값 없이 Unit타입 문제를 처음 보고 당황스러웠기 때문이다..
- return값이 없어서 println으로 출력을 했는데, print 안에 출력 문법에서 당황했다. 자바에서는 println(변수명 + "출력하고싶은문장") 이렇게 연결했던 것 같은데..
물론 이 방법도 사용가능 하겠지만은, 코틀린에서는 전부 따옴표 안에 작성하는 것이 더 효율적이다.
📖홀짝 구분하기 문제의 다른 사람 풀이
println("$a is ${if (a % 2 == 0) "even" else "odd"}")
- $a처럼 문자열 내에서 단일 변수를 출력할 때는 중괄호를 생략할 수 있다.
- 하지만 ${if (a % 2 == 0) "even" else "odd"}처럼 코드 자체를 활용하고 싶거나, 확장함수 등을 붙여서 사용하고 싶다면 ${ } 중괄호를 활용하여 꼭 묶어줘야 인식을 한다.
import kotlin.math.*
class Solution {
fun solution(a: Int, b: Int): Int {
return max("$a$b".toInt(), "$b$a".toInt())
}
}
- 이 문제는 반환타입이 Unit은 아니지만, $+변수명 을 활용한 풀이가 인상 깊어서 가져왔다.
- "$a$b"처럼 a와b를 합친 모습 자체에 .toInt( ) 확장함수를 붙여서 활용할 수 도 있다.
📖Unit타입
- 함수의 반환 타입이 Unit 일 경우, 반환 값을 생략할 수 있다.
즉, 반환 값이 필요 없는 경우에는 Unit 타입을 사용한다.
- 위의 코드에서 fun main(args: Array<String>) : Unit 이 생략되어 있다. 따로 반환 타입이 명시되어 있지 않다면 기본적으로 Unit타입이다.
- 위의 코드에서 return Unit (return) 자체가 생략되어 있다. 선택적으로 작성이 가능하다. 생략을 해도 암묵적으로 Unit 타입 객체를 반환한다.
- 자바에서 void의 역할과 유사하다.
- 문자열 my_string에 slice를 활용하여 0번부터 n번 인덱스의 앞까지 자르도록 작성했다.
class Solution {
fun solution(my_string: String, n: Int): String
= my_string.slice(0 until n)
}
- 이 문제도 쉽게 풀었지만, 다른 사람의 풀이 중에 기억하고 싶은 부분이 있어서 가져왔다.
📖문자열의 앞의 n글자 문제의 다른 사람 풀이 : take( )를 활용한 방법
class Solution {
fun solution(my_string: String, n: Int): String {
return my_string.take(n)
}
}
- take(n: Int) : n 개수 만큼의 값을 앞에서 부터 반환한다.
- slice와 substring은 문제 풀이를 하면서 많이 봤지만, take는 처음 보는 것 같다.
- 당연하지만, 문자열말고 리스트에서도 활용이 가능하다.
- 이외의 take를 바탕으로하는 함수들
- takeWhile {boolean식} : 식의 조건이 false가 될때까지 앞에서 부터 값을 취해 반환.
- takeLast(n: Int) : n 개수 만큼의 값을 뒤에서 부터 반환한다.
- takeLastWhile {boolean식} : 식의 조건이 false가 될때까지 뒤에서 부터 값을 취해 반환.
- takeIf{boolean식} : 확장함수의 수신객체가 특정 조건을 만족 시킨다면 수신객체 자체를 반환, 불만족한다면 null을 반환.
- takeIf는 다른 문제 풀이에서 종종 활용하는 모습을 봤었다. 여기서 한 번 정리하게 되었으니까 필요할 때 사용할 수 있도록 익숙해져야겠다.
✏20240104 목요일
- answer에 add를 사용할 수 있도록 ArrayList 타입으로 변환한 num_list를 할당해둔다.
- num_list.last()로 리스트의 마지막 값을 구하고, num_list[num_list.size-2]를 통해 마지막 원소의 전 원소를 구한다.
- if문을 통해 둘을 비교하여 문제에서 요구하는 값을 add 해준다.
- 마지막으로 ArrayList 타입의 answer을 요구하는 반환타입인 IntArray 로 변환해준 후 반환한다.
class Solution {
fun solution(num_list: IntArray): IntArray {
var answer = num_list.toCollection(ArrayList<Int>())
if(num_list.last()>num_list[num_list.size-2]){
answer.add(num_list.last() -num_list[num_list.size-2])
} else answer.add(num_list.last()*2)
return answer.toIntArray()
}
}
- 지금 생객해보면 num_list.last()랑 num_list[num_list.size-2]에 대해 변수를 선언해줄껄. 그럼 더 깔끔했을텐데.. 라는 생각이 든다.
- 마지막원소를 구하는 방법은 여러가지 가 있지만(lastIndex, size-1 등), 그 앞에 함수를 가져오는 것은 살짝 애매했다. lastIndex와 lastIndex-1을 사용하면 통일감이 었어보여서 좋지 않았을까 하고 다른사람의 풀이를 보고 생각해본다..
- answer의 경우 var answer: IntArray = intArrayOf() 로 되어있었어서 대뜸 answer.add했더니 내가 add한 값만 하나 들어가 있었다. 당연하다. 비워져있으니까.. 그래서 answer자체를 num_list로 초기화 했다.
📖마지막 두 원소 문제의 다른 사람 풀이
class Solution {
fun solution(num_list: IntArray): IntArray {
val answer = num_list.toMutableList().apply {
val (first, second) = num_list.takeLast(2)
if (first < second) add(second - first)
else add(second + second)
}
return answer.toIntArray()
}
}
- takeLast를 사용하여 뒤에서 부터 2개를 가져와, first와 second에 각각 할당한다. (여러개의 값을 동시에 할당하는 구조 분해 선언)
- take는 이번주에 정리한 개념인데, 여기서 또 보니까 아차! 싶었다. 아예 생각을 안한 건 아닌데.. 오늘은 마음이 급해서 그냥 익숙한 것을 선택해버렸다.
- 그리고 MutableList 처럼 배열 선언하는 것에 아직도 버벅거린다. 맨날 초기화해준대로 쓰는 버릇 하다보니까.. 머리로 안다고 손까지 내려오는건 아니라던데 더 노력해야겠다.
- 원소들의 합을 구한 후, 제곱을 사용하기 위해 더블타입으로 변경해주었다. pow(2)로 제곱한 값을 sumPow에 할당했다.
- 원소들의 곱을 구하기 위해 reduce를 사용했다.
import kotlin.math.*
class Solution {
fun solution(num_list: IntArray): Int {
var sumPow = num_list.sum().toDouble().pow(2)
var multiN = num_list.reduce{total, n -> total * n}
return if (sumPow>multiN) 1 else 0
}
}
- reduce( ) : 초기값은 컬렉션의 첫번째 요소. 반환값은 컬렉션의 자료형이다.
- reduce는 이전에 정리한 적이 있지만.. 정리한기억은 있고 사용한 기억은 없어서 사용하기위해 오늘 다시 .. 검사를 해봤다.ㅎ 사실 total *= n 이라고 적었다가 오류를 만났다. *= 해주지 않아도 기본이 누적되는 형식인데... 반성했다.
- pow를 사용하기위해서 앞에 Double(Float)타입이 와야한다는 것도 계속 주의해야겠다.
✏20240105 금요일
- 숫자를 짝수와 홀수 나눠서 담기위해 even과 odd 변수를 만들었다. += 연산자로 바로 담을 수 있도록 String타입으로 만들었다.
- for문을 통해 num_list 값들을 돌면서 짝수인지 홀수인지 판별하고 각각의 자리에 이어붙여질 수 있도록 작성했다.
- 마지막으로 String타입을 Int타입으로 바꾸어서 더해준 값을 반환했다.
class Solution {
fun solution(num_list: IntArray): Int {
var even = ""
var odd = ""
for(i in num_list){
if(i % 2 == 0) even += i.toString()
else odd += i.toString()
}
return even.toInt() + odd.toInt()
}
}
- 문자열도 거의 리스트처럼 활용가능하다고 생각해서 even이랑 odd를 String으로 선언하고 혼자 뿌듯해했다.. += 으로 바로 담는 것이 유독 편하다고 느껴진다. 다만.. 당연히 문자열에 들어가야하니까 Int타입일 i에 대해서 .toString( )으로 변환해줘야한다고 생각했는데, 변환해주지 않아도 잘만 들어간다. 이런때에는 또 포용력이 넓다.. 참 나...
- 사실 이 문제를 들고 온 이유는 toInt( )때문이다. 맨처음에는 even이랑 odd에 대해서 digitToInt( )를 쓰려고했었다. 보여지는 그대로 숫자를 변경해야된다는데에 꽂혔기 때문이다. 근데 digitToInt( )는 Char타입일때! 얘네는 아스키 코드여서 toInt( )일때 아스키코드의 숫자로 변환되니까, 이럴 떄 편의상 쓰는게 digitToInt( )였던거고, String은 숫자문자열에게 toInt( )쓰면 원래 보이는 그대로 잘 변환이 된다. 괜히 좀 헤맸다.ㅎ
📖이어 붙인 수 문제의 다른 사람 풀이
class Solution {
fun solution(numList: IntArray)
= numList.partition { it % 2 == 0 }.toList()
.sumOf { it.joinToString("").toInt() }
}
- partition {boolean조건} : true와 false인 경우로 리스트를 분리해준다.
List, Set에서는 사용가능하나, Map에서는 사용불가능하다.
반환타입은Pair<List<요소타입>,List<요소타입>>으로, first(ture해당요소들)와 second(false해당요소들)으로 접근 가능하다.
- partition함수는 처음보는 것 같다. 이 풀이에서는 .toList( )로 바로 변환했기 때문에 짝수로 분할된 요소와 홀수로 분할된 요소를 가지고 있어서 그 뒤에 .sumOf를 통해 두개를 바로 합칠 수 있게 된다.
- 사실 아직도 좀 뿌옇게 이해된 것 같은데, 대충 돌아가는 원리는 알 것 같다. 얘도 여러번 봐야 익숙해질 것 같다.
- for문을 통해 0 번부터 num_list의 마지막인덱스번호까지 n개씩 건너뛰어 i가 반복되도록하고, num_list[i]를 answer에 +=으로 담아, answer를 반환한다.
class Solution {
fun solution(num_list: IntArray, n: Int): IntArray {
var answer: IntArray = intArrayOf()
for(i in 0..num_list.lastIndex step n){
answer += num_list[i]
}
return answer
}
}
📖n개 간격의 원소들 문제의 다른 사람 풀이
class Solution {
fun solution(nums: IntArray, n: Int) = nums.slice(nums.indices step n)
}
- indices : collection의 유효한 인덱스 범위 를 반환한다.
- indices를 솔직히 풀이 때마다 자주 봤지만, 오늘은 꼭 정리를 해야겠다고 생각했다. 여태껏 보고도 잘 안썼었는데.. 범위를 반환한다는 게 꽤 큰 메리트가 있는 것 같다. 왠지 자주 쓰이더니.. 다 이유가 있는 것이다.
- 이 풀이에서는 slice에서 indices범위를 step과 함께 사용했다. slice 안에서도 step이 유효하게 적용되는지 이걸 보고 꺠달았다. 아무리 쉬운 문제더라도 이렇게 풀고나서 다른 사람들의 풀이를 보면 정말 많이 배우게 된다.