Advent of Code 2023 Day 2 - Kotlin

cotton·2023년 12월 2일

Advent of Code 2023

목록 보기
2/4
post-thumbnail

🔥 매년 12월 1일부터 12월 25일까지 한 문제씩 프로그래밍 퍼즐을 제공하는 사이트다. Eric Wastl이 2015년에 만든 사이트로, 재림절 달력(Advent calendar)을 매일 열어보듯이 크리스마스까지 꾸준히 문제를 해결해나간다는 컨셉이다. 퍼즐은 UTC-5 기준으로 자정, 한국시간으로는 오후 2시에 공개된다.
출처 : 나무위키 - Advent of Code

Advent of Code가 2023년 돌아왔습니다! 25일간 프로그래밍 퍼즐을 풀어봅시다.

Jetbrains는 이번에도 어김없이 Kotlin을 통해 25일간의 AoC에 참가하면 코틀린 독점 상품을 받을 수 있는 기회를 준다고 합니다!

자세한 내용은 코틀린 블로그에 개제된 Tackle Advent of Code 2023 With Kotlin and Win Prizes! 를 참고하세요.

오늘은 두 번째 문제인 Cube Conundrum 문제를 풀어봤습니다.

Part 1

문제 풀이

엘프들이 작은 가방 안에 있는 빨간색, 초록색, 파란색 큐브를 랜덤하게 꺼냅니다.

이 때 랜덤하게 뽑은 큐브를 보여주고 다시 주머니 안에 넣습니다.

Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green

Game 1의 경우에는 3개의 파란색 큐브와 4개의 빨간색 큐브를 보여주고, 집어넣습니다. (;) 그리고 이를 반복합니다.
이 때 엘프의 가방에는 빨간색 큐브 12개, 녹색 큐브 13개, 파란색 큐브 14개만 있는 상태에서 위 게임들의 결과 중 가능한 결과의 ID 합계를 구합니다.
가능한 게임은 1, 2, 5이므로, 답은 8입니다.

내 풀이

fun part1(input: List<String>): Int {
		var sum = 0
		input.forEachIndexed { idx, str ->
		    val list = str.split(*arrayOf(";", ":", ",")).drop(1).map { it.trim().split(" ") }
		    for (pair in list) {
		        when (pair.last()) {
		            "red" -> if (pair.first().toInt() > 12) return@forEachIndexed
		            "green" -> if (pair.first().toInt() > 13) return@forEachIndexed
		            "blue" -> if (pair.first().toInt() > 14) return@forEachIndexed
		        }
		    }
		    sum += idx + 1
		}
		return sum
}
  • 문자열을 ;, :, , 로 자릅니다. 해당 값으로 자른 리스트는 [ “Game 1”, “ 3 blue”, “4 red” … ] 와 같이 첫 번째 값을 제외하고는 큐브 색깔과 개수를 의미합니다.
  • drop(1) 으로 게임을 의미하는 첫번째 값을 버리고, 큐브 색깔과 개수를 의미하는 리스트만 남깁니다.
    “3 blue” 와 같은 형태로 내려오기 때문에 공백을 기준으로 나눠서 [3, blue] 같은 형태로 매핑하고 다시 순회합니다.
  • list.last()를 통해 색깔을 가져와 when문으로 구분하고, list.first()를 통해 큐브 개수를 가져와 비교합니다. 만약에 각각의 개수보다 많은 경우에는 forEachIndexed를 탈출해 합계에 합산되지 않고, 각각의 개수보다 모두 적은 경우에는 인덱스 값을 기준으로 합산합니다.

다른 사람들 풀이

🔥 다른 사람들의 풀이는 KotlinLang Slack에 참여하면 확인할 수 있습니다!

  • 주어진 문자열에서 : 다음의 문자들을 substringAfter 를 이용해 추출합니다.
    • 내 코드의 split().drop(1) 과 같은 느낌의 동작
  • ;,를 기준으로 나누고, 공백을 기준으로 subStringBefore / subStringAfter를 이용해 숫자와 색깔을 구분하고 조건문에 맞게 돌립니다. 조건에 걸리는 경우 (게임에서 주머니 안에 있는 큐브의 개수가 더 많은 경우) 는 반환합니다
  • 해당 조건에 걸리지 않은 경우 (게임이 조건에 맞게 돌아갈 수 있는 경우) 에는 처음 문자열에서 Game 1: ... 에서 공백과 : 사이에 있는 숫자를 도출해 합계를 반환합니다.

Part 2

문제 풀이

이번에는 보유 중인 개수에 제한하지 않고, 한 번에 가장 많은 색깔을 꺼낸 경우들을 모두 곱연산합니다.

Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green

마찬가지로 Game 3을 예시로 들면, 빨간색을 20개, 초록색을 13개, 파란색을 6개 꺼냈으므로, 20 x 13 x 6 , 1560이 답이 됩니다.

내 풀이

fun part2(input: List<String>): Int {
    var sum = 0
    for (str in input) {
        val list = str.split(*arrayOf(";", ":", ",")).drop(1).map { it.trim().split(" ") }
        var red = 0
        var green = 0
        var blue = 0
        for (map in list) {
            when (map[1]) {
                "red" -> {
                    red = listOf(red, map[0].toInt()).max()
                }
                "green" -> {
                    green = listOf(green, map[0].toInt()).max()
                }
                "blue" -> {
                    blue = listOf(blue, map[0].toInt()).max()
                }
            }
        }
        sum += red * green * blue
    }
    return sum
}
  • 아까와 동일하게 주어진 문자열을 수정해 List<List<String>> 형태로 만듭니다.
  • 이번에는 리스트 전체를 순회하면서 각 색깔의 최대 숫자를 max() 를 통해 저장합니다.
  • 전체 순회 후, 합계 변수에 각 색깔 숫자 값을 곱해 더합니다.

다른 사람의 풀이

  • 각각의 색깔의 max 값을 저장하기 위한 map을 만듭니다.
  • 맨 앞의 Game 1: 을 substringAfter 를 이용해 제거한 이후, ;, 를 기준으로 분리합니다.
  • 기존에 map에 저장한 값과 비교하면서 최대값을 map에 저장합니다.
  • 그 이후 map에 있는 값을 꺼내, 숫자 값을 곱해 반환합니다.
profile
안드로이드 개발자

0개의 댓글