https://school.programmers.co.kr/learn/courses/30/lessons/67256
문제
스마트폰 전화 키패드의 각 칸에 다음과 같이 숫자들이 적혀 있습니다.
이 전화 키패드에서 왼손과 오른손의 엄지손가락만을 이용해서 숫자만을 입력하려고 합니다.
맨 처음 왼손 엄지손가락은 * 키패드에 오른손 엄지손가락은 # 키패드 위치에서 시작하며, 엄지손가락을 사용하는 규칙은 다음과 같습니다.
엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
4-1. 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.
순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때, 각 번호를 누른 엄지손가락이 왼손인 지 오른손인 지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해 주세요.
[제한사항]
numbers 배열의 크기는 1 이상 1,000 이하입니다.
numbers 배열 원소의 값은 0 이상 9 이하인 정수입니다.
hand는 "left" 또는 "right" 입니다.
"left"는 왼손잡이, "right"는 오른손잡이를 의미합니다.
왼손 엄지손가락을 사용한 경우는 L, 오른손 엄지손가락을 사용한 경우는 R을 순서대로 이어 붙여 문자열 형태로 return 해주세요.
풀이 1
import kotlin.math.abs
class Solution {
fun solution(numbers: IntArray, hand: String): String {
var l_x = 0
var l_y = 3
var r_x = 2
var r_y = 3
val state = hand == "right"
var result: String = ""
numbers.forEach {
if (it == 1 || it == 4 || it == 7) {
l_x = 0
l_y = it / 3
result += 'L'
} else if (it == 3 || it == 6 || it == 9) {
r_x = 2
r_y = it / 3 - 1
result += 'R'
} else if (it == 2 || it == 5 || it == 8 || it == 0) {
var y: Int
if (it == 0) {
y = 3
} else {
y = it / 3
}
var l_distance = abs(l_x - 1) + abs(l_y - y)
println("l_distance : $l_distance")
var r_distance = abs(r_x - 1) + abs(r_y - y)
println("r_distance : $r_distance")
if (l_distance > r_distance){
r_x = 1
r_y = y
result += 'R'
} else if (l_distance < r_distance){
l_x = 1
l_y = y
result += 'L'
}else{
if (state){
r_x = 1
r_y = y
result += 'R'
}else{
l_x = 1
l_y = y
result += 'L'
}
}
}
print("L $l_x $l_y ")
println("R $r_x $r_y")
}
return result
}
}
- 2022년 10월쯤에 풀었던 문제입니다. 해당문제를 왼손과 오른손의 좌표를 설정하여 조건문으로 해당 번호를 누를 때마다 좌표가 바뀌게 설정하였습니다. 지금 보면 이 풀이는 문자열이나 가변성 나누기등 고칠 점이 너무 많아 보입니다.
결과 1
풀이 2
import kotlin.math.abs
class Solution {
fun solution(numbers: IntArray, hand: String): String {
var lX = 0
var lY = 3
var rX = 2
var rY = 3
val state = hand == "right"
val result = StringBuilder()
val arrY: IntArray = intArrayOf(3, 0, 0, 0, 1, 1, 1, 2, 2, 2)
numbers.forEach {
if (it == 1 || it == 4 || it == 7) {
lX = 0
lY = arrY[it]
result.append('L')
} else if (it == 3 || it == 6 || it == 9) {
rX = 2
rY = arrY[it]
result.append('R')
} else if (it == 2 || it == 5 || it == 8 || it == 0) {
val y: Int = arrY[it]
val lDistance = abs(lX - 1) + abs(lY - y)
val rDistance = abs(rX - 1) + abs(rY - y)
if (lDistance > rDistance) {
rX = 1
rY = y
result.append('R')
} else if (lDistance < rDistance) {
lX = 1
lY = y
result.append('L')
} else {
if (state) {
rX = 1
rY = y
result.append('R')
} else {
lX = 1
lY = y
result.append('L')
}
}
}
}
return result.toString()
}
}
- 우선 처음으로 바꾼 것은 나누기입니다. 나누는 연산 같은 경우 0~9까지 계속 수행합니다. 이러한 부분은 중복되기 때문에 나누기 결과에 맞는 값을 배열에 넣어 주었습니다.
- 두 번째로 바꾼 부분은 문자열 생성 부분이었습니다. 한두 개 정도의 문자열은 더해도 큰 소모가 없지만 계속해서 값들을 추가할 때는 큰 소모가 생깁니다. 그래서 해당 부분을 String이 아닌 StringBuilder를 이용하여 이러한 소모적인 부분을 해결하였습니다.
- 세 번째로 바꾼 부분은 가변성과 변수의 이름입니다. 이전에는 가변적인 객체를 많이 집어넣어 컴파일러에서 해결할 때 약간의 시간 소모가 있었습니다. 그런데 이러한 소모가 있음에도 한 번도 바꾸지 않는데 가변객체로 설정된 변수들이 많았습니다. 해당 부분들은 상수로 바꾸고 변수명 같은 경우 가독성 좋게 카멜로 바꾸었습니다.
결과 2
'코틀린 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] - 소수 만들기 (Kotlin) (0) | 2023.08.08 |
---|---|
[프로그래머스] - 성격 유형 검사하기 (Kotlin) (0) | 2023.08.08 |
[프로그래머스] - 삼총사 (Kotlin) (0) | 2023.08.07 |
[프로그래머스] - 과일 장수 (Kotlin) (0) | 2023.08.07 |
[프로그래머스] - 푸드 파이트 대회 (Kotlin) (0) | 2023.08.07 |