문제 출처
https://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 해주세요.
풀이
class Solution {
enum class HandType(val v:String){
L("left"),
R("right");
}
fun solution(numbers: IntArray, hand: String): String {
var answer = ""
val areaL = listOf(1,4,7,10)
val areaR = listOf(3,6,9,11)
val areaC = listOf(2,5,8,0)
var lastL = areaL.last()
var lastR = areaR.last()
fun click(isLeft:Boolean, i:Int){
if(isLeft){
answer += HandType.L.name
lastL = i
}else{
answer += HandType.R.name
lastR = i
}
}
fun isSide(list:List<Int>, value:Int):Boolean{
return list.indexOf(value) != -1
}
fun getStep(list:List<Int>, value:Int, num:Int): Int{
val c = areaC.indexOf(num)
val v =
if(isSide(list, value))
Math.abs(c-list.indexOf(value))+1
else
Math.abs(c-areaC.indexOf(value))
return v
}
for(i in numbers){
if(i==1||i==4||i==7) click(true, i)
else if(i==3||i==6||i==9) click(false, i)
else{
val stepL = getStep(areaL, lastL, i)
val stepR = getStep(areaR, lastR, i)
if(stepL == stepR){
click((hand == HandType.L.v), i)
}else if(stepL > stepR){
click(false, i)
}else{
click(true, i)
}
}
}
return answer
}
}
풀이 요약
- 키패드를 누르는 조건
- 키패드의 왼쪽줄은 왼손
- 오른쪽 줄은 오른손
- 가운데 줄은 가까운 손
- 거리가 같을 경우 주로 사용하는 손
- 상하좌우만 움직일 수 있기 때문에 각 줄별로 리스트로 만든다
- 마지막 왼손, 오른손의 위치를 기억한다
- 마지막 손의 위치와 누를 수의 거리를 비교하여 답을 결정한다
- 눌러야할 숫자가 가운데 줄에 해당할 경우
- 마지막 손의 위치를 각 줄별로 생성한 리스트에서 찾는다
- 양쪽 사이드 줄에 없으면 가운데 줄에서 찾는다
- 양쪽 사이드 줄에 있다면 눌러야할 키패드까지 이동하기 위해 좌 또는 우로 움직여야하기 때문에 1을 더한다
- 마지막 손의 위치를 각 줄별로 생성한 리스트에서 찾는다
학습내용
- 내 풀이 방식은 줄별로 관리하여 몇번째에 있는가로 거리를 계산했다
- 다른 사람 풀이를 보니 키패드에 좌표를 부여하여 하여 거리를 계산하는 방식도 있었다
반응형