코트린 코드의 출현: 첫날

9324 단어 adventofcodekotlin

소개하다.


매년 이맘때면 바깥이 어둡고 추워지고(적어도 베를린에서) 사람들은 크리스마스 분위기에 들어가 크리스마스 장터에 가서 Gluhwein을 마시기 시작한다.실내에서 따뜻한 음료수를 편안하게 마시는 데 더 많은 시간을 들일 때다.
더 구체적으로 말하면, 만약 당신이 인코딩에 관심이 있다면, 오늘이 advent of code의 첫날이다.이 생각은 상당히 간단하다. 매일 프로그래밍 수수께끼를 발표하여 전날 해결해야 할 매일의 수수께끼를 풀려고 한다.
인코딩을 좋아하는 사람에게는 새로운 것을 배울 수 있는 좋은 기회이자 즐거움도 얻을 수 있다.
저는 개인적으로 Kotlin을 배우고 있기 때문에 이런 프로그래밍 언어 기능을 연습할 수 있는 기회입니다.
면책 성명: 이번 행사는 경쟁성이 있을 수 있기 때문에 일부 사람들에게 스트레스를 줄 수 있다.나는 매일 모든 수수께끼를 완성할 생각은 없다. 왜냐하면 '생활' 이기 때문이다.나도 가능한 한 빨리 혹은 간결하게 수수께끼를 해결하지 못했다.
반대로 내가 이번 활동에 참가하는 주요 목표는 세 가지가 있다.
  • Kotlin
  • 에서 인코딩 연습
  • 재밌게 놀았어
  • 내가 배운 지식을 지역사회와 공유
  • 다행히도, 당신도 Kotlin 학습에 관심이 있다면, JetBrains는 이 활동에 대한 blog post 을 공유했고, 당신이 어떻게 참여할 수 있는지 상세하게 설명했다.이 밖에 그들은 GitHub template를 만들어서 쉽게 시작할 수 있습니다.
    나의 계획은 내가 문제를 해결할 시간이 있는 날에 간단한 블로그 게시물을 써서 내가 일상적인 난제를 해결하는 방법을 공유하고 설명하는 것이다.
    첫날부터 시작합시다!

    첫날


    참고만: 지난 몇 년 동안 수수께끼의 난이도가 계속 증가했다. 처음 며칠은 한 번의 업그레이드로 볼 수 있다.

    수수께끼. - 1부.


    수수께끼 설명은 찾을 수 있다here. 나는 다음과 같이 요약할 것이다.

    Given a list of integers, return the number of times an element in the list is bigger than the previous element.


    솔루션


    다음은 제가 제시한 해결 방안입니다. 제가 나중에 상세하게 소개하겠습니다.
    fun countIncrease(input: List<Int>): Int {
        if (input.isEmpty()) return 0
    
        var count = 0
        var previous = input[0]
        val tail = input.drop(1)
        for (current in tail) {
            if (current > previous) {
                count += 1
            }
            previous = current
        }
        return count
    }
    
    이 방법은 정수 목록을 매개 변수로 하고 정수를 되돌려줍니다.
    순환 입력을 하기 전에, 나는 그것이 비어 있는지 확인했다. (비어 있다면, 우리는 미리 돌아올 수 있다.)그리고 나는 previous라는 임시 변수에서 목록의 첫 번째 요소를 추출했다. 이 변수는 가변적이며 항상 current 이전의 요소로 업데이트될 것이다.
    그리고 나는 목록에 있는 tail 을 순환해서 훑어보았다.i, e 첫 번째 요소를 삭제한 후의 입력 목록입니다.순환체에서 나는 current원소와 previous원소를 비교하기만 하면 전자가 후자보다 크면 count변수를 증가시킨다.그리고 나는 previous 변수를 current로 업데이트할 것이다.
    마지막으로 순환이 끝난 후에 나는 count 변수를 되돌려 주었다.
    여기서 재미있는 부분은 .drop API의 List 방법으로 첫 번째 요소를 포함하지 않은 새로운'읽기'목록의 실례를 간결하게 되돌려줍니다.

    수수께끼. - 2부.


    수수께끼의 두 번째 부분은 첫 번째 부분의 연장으로 사실상 똑같은 문제로 간주되고 계산하기 전에 추가 데이터 변환을 할 수 있다.
    실제로 우리는 모든 세 요소를 그룹으로 나누어 우리의 알고리즘을 새로운 변환 목록에 적용해야 한다.
    예를 들어 입력 목록이 [4, 1, 4, 1, 7]이면 변환된 목록은 [9, 6, 12], 4 + 1 + 4 = 9, 1 + 4 + 1 = 6, 4 + 1 + 7 = 12로 계산된다.일단 우리가 변환된 목록을 얻게 되면, 우리는 그것을 첫 번째 부분에서 우리의 함수로 전달하기만 하면 된다.

    솔루션


    다음은 제가 제안한 데이터 변환 솔루션입니다.
    fun buildTriples(input: List<Int>): List<Triple> {
        val lastFirst = input.size - 3
        return input
            .filterIndexed { index, _ -> index <= lastFirst }
            .mapIndexed { index, _ ->
                val first = input[index]
                val second = input[index + 1]
                val third = input[index + 2]
                Triple(first, second, third)
            }
    }
    
    data class Triple(val first: Int, val second: Int, val third: Int)
    
    fun Triple.sum(): Int = this.first + this.second + this.third
    
    이 방법은 목록의 모든 요소를 하나의 Triple 실례로 변환하고 Triple는 3개의 정수 속성을 가진 간단함data class이다.
    삼원조는 현재 요소와 목록에 있는 다음 두 요소를 포함한다.
    여기에 사용된 흥미로운 부분은 .filterIndexed API.mapIndexedList 방법이다.말 그대로 이들은 .filter.map에 해당하지만 현재 요소뿐만 아니라 한 쌍(index, element)을 제공한다.
    마지막 두 개를 제외한 모든 요소를 훑어보아야 하지만, 이 요소들에 접근해야 하기 때문에 .dropLast 을 사용하지 않고 색인 값을 사용하여 요소를 필터합니다.그리고 우리는 모든 원소를 현재 원소와 두 개의 후속 원소를 포함하는 삼중 원소로 전환해야 한다.이를 위해, 우리는 .mapIndexed 을 사용합니다. 현재 색인을 바탕으로 다음 요소에 접근하고, 모든 요소에 Triple 실례를 만들 수 있기 때문입니다.
    변환을 수행한 후에는 다음과 같이 결과를 다른 함수에 전달하기만 하면 됩니다.
    countIncrease(buildTriples(input).map { it.sum() })
    
    우리는 또한 extension function를 이용하여 Triple의 합을 계산한다.

    소스 코드


    너는 나의 해결 방안의 원본 코드here를 찾을 수 있다.
    읽어주셔서 감사합니다!

    좋은 웹페이지 즐겨찾기