[Kotlin/프로그래머스] 24년 1월 1주차 코드카타정리

지혜·2024년 1월 2일

Code_Kata

목록 보기
7/16

✏20240102 화요일

📖숨어있는 숫자의 덧셈(1)

  • 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의 역할과 유사하다.

📖문자열의 앞의 n글자

  • 문자열 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를 통해 두개를 바로 합칠 수 있게 된다.
  • 사실 아직도 좀 뿌옇게 이해된 것 같은데, 대충 돌아가는 원리는 알 것 같다. 얘도 여러번 봐야 익숙해질 것 같다.

📖n개 간격의 원소들

  • 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이 유효하게 적용되는지 이걸 보고 꺠달았다. 아무리 쉬운 문제더라도 이렇게 풀고나서 다른 사람들의 풀이를 보면 정말 많이 배우게 된다.
profile
파이팅!

0개의 댓글