Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Week3] 김재원: 킹, 크로스워드, 단풍잎 이야기, 랜선 자르기 #13

Merged
merged 6 commits into from
Nov 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/3week/jaewon/과제.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

import kotlin.math.max

data class HOMEWORK (val d : Int, val w : Int)
Copy link
Member

@gongdongho12 gongdongho12 Oct 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

주로 상수에만 전부 대문자 사용하더라구요(물론 정하기 나름이지만...) 클래스는 카멜케이스 + 첫글자 대문자 사용해주시면 좋을것 같아요

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

카멜케이스는 첫글자가 소문자 아닌가요!?!

Copy link
Member

@gongdongho12 gongdongho12 Oct 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그래서 + 입니다 ㅠ 이걸 무슨케이스라고 하지... HomeWork 이런느낌

Copy link
Member Author

@ashwon12 ashwon12 Oct 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

파스칼이요!!~!!! 🤓

var answer = 0

fun main(){
val n = readln().toInt()
var maxDay = 0
val work : MutableList<HOMEWORK> = mutableListOf()
repeat(n){
val list = readln().split(" ").map { it.toInt() }
work.add(HOMEWORK(list[0],list[1]))
maxDay = max(maxDay,list[0])
}
ashwon12 marked this conversation as resolved.
Show resolved Hide resolved

for (i in maxDay downTo 1){
var temp = HOMEWORK(0,0)

work.filter { it.d >= i }.forEach {
if(temp.w < it.w){
temp = it
}
}
Comment on lines +20 to +24
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

필터된 항목중에서 w가 가장 큰 homework를 가져오는 연산인것 같더라구요
이런 느낌은 어떠신가요?

work.filter { it.d >= i }.maxByOrNull { it.w }?.let {
    work.remove(it)
}

answer += temp.w
work.remove(temp)
}
Comment on lines +17 to +27
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

answer 변수 전역변수로 빼지 않아도 되게 sumOf로 처리하면 어떠신가요?

val answer = (maxDay downTo 1).sumOf { i ->
    work.filter { it.d >= i }.maxByOrNull { it.w }?.let {
        work.remove(it)
        it.w
    }?: 0
}

Copy link
Member Author

@ashwon12 ashwon12 Oct 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반복문을 저런식으로도 적용시킬 수가 있나요??!? wow..


println(answer)
}
77 changes: 77 additions & 0 deletions src/3week/jaewon/단풍잎 이야기.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import kotlin.math.max
import kotlin.system.exitProcess

/**
* n개의 키가 비어있고 키마다 스킬을 셋팅해주어야 함.
* 퀘스트 1개마다 k개의 스킬을 사용할 수 있어야 깰 수 있음.
* 최대한 많이 퀘스트를 통과할 수 있도록 키에 스킬을 지정해 주어야 한다.
*
* 스킬의 갯수 최대 29개.
* 아이디어 !
* 1. 퀘스트마다 필요한 스킬들을 전부 모아서
* 2. 그 중에 n 개를 뽑는 경우의 수를 구하기.
* 3. 2에서 구한 경우의 수 중에 통과할 수 있는 퀘스트를 구하기
* 4. 만약!! 통과할 수 있는 경우의 수가 퀘스트 갯수와 같다면 종료.
*
* 반례
* 3 4 2
* 1 2
* 1 2
* 1 2
* 1 2
*
* 퀘스트마다 필요한 스킬들을 전부 모아서 조합할 때,
* 만약 필요한 스킬의 종류가 n 보다 숫자가 작다면 조합이 불가능... 2개 중에 3개를 뽑는 것은 불가능 하기 때문!!
* 이 부분에 대한 예외처리가 필요했음.
*/
ashwon12 marked this conversation as resolved.
Show resolved Hide resolved

var can = 0
lateinit var quest : Array<IntArray>
ashwon12 marked this conversation as resolved.
Show resolved Hide resolved

fun main(){
val (n,m,k) = readln().split(" ").map { it.toInt() }
quest = Array(m){IntArray(k)}

repeat(m){
val want = readln().split(" ").map { it.toInt() }.toIntArray()
quest[it] = want
}
ashwon12 marked this conversation as resolved.
Show resolved Hide resolved

val skills = quest.flatMap { it.asIterable() }.distinct() // 퀘스트마다 필요한 스킬들
if (skills.size <= n){
can = m
}else{
val canSkill = mutableListOf<List<Int>>()
combination(canSkill,skills, Array<Boolean>(skills.size){false},0,n)
canSkill.forEach {com ->
var count = 0
quest.forEach { it ->
// 지금 퀘스트를 꺨 수 있는 지 확인.
val temp = it.count { com.contains(it) }
if (temp == it.size){ // 두개 다 통과
count++
}
}
if (count == quest.size){
println(quest.size)
exitProcess(0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그냥 canSkill의 forEach를 return 해도 되지 않나요? return@forEach
그러면 can만 quest.size로 업데이트하고 출력하게 되니까요!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

음 바로 실행을 종료시키는게 좋다고 생각했는데 exitProcessimport 해야해서 이 방법을 추천해주시는건가요~?!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

혹시 그냥 return 은 종료가 안되신건가요?
사실 이부분은 취향차인데
exitProcess로 종료된다는게 특별히 Intelij에서 강조되는것도 없는데 종료되는 로직이자나요 그래서 저는 되도록 한 함수에서의 종료는 기본적으로 맨 아래로 두는게 나은것 같아요

}else{
can = max(can,count)
}
}
Comment on lines +44 to +61
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

정리하면 이런느낌이네요!

skills.combination(n).forEach { com ->
    val questCount = questBox.count { questList -> questList.count { q -> com.contains(q) } == questList.size }
    if (questCount == questBox.size) {
        can = questBox.size
        return@forEach
    } else {
        can = max(can, questCount)
    }
}

}
println(can)
}

fun <T> combination(answer: MutableList<List<T>>, el: List<T>, ck: Array<Boolean>, start: Int, target: Int) {
if(target == 0) {
answer.addAll( listOf(el.filterIndexed { index, t -> ck[index] }) )
} else {
for(i in start until el.size) {
ck[i] = true
combination(answer, el, ck, i + 1, target - 1)
ck[i] = false
}
}
}
Comment on lines +44 to +76
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코틀린은 함수형이다 보니까 combination도 깔끔하게 사용할 수 있더라구요!
(자매품) permutation도 가능합니다!

fun <T> List<T>.combination(num: Int): List<List<T>> {
    if (num == 1) return map { listOf(it) }
    return indices.flatMap {
        val current = get(it)
        subList(it + 1, size).combination(num - 1).map { combination ->
            LinkedList(combination).apply {
                addFirst(current)
            }
        }
    }
}

그러면 사용부에 mutableList로 만든 canSkill을 아래와 같이 정의할 수 있어요

val canSkill = skills.combination(n)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

헉 이부분 코드는 다시한번 보고 다음에 사용해야 할 때 사용해보아야겠어요.. !!


29 changes: 29 additions & 0 deletions src/3week/jaewon/랜선 자르기.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* 어떻게 풀어야 할지 감이 안잡힘...
* ㅇㅏ이디어 : 이분탐색
*
*/

fun main(){
val (k,n) = readln().split(" ").map { it.toInt() }
val size = IntArray(k)
repeat(k){ size[it] = readln().toInt()}

var answer : Long = 0
var high : Long = size.maxOf { it }+1.toLong()
Comment on lines +9 to +13
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size 만드는걸 아래같이 바꾸면 초기화 없이 가능할거구 아래에 보면
high값을 처리하는데 이부분을 위한 max값도 같이 만들면 좋을것 같아요

var max: Int = 0
val size = Array(k) {
    val v = readln().toInt()
    if (max < v) {
        max = v
    }
    v
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그리고 코딩하다 보면 각각의 타입에 대한 정의를 추론하기 힘든 경우가 많은데
코틀린은 타입을 필수로 명시하지 않아도 되니까 그런 부분이 더 심하더라구요
size 보다는 sizeArray 형식이 좋지 않을까요?

var row : Long = 1
while (row <= high){
val mid : Long = (high+row)/2
var temp : Long = 0
size.forEach {
temp += it/mid
}
if (temp >= n){
row = mid+1
answer = mid
}else{
high = mid-1
}
}
println(answer)
}
170 changes: 170 additions & 0 deletions src/3week/jaewon/마법사 상어와 복제.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/**
*
* 0. 현재 물고기 정보 저장.
* 1. 물고기가 이동할 수 있는 경우
* 모든 물고기는 한칸씩 이동
* 상어가 있는 칸 ( shark 로 확인 ) , 물고기의 냄새가 있는 칸 ( smell로 확인 ) , 격자의 범위는 x
* -> 안되면 45도씩 이동해서 갈 수 있는지 확인
*
*
* 2. 상어가 움직이는 경우
* 1,2,3,4 중에 3개를 뽑고 중복순열을 만들어서 오름차순으로 정렬하기
* 해당 값을 반복하면서
* 좌표를 이동
* 불가능하면 -> 이동x
* 물고기가 있다면 -> 물고기 제외 count 추가
* 물고기 제외 count max()
* max인 값의 좌표로 이동후 물고기 냄새 표시하기.
*
*
* 3. smell에서 time이 2인 얘들 삭제
* 4. 기존의 fishse 그대로 적용... 오마갓...
*
*
*/

data class FISH (val x : Int, val y : Int, val arrow : Int)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FISH => Fish로 선언하면 좋을것 같아요

data class Fish (var x : Int, var y : Int, val arrow : Int) {
    operator fun plus(pos: Pair<Int, Int>) {
        this.x += pos.first
        this.y += pos.second
    }
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 업데이트 하면 레퍼런스로 업데이트 되서 배열에 직접 인덱스 참고해서 반영하지 않아도 되니까요

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그리고 Fish 자체에 있으면 좋은 함수로 check, validate, setZero 등이 있으면 용이할 것 같아요

data class Fish(var x: Int, var y: Int, var arrow: Int) {
    operator fun plus(pos: Pair<Int, Int>) {
        this.x += pos.first
        this.y += pos.second
    }
    
    fun validate(first: Int, second: Int): Boolean = this.x == first && this.y == second
    
    fun setZero() {
        this.x = 0
        this.y = 0
        this.arrow = 0
    }
    
    fun check(): Boolean {
        val (posX, posY) = fishPos[arrow]!!
        val newX = x + posX
        val newY = y + posY
        return !((newX == sharkX && newY == sharkY) || (smell.any { smell -> smell.x == newX && smell.y == newY }) || newX > 4 || newY > 4)
    }
}

data class SMELL (val x : Int, val y : Int, var time : Int)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SMELL => Smell

자주 Pair 형태로 더하는 경우가 있는데 이부분도

data class Smell(var x: Int, var y: Int, var time: Int) {
    operator fun plus(pos: Pair<Int, Int>) {
        this.x += pos.first
        this.y += pos.second
    }
}

추가되면 좋을것 같아요


val fishPos = mapOf<Int, Pair<Int,Int>>(
0 to Pair(0,0),
1 to Pair(0,-1),
2 to Pair(-1,-1),
3 to Pair(-1,0),
4 to Pair(-1,1),
5 to Pair(0,1),
6 to Pair(1,1),
7 to Pair(1,0),
8 to Pair(1,-1)
)

val sharkPos = mapOf(
1 to Pair(-1,0),
3 to Pair(1,0),
2 to Pair(0,-1),
4 to Pair(0,1)
)
Comment on lines +29 to +46
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

번호로 만들었을때 0으로 시작하는 경우엔 그냥 리스트 자료구조를 사용하는게 낫지 않으신가요?


var sharkX = 0
var sharkY = 0
var fishes = mutableListOf<FISH>()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lateinit var fishes: MutableList<Fish>

val smell = mutableListOf<SMELL>()
val temp = mutableListOf<FISH>()
val moveSharkList = mutableListOf<String>()


fun main(){
val (m,s) = readln().split(" ").map { it.toInt() }
repeat(m){
val fi = readln().split(" ").map { it.toInt() }
fishes.add( FISH(fi[0],fi[1],fi[2]))
}
Comment on lines +58 to +61
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fishes = Array(m) {
    val (x, y, arrow) = readln().split(" ").map { it.toInt() }
    Fish(x, y, arrow)
}.toMutableList()

lateinit 선언후 직접 반영이 좋을것 같아요

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어떤 값이 들어갈지 확정적이라면 배열로 참조하는 것 보다는 명시해주면 좋을것 같아요


val shark = readln().split(" ").map { it.toInt() }
sharkX = shark[0]
sharkY = shark[1]
makeMoveShark(arrayOf(1,2,3,4), Array(3){0},0,3)
moveSharkList.sortDescending()

repeat(s){
smell.forEach{ smell -> smell.time ++}
temp.clear()
temp.addAll(fishes)

//물고기 이동
fishes.forEachIndexed { idx, fish ->
var (x,y,arrow) = fish
if (checkFish(x,y,arrow)){
x += fishPos[arrow]!!.first
y += fishPos[arrow]!!.second
fishes[idx] = FISH(x,y,arrow)
}else if(!checkFish(x,y,arrow)){
// 이동할 수 없는 경우
var i = 0
while (i < 8){
arrow = if( arrow == 1) 8 else { arrow-1 } // 45도 반시계로 돌리기
if(checkFish(x,y,arrow)){
x += fishPos[arrow]!!.first
y += fishPos[arrow]!!.second
Comment on lines +78 to +88
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fishPos[arrow]!! 를 사용했는데 x, y를 가져오기 위해 다시 사용하고 있네요
이부분 사실 가장 좋은 방법은 fish 자체에 operator에 추가하면 사실 first와 second로 뺄 필요도 없게 되지 않을까요?

fishes[idx] = (FISH(x,y,arrow))
break
}else {
i++
}
}
}
}
Comment on lines +75 to +96
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

물고기 이동부를 객체 내부 함수로 정리해보면 이런느낌이 되네요!

fishes.forEach { fish ->
    var (arrow) = fish
    if (fish.check()) {
        fish + fishPos[arrow]!!
    } else if (!fish.check()) {
        // 이동할 수 없는 경우
        var i = 0
        while (i < 8) {
            // 45도 반시계로 돌리기
            fish.arrow = if (arrow == 1) 8 else {
                arrow - 1
            }
            if (fish.check()) {
                fish + fishPos[fish.arrow]!!
                break
            } else {
                // rollback
                fish.arrow = arrow
                i++
            }
        }
    }
}


//상어의 우선순위 이동pos 찾기
var removeMax = 0
var removePos = "444"
moveSharkList.forEach sharkRepeat@{ pos ->
var count = 0
var tempMax = 0
var tempSharkX = sharkX
var tempSharkY = sharkY
val tempFishList = mutableListOf<FISH>()
tempFishList.clear()
tempFishList.addAll(fishes)
repeat(3){
tempSharkX += sharkPos[(pos[it]).digitToInt()]!!.first
tempSharkY += sharkPos[(pos[it]).digitToInt()]!!.second
if (tempSharkX <= 4 && tempSharkY <=4){
count++
tempFishList.forEachIndexed {idx , fish ->
if (tempSharkX == fish.x && tempSharkY == fish.y){
// 상어자리에 물고기가 있다면
tempFishList[idx] = FISH(0,0,0)
tempMax++
}
}
}
}

if (count == 3 && tempMax >= removeMax){
removeMax = tempMax
removePos = pos
if (removeMax == 3){ return@sharkRepeat }
}
}
Comment on lines +101 to +129
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상어의 우선순위 이동pos 찾기를 위에 선언한 객체 내부 함수를 이용한다면

moveSharkList.forEach sharkRepeat@{ pos ->
    var count = 0
    var tempMax = 0
    var tempSharkX = sharkX
    var tempSharkY = sharkY
    val tempFishList = mutableListOf<Fish>()
    tempFishList.clear()
    tempFishList.addAll(fishes)
    repeat(3) {
        val (first, second) = sharkPos[(pos[it]).digitToInt()]!!
        tempSharkX += first
        tempSharkY += second
        if (tempSharkX <= 4 && tempSharkY <= 4) {
            count++
            tempFishList.filter { it.validate(tempSharkX, tempSharkY) }.forEach { fish ->
                // 상어자리에 물고기가 있다면
                fish.setZero()
                tempMax++
            }
        }
    }

    if (count == 3 && tempMax >= removeMax) {
        removeMax = tempMax
        removePos = pos
        if (removeMax == 3) {
            return@sharkRepeat
        }
    }
}

이부분도 깔끔해지는 느낌!


removeFish(removePos) // 3번 이동( 물고기 제외 & 상어 좌표 이동 )
smell.filter { it.time == 2 }.forEach { smell.remove(it) } // 두번 전에 생긴 물고기 냄새 지우기
temp.forEach { fishes.add(it) }
Comment on lines +131 to +133
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Iterator의 함수중에 add나 remove를 반복해야 하는 경우 직접 반복해서 지우는 작업은 오래걸려서 addAll과 removeAll을 사용해보면 좋을것 같아요

smell.removeAll(smell.filter { it.time == 2 }) // 두번 전에 생긴 물고기 냄새 지우기
fishes.addAll(temp)

}

println(fishes.size)
}

fun checkFish(x : Int, y : Int, arrow : Int) : Boolean{
val newX = x + fishPos[arrow]!!.first
val newY = y + fishPos[arrow]!!.second
return !((newX == sharkX && newY == sharkY) || (smell.any{ smell -> smell.x == newX && smell.y == newY}) || newX >4 || newY >4)
}
Comment on lines +139 to +143
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fish라는 주체의 연산인데 외부에 나와있을 이유가 없겠죠?


fun makeMoveShark(arr : Array<Int>, output : Array<Int>, depth : Int, r : Int){
if(depth == r){
moveSharkList.add(output.joinToString(""))
println()
return
}
for (i in arr.indices){
output[depth] = arr[i]
makeMoveShark(arr,output,depth+1, r)
}
}

fun removeFish(moveShark : String){
moveShark.forEach {
sharkX += sharkPos[it.digitToInt()]!!.first
sharkY += sharkPos[it.digitToInt()]!!.second
Comment on lines +159 to +160
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이부분도 sharkPos를 두번 숫자로 참조하고 있네요!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moveShark.map { sharkPos[it.digitToInt()]!! }.forEach { (posX, posY) ->
    sharkX += posX
    sharkY += posY

이렇게 참조해서 사용하면 어떨까요?

fishes.forEachIndexed {idx, fish ->
if (sharkX == fish.x && sharkY == fish.y){
// 상어자리에 물고기가 있다면
fishes[idx] = FISH(0,0,0)
smell.add(SMELL(fish.x,fish.y,0))
}
}
Comment on lines +161 to +167
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위에서 객체 내부 함수로 이부분도 정의가 가능하겠죠?

fishes.forEach { fish ->
    if (fish.validate(sharkX, sharkY)) {
        // 상어자리에 물고기가 있다면
        fish.setZero()
        smell.add(Smell(fish.x, fish.y, 0))
    }
}

}
fishes = fishes.filterNot { it.x == 0 && it.y ==0 && it.arrow == 0 }.toMutableList()
}
28 changes: 28 additions & 0 deletions src/3week/jaewon/크로스워드.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* 가로 : split 를 사용해서 값을 추가해주기
* 세로 : 배열에 저장 후 for문을 사용하여 문자를 만들어서 값 추가해주시
* 리턴 값 : 정렬해서 첫번째 인덱스
*/

fun main(){
val (r,c) = readln().split(" ").map { it.toInt() }
val list = mutableListOf<List<String>>()
val answer = mutableListOf<String>()
repeat(r){
val input = readln()
answer.addAll(input.split("#").filterNot { it.isEmpty() || it.length<2})
val temp = input.chunked(1).map { it }
list.add(temp)
}
Comment on lines +9 to +16
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

list값 도중에 업데이트 하는 경우가 없는것 같더라구요!
그러면

val list = Array(r) {
    val input = readln()
    answer.addAll(input.split("#").filterNot { it.isEmpty() || it.length < 2 })
    input.chunked(1)
}

로 써도 아래에서 사용하는건 참조에 지장없을것 같아요!


var temp = ""
for (i in 0 until c) {
for( j in 0 until r){
temp += list[j][i]
}
answer.addAll(temp.split("#").filterNot { it.isEmpty() || it.length <2})
temp=""
}
Comment on lines +18 to +25
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

temp를 지속해서 초기화 해주는 것 보다는 스코프 빠져나갈 때 자동으로 gc 일어나게 하는게 효율적인데 temp를 지속적으로 더하고 업데이트 하고 있네요

val temp = (0 until r).map { j -> list[j][i] }.joinToString()

이러면 String append 에 효율적인 StringBuilder 사용해서 연산하고 for문 마다 gc 처리 일어나게끔 구성할 수 있을것 같아요


println(answer.filter { it.length >= 2 }.sorted()[0])
}
Loading