실무할 때는 제대로 다루지도 못하던 비동기를 내 손으로 다루게 되다니!
다행인 점은 chatGPT의 도움과 최신화 된 레퍼런스들 덕분에 마침내 이해에 성공해서 발표 자체는 수월하게 끝난 것 같다. 물론 개념까지만 이해한 것이기 때문에 여전히 코드로 작성하라고 하면 엉망이긴 할 것 같다.
그리고 TIL의 작성 방식도 좀 생각을 해봤는데 본 캠프에 가면 지금처럼 짤짤이 공부가 아닌 프로젝트 단위로 아득바득 뭔가 해결할 것이기 때문에 본 캠프부터 해결을 중점으로 구성을 바꾸게 될 것 같다.
문자열 s의 길이가 4 혹은 6이고, 숫자로만 구성돼있는지 확인해주는 함수, solution을 완성하세요. 예를 들어 s가 "a234"이면 False를 리턴하고 "1234"라면 True를 리턴하면 됩니다.
fun solution(s: String): Boolean = s.matches("\\d{4}|\\d{6}".toRegex())
조건문을 내세우지 않고 정규표현식으로 표현을 해봤다. 어차피 앞으로도 다룰 일 많아질테니 마침 문제 이름도 문자열 다루기 기본
이고 복잡한 길로 돌아가려고 고른 방법이긴 하다.
\\d{4}|\\d{6}
or를 담당하는 | 와 함께 \d
가 {4}
번 반복하는지 {6}
번 반복하는지 체크하는 정규표현식이고 제출은 큰 문제없이 성공했다.
복잡한 정규표현식은 읽기만 해도 눈 앞이 어지럽지만 기본적인 사용법 정도는 알고 있었는데 정리할 내용이 부족하니 이 문제에 맞춰서 최대한 더 쥐어짜내봤다.
예로 아래 패턴은 같은 결과를 캡쳐해낸다.
s.matches("[0-9]{4}|[0-9]{6}".toRegex())
s.matches("\\d{4}(?:\\d{2})?".toRegex())
[0-9]
는 \d
와 동일한 범위를 지니기에 같은 결과를 가진다.
?:
는 비캡쳐 그룹으로 패턴으로는 사용할 수 있지만 캡쳐하진 않기 때문에 결과적으로 4자 또는 6자인 숫자만 찾아낸다.
예시로 s가 123456일 경우 패턴을 매칭하면 123456 과 1234만 캡쳐되며 비캡쳐 그룹에 포함된 56은 캡쳐되지 않는다.
?
는 그렇다 쳐도 ?:
패턴을 이해하느라 시간이 꽤 걸렸는데 예제를 수없이 돌려보고 chatGPT와 함께 머리를 쥐어짜내서 해석에 성공했다. 아무래도 핵심은 캡쳐 아니겠는가?
물론 완벽한 정규표현식은 아니겠지만 표현할 줄 아는가에 대해서는 계속 공부를 해야겠다.
\D
는 아라비안 숫자가 아닌 나머지를 가리킨다. 대문자로 바뀌면 패턴이 정반대가 된다. 예로\s
는 space 공백을 찾는 패턴인데\S
는 space 공백을 제외한 나머지를 찾는다.
그리고 내가 풀어낸 방식은 사실 문제가 간단한데 괜히 정규표현식을 들먹여서 바람직한 정답은 아니라고 생각한다.
역시나 다른 분들의 풀이는 훨씬 정직하고 간결했다.
(s.length == 4 || s.length == 6) && s.toIntOrNull() != null
s.all { it.isDigit() } && ((s.length == 4) || (s.length == 6))
다른 분들의 풀이인데 골치 안아프게 이렇게 isDigit
이나 intOrNull
을 끌어다 쓰면 편한 건 아는데 이번엔 굳이? 아득바득 정규표현식 써보겠다고 난리친 결과물이긴 하다.
그리고 정규표현식을 사용하면 컴파일, 실행 과정에서 오버헤드가 추가로 발생할 수 있어 최적화된 함수가 존재한다면 이러한 함수를 사용하는 것이 성능 향상에 도움이 될 것이다.