2020. 7. 3. 15:38ㆍAlgorism
스마트폰 전화 키패드의 각 칸에 다음과 같이 숫자들이 적혀 있습니다.
이 전화 키패드에서 왼손과 오른손의 엄지손가락만을 이용해서 숫자만을 입력하려고 합니다.
맨 처음 왼손 엄지손가락은 * 키패드에 오른손 엄지손가락은 # 키패드 위치에서 시작하며, 엄지손가락을 사용하는 규칙은 다음과 같습니다.
- 엄지손가락은 상하좌우 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 해주세요.
문제가 점점 길어지네요....이번엔 열심히 읽어야겠어요..
휴 길었네요.. 생략되어있는 입출력 예도 상세하게 나와있네요...
이번문제는 2차원 배열을 이용하거나 번호판을 좌표화 해서 풀면 생각보다 쉽게!? 풀리는 방식이에요.
2차원 배열을 이용하면 가독성이 좋지 않을거 같고 연산식이 많이 필요할것 같아
Coords라는 좌표를 저장하는 구조체를 만들어서 풀어 봤어요.
왼쪽 키패드는 모두 왼손만 사용하고, 오른쪽 키패드는 오른손만 사용한다.
그러면 가운데 키패드 배열을 누르는 손가락만 판단하면 되는 내용이였어요.
먼저 키패드를 좌표화한 mapArray를 선언한뒤에
마지막 왼쪽손, 오른쪽 손위치를 저장할 변수를 선언하고
행(x), 열(y)에 좌표값에 해당하는 연산을 하면 총 이동 해야할 횟수가 나옵니다.
그래서 아래처럼 func으로 분리한뒤 진행하면 생각보다 쉽게!? 풀 수 있습니다.
import Foundation
struct Coords {
var x: Int
var y: Int
init(_ x: Int, _ y: Int) {
self.x = x
self.y = y
}
}
func solution(_ numbers:[Int], _ hand:String) -> String {
var returnMoveString = ""
let leftArray = [1,4,7]
let rightArry = [3,6,9]
// 휴대폰 번호판 좌표 배열
let mapArray = [
1:Coords(0, 0), 2:Coords(0, 1), 3:Coords(0, 2),
4:Coords(1, 0), 5:Coords(1, 1), 6:Coords(1, 2),
7:Coords(2, 0), 8:Coords(2, 1), 9:Coords(2, 2),
-1:Coords(3, 0), 0:Coords(3, 1),-2:Coords(3, 2)
]
var leftCurrent = Coords(3, 0)
var rightCurrent = Coords(3, 2)
numbers.forEach {
let moveLocation = mapArray[$0]!
if leftArray.contains($0) { // 왼쪽 번호 열 왼손
returnMoveString += "L"
leftCurrent = moveLocation
} else if rightArry.contains($0) { // 오른쪽 번호 열 오른손
returnMoveString += "R"
rightCurrent = moveLocation
} else { // 가운데 번호 열
let leftMovingCount = countingCalculation(leftCurrent, move: moveLocation)
let rightMovingCount = countingCalculation(rightCurrent, move: moveLocation)
if isLeftMoving(leftMovingCount, rightMovingCount, hand) {
returnMoveString += "L"
leftCurrent = moveLocation
} else {
returnMoveString += "R"
rightCurrent = moveLocation
}
}
}
return returnMoveString
}
// 움직일 횟수 계산
func countingCalculation(_ current: Coords, move: Coords) -> Int {
let x = current.x - move.x
let y = current.y - move.y
return (x < 0 ? -x : x) + (y < 0 ? -y : y)
}
// 왼쪽으로 움직 여야 하는지 여부 return -> true: left, false: right
func isLeftMoving(_ leftCount: Int, _ rightCount: Int, _ hand: String) -> Bool {
if leftCount < rightCount {
return true
} else if leftCount > rightCount {
return false
} else {
if hand == "right" {
return false
} else {
return true
}
}
}
print(solution([1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5], "right"))
위에는 로그를 지웠지만 문제 풀때는 로그를 추가해서 연산이 원하는대로 진행되는지 확인 하는 방법도 있습니다.
movingNumber = 1
movingNumber = 3
movingNumber = 4
movingNumber = 5
moveLocation = Coords(x: 1, y: 1), leftCurrent = Coords(x: 1, y: 0), rightCurrent = Coords(x: 0, y: 2)
movingNumber = 5, leftMovingCount = 1, rightMovingCount = 2
movingNumber = 8
moveLocation = Coords(x: 2, y: 1), leftCurrent = Coords(x: 1, y: 1), rightCurrent = Coords(x: 0, y: 2)
movingNumber = 8, leftMovingCount = 1, rightMovingCount = 3
movingNumber = 2
moveLocation = Coords(x: 0, y: 1), leftCurrent = Coords(x: 2, y: 1), rightCurrent = Coords(x: 0, y: 2)
movingNumber = 2, leftMovingCount = 2, rightMovingCount = 1
movingNumber = 1
movingNumber = 4
movingNumber = 5
moveLocation = Coords(x: 1, y: 1), leftCurrent = Coords(x: 1, y: 0), rightCurrent = Coords(x: 0, y: 1)
movingNumber = 5, leftMovingCount = 1, rightMovingCount = 1
movingNumber = 9
movingNumber = 5
moveLocation = Coords(x: 1, y: 1), leftCurrent = Coords(x: 1, y: 0), rightCurrent = Coords(x: 2, y: 2)
movingNumber = 5, leftMovingCount = 1, rightMovingCount = 2
result = LRLLLRLLRRL
'Algorism' 카테고리의 다른 글
알고리즘 - 프로그래머스 행렬의 덧셈 (Swift) (0) | 2020.07.06 |
---|---|
알고리즘 - 프로그래머스 콜라츠 추측 (Swift) (0) | 2020.07.03 |
알고리즘 - 프로그래머스 제일 작은 수 제거하기 (Swift) (0) | 2020.07.03 |
알고리즘 - 프로그래머스 정수 내림차순으로 배치하기 (Swift) (0) | 2020.07.02 |
알고리즘 - 프로그래머스 자릿수 더하기 (Swift) (0) | 2020.07.02 |