[TIL][내일배움캠프]

[내일배움캠프][TIL] 23.11.29 (수) - 과일 장수, Kotlin 문법 기초 과제 (계산기 만들기)

kimlaurant 2023. 11. 29. 19:59
1. 코드카타

 

오늘 푼 알고리즘 문제는 '과일 장수' 이다.

 

 과일 장수

 

이 문제는 매개변수가 k, m으로 주어져서 자칫 k를 이용하여 답을 구해야하는 것처럼 보이지만, 실상은 아니다.

왜냐하면 사과 상자의 가격은 상자 안에 들어있는 사과 중에서 가장 질이 낮은 사과에 달려 있기 때문이다.

 

예를 들어, 위의 예제에 있는 score = [4, 1, 2, 2, 4, 4, 4, 4, 1, 2, 4, 2]를 들자면 m이 3이므로 3개씩 담으면 되는데 아무리 품질이 4인 사과를 2개 넣어도 품질이 1인 사과 1개를 집어넣는 순간 그 사과 상자의 가격은 3이 되어버린다.

 

그렇기 때문에 이 문제에서 최대의 이익을 뽑아내는 방법은 정해져 있다.

 

score를 숫자가 높은 순서대로 정렬시킨 다음 m개씩 분류하는 것.

 

이를 코드로 나타내면 다음과 같다.

 

class Solution {
    fun solution(k: Int, m: Int, score: IntArray): Int {
        var answer: Int = 0
        var box: Int = (score.size)/m
        var sortedScore = score.sortedDescending()
        
        for (i in 0 until box) {
            answer += sortedScore[m*(i+1)-1] * m
        }
        
        
        return answer
    }
}

 

여기서 box는 상자의 개수를 뜻하고, sortedScore는 score를 내림차순으로 정렬시킨 배열이다.

 

그리고 반복문은 m개씩 분류한 사과들 중 가장 마지막 순서의 사과의 품질을 골라서 사과 상자의 가격을 계산한다.

 

 

이렇게 오늘의 알고리즘 문제도 수월하게 클리어.

다만, 이 다음부터 남은 문제들은 하나같이 복잡해보여서 벌써부터 겁이 난다.

 

 

2. Kotlin 문법 기초 과제 - 계산기 만들기

 

이번주에는 Kotlin 문법을 배움과 동시에, 그걸 얼마나 활용을 잘 하는지 개인 과제를 내주었다.

 

이번 과제는 바로 계산기이다.

구현해야 하는 기능은 다음과 같이 단계별로 나뉘어있다.

 

  • Lv1 : 더하기, 빼기, 나누기, 곱하기 연산을 수행할 수 있는 Calculator 클래스를 만들고, 클래스를 이용하여 연산을 진행하고 출력하기
  • Lv2 : Lv1에서 만든 Calculator 클래스에 출력 이후 추가 연산을 가능하도록 코드를 추가하고, 연산 진행 후 출력하기
  • Lv3 : AddOperation(더하기), SubstractOperation(빼기), MultiplyOperation(곱하기), DivideOperation(나누기) 연산 클래스를 만든 후 클래스간의 관계를 고려하여 Calculator 클래스와 관계를 맺기
  • Lv4 (선택) : AddOperation(더하기), SubtractOperation(빼기), MultiplyOperation(곱하기), DivideOperation(나누기) 연산 클래스들을 AbstractOperation라는 클래스명으로 만들어 사용하여 추상화하고 Calculator 클래스의 내부 코드를 변경하기

 

우선은 Lv1부터 차근차근 밟아보자.

 

  • Lv1 : 더하기, 빼기, 나누기, 곱하기 연산을 수행할 수 있는 Calculator 클래스를 만들고, 클래스를 이용하여 연산을 진행하고 출력하기
fun main(num1: Int, num2: Int) {
    var num1 = readLine()!!.toInt()
    var num2 = readLine()!!.toInt()
    var num = 0

    println("어떤 연산자를 사용하시겠습니까?")
    println("[1] 덧셈  [2] 뺄셈  [3] 곱셈  [4] 나눗셈")
    var operator = readLine()!!.toInt()

    if (operator == 1) {
        num = num1 + num2
        println("덧셈 결과 ${num} 입니다.")
    }

    else if (operator == 2) {
        num = num1 - num2
        println("뺄셈 결과 ${num} 입니다.")
    }

    else if (operator == 3) {
        num = num1 * num2
        println("곱셈 결과 ${num} 입니다.")
    }

    else if (operator == 4) {
        num = num1 / num2
        println("나눗셈 결과 ${num} 입니다.")
    }

    else {
        println("계산기를 실행할 수 없습니다.")
    }

}

 

 

그 다음 Lv2.

 

  • Lv2 : Lv1에서 만든 Calculator 클래스에 출력 이후 추가 연산을 가능하도록 코드를 추가하고, 연산 진행 후 출력하기

Lv2는 Lv1에서 완성된 계산기에 '이전에 진행했던 값을 다시 써서 계산하는' 기능을 추가하면 된다.

 

fun main() {
    var num1 = readLine()!!.toInt()
    var num2 = readLine()!!.toInt()
    var num = 0

    println("어떤 연산자를 사용하시겠습니까?")
    println("[1] 덧셈  [2] 뺄셈  [3] 곱셈  [4] 나눗셈")
    var operator = readLine()!!.toInt()

    if (operator == 1) {
        num = num1 + num2
        println("덧셈 결과 ${num} 입니다.")
    }

    else if (operator == 2) {
        num = num1 - num2
        println("뺄셈 결과 ${num} 입니다.")
    }

    else if (operator == 3) {
        num = num1 * num2
        println("곱셈 결과 ${num} 입니다.")
    }

    else if (operator == 4) {
        num = num1 / num2
        println("나눗셈 결과 ${num} 입니다.")
    }

    else {
        println("계산기를 실행할 수 없습니다.")
    }

    var i = 1
    while (i == 1) {
        println("계산기를 계속 사용하시겠습니까?")
        println("[1] 예  [2] 아니오")
        var continueCal = readLine()!!.toInt()

        if (continueCal == 1){
            var num3 = readLine()!!.toInt()
            println("어떤 연산자를 사용하시겠습니까?")
            println("[1] 덧셈  [2] 뺄셈  [3] 곱셈  [4] 나눗셈")
            var operator = readLine()!!.toInt()

            if (operator == 1) {
                num = num + num3
                println("덧셈 결과 ${num} 입니다.")
            }

            else if (operator == 2) {
                num = num - num3
                println("뺄셈 결과 ${num} 입니다.")
            }

            else if (operator == 3) {
                num = num * num3
                println("곱셈 결과 ${num} 입니다.")
            }

            else if (operator == 4) {
                num = num / num3
                println("나눗셈 결과 ${num} 입니다.")
            }
            
            else {
                println("계산기를 실행할 수 없습니다.")
                break
    		}
        }
        
        else {
            i--
        }
    }

}

 

그런데 적다보니까 길이가 너무 길어졌다. 사실상 코드 하나를 더 붙인 꼴이라.

…뭔가 이런 식으로 하는 건 맞는 것 같은데 좀 더 간단하게 줄일 수 없나? 아직 시간은 있으니 조금 더 고민해보기로 했다.

 

 

그리고 대망의 Lv3.

 

  • Lv3 : AddOperation(더하기), SubstractOperation(빼기), MultiplyOperation(곱하기), DivideOperation(나누기) 연산 클래스를 만든 후 클래스간의 관계를 고려하여 Calculator 클래스와 관계를 맺기

이거는 각각의 연산 클래스를 만들고나서 Calculator 클래스와 관계를 맺으면 되는데 클래스 간에 상속을 하면 되는 걸까?

 

이것 역시 조금만 더 생각해보고 내일 한 번 짜보기로 했다.