Lv.1 신규 아이디 추천

James_·2022년 1월 18일
0
post-thumbnail

문제- 신규 아이디 추천
오랜만에 알고리즘 문제를 풀어봤는데 지금까지 Python으로 많이 풀어왔지만 이번엔 코틀린으로 한 번 풀어봤다.
생각보다 쉽지 않았고 시간이 많이 걸렸다.

풀이

람다로 짜는걸 좋아해서 람다로 풀어보기로 했다.

1단계 new_id의 모든 대문자를 대응되는 소문자로 치환합니다.

it.toLowerCase().toString() // A -> a

첫 번쨰는 그렇게 어렵지 않다. map으로 1대1로 소문자로 바꿔준다.

2단계 newid에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(), 마침표(.)를 제외한 모든 문자를 제거합니다.

.filter{it.isLetterOrDigit() || it.toString() == "-" || it.toString() == "_" || it.toString() == "."}
// "...!@bat#*..y.abcdefghijklm" -> [,.,.,.,b,a,t,.,.,y,.,a,b,c,d,e,f,g,h,i,j,k,l,m]

문자와 숫자인지 확인하고 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)만 fiter해서 리스트로 받아온다. 첫 번째와 두 번쨰 순서상 결과는 똑같기 때문에 1단계에 앞서 진행해줬다.
map으로 1대1로 반환했기 때문에 다시 리스트로 만들고 스트링으로 만들어야했다. 그래서 내가 생각난건 flatMap으로 일단 시도해보기로 했다.

.flatMap{it.toList()} // 다시 리스트로 만들어준다. "a","b","c" -> ["a",b","c]
.let{it.joinToString("")} // 리스트 요소들을 합쳐준다. ["a","b","c"] ->"abc"

3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.

.let{it.replace("\\.{2,}".toRegex(),".")}
// ... -> .

이 경우에는 Regex를 사용하면 간단하게 할 수 있었다. 앱 개발 할때도 Regex도 알고있으면 코드 수가 많이 줄 것 같다.

4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.

.removePrefix(".")
.removeSuffix(".")

접두사,접미사에 특정 문자가 있으면 제거하는 아주 좋은 함수가 있었다!

5단계 new_id가 빈 문자열이라면, new_id에 "a"를 대입합니다.

.let{ if(it.isEmpty())"a"else it}

코드 그대로 빈 문자("")인지 확인하고 비었다면 a를 반환해주고 빈 문자가 아니라면 그대로 반환해준다.

6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다.
만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.

.let{
     if(it.length >= 16){
     	it.toString().removeRange(15,it.length).toString().removePrefix(".").removeSuffix(".")
}else it}

16자 이상인 체크하고 removeRange로 범위를 설정해서 index i5부터 끝가지 버려준다.
문제 그대로 .이 있는지 다시 확인해서 앞,뒤 지워준다.

7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.

.let{
	if(it.length <= 2){
		when(it.length){
			1 -> "${it.get(0)}${it.last()}${it.last()}"
			else -> "${it}${it.last()}"
		} 
	}else it 
   }

여기서 어떻게 할까 많이 고민했지만 경우의 수가 2개(문자열이 1개 or 2개)라서 하드코딩하기로 했다.

전체 코드

class Solution {
    fun solution(new_id: String): String  = new_id
            .filter{it.isLetterOrDigit() || it.toString() == "-" || it.toString() == "_" || it.toString() == "."}
            .map{it.toLowerCase().toString()}
            .flatMap{it.toList()}
            .let{it.joinToString("")}
            .let{it.replace("\\.{2,}".toRegex(),".")}
            .removePrefix(".")
            .removeSuffix(".")
            .let{
                if(it.isEmpty()){
                    "a"
                }else it
            }
            .let{
                if(it.length >= 16){
                    it.toString().removeRange(15,it.length).toString().removePrefix(".").removeSuffix(".")
                }else it
            }
            .let{
                if(it.length <= 2){
                    when(it.length){
                    1 -> "${it.get(0)}${it.last()}${it.last()}"
                    else -> "${it}${it.last()}"
                } 
                }else it 
    }
}

1단계가 예전보다 많이 어려워졌다.. 카카오 문제라서 그런가
코틀린으로 푸니까 아주 신선했다.

profile
Android 개발자

0개의 댓글