2021. 12. 13. 19:15ㆍComputer Sciences/Problem Solve
https://programmers.co.kr/learn/courses/30/lessons/67256
1단계 문제라서 쉽게 해결될 줄 알았는데 생각보다 애먹었다. 처음에는 키패드 숫자로 계산해서 거리를 찾으려고 했으나 나 실패하였고, 배열로 하려고 잠깐 생각했었지만 복잡해질 것 같았다. 그래서 Position이라는 객체를 만들어서 거리 계산을 해결했다. 로직은 그렇게 복잡한 것이 아니니 읽어내려가면 이해가 될 것이다.
해결 과정
먼저 좌측과 우측 키패드는 손이 정해져 있으므로 먼저 판별한다. 왼쪽은 1, 4, 7인데 이는 mod 3의 결과가 1이다. 오른쪽은 3, 6, 9이고 mod 3의 결과는 0이다. 이때 0이 입력으로 들어온 경우도 mod 3이 0이 되므로 이 경우를 고려해야 한다.
이제 가운데 버튼만 고려하면 된다. 가운데 버튼의 경우 손이 더 가까운 쪽, 거리가 같다면 자주 쓰는 손으로 누르게 된다. 따라서 먼저 거리를 계산한다. 거리는 절댓값(줄의 차이) + 절댓값(칸의 차이)으로 계산한다. 절댓값 처리를 하는 이유는 현재 1, 2, 3 이 있는 줄에서 손이 있는데 누를 버튼의 줄이 7, 8, 9가 있는 줄에 있다면 0 - 2가 되므로 음수가 나오기 때문이다. 이제 칸을 -1, 0, 1로 한 이유가 나온다. 거리를 계산하는 이유는 가운데 숫자를 누르기 위해서다. 현재 손이 왼쪽에 있다면 가운데로부터 1만큼 떨어져 있고 가운데에 있다면 0만큼 떨어져 있으며 오른쪽에 있는 경우 1만큼 떨어져 있다. 다시 말하면, 가운데를 0으로 기준을 두고 양 옆은 칸을 구분하게 위해 -1, 1로 두었다. 거리를 계산할 때는 절댓값을 취해주면 딱 떨어지게 계산할 수 있게 된다. 거리가 같다면 파라미터로 입력받은 hand 값을 사용하면 된다.
코드
class Solution {
private StringBuilder sb = new StringBuilder();
/**
* 키패드 위치
* | -1 0 1
* --+-----------
* 0 | 1 2 3
* 1 | 4 5 6
* 2 | 7 8 9
* 3 | * 0 #
*/
private Position currentLeftPosition = new Position(3, -1);
private Position currentRightPosition = new Position(3, 1);
public String solution(int[] numbers, String hand) {
for (int number : numbers) {
if (isLeft(number)) {
sb.append("L");
setCurrentLeftPosition(number);
continue;
}
if (isRight(number)) {
sb.append("R");
setCurrentRightPosition(number);
continue;
}
int calcedLeftDistance = calcDistance("left", number);
int calcedRightDistance = calcDistance("right", number);
if (calcedLeftDistance < calcedRightDistance) {
sb.append("L");
setCurrentLeftPosition(number);
continue;
} else if (calcedLeftDistance > calcedRightDistance) {
sb.append("R");
setCurrentRightPosition(number);
continue;
} else {
if (hand.equals("left")) {
sb.append("L");
setCurrentLeftPosition(number);
continue;
}
if (hand.equals("right")) {
sb.append("R");
setCurrentRightPosition(number);
continue;
}
}
}
return sb.toString();
}
private boolean isLeft(int number) {
return number % 3 == 1;
}
private boolean isRight(int number) {
return number % 3 == 0 && number != 0;
}
private void setCurrentLeftPosition(int number) {
if (number == 1) {
currentLeftPosition.setPosition(0, -1);
} else if (number == 4) {
currentLeftPosition.setPosition(1, -1);
} else if (number == 7) {
currentLeftPosition.setPosition(2, -1);
} else
setCurrentMiddlePosition(currentLeftPosition, number);
}
private void setCurrentRightPosition(int number) {
if (number == 3) {
currentRightPosition.setPosition(0, 1);
} else if (number == 6) {
currentRightPosition.setPosition(1, 1);
} else if (number == 9) {
currentRightPosition.setPosition(2, 1);
} else
setCurrentMiddlePosition(currentRightPosition, number);
}
private void setCurrentMiddlePosition(Position position, int number) {
if (number == 2) {
position.setPosition(0, 0);
} else if (number == 5) {
position.setPosition(1, 0);
} else if (number == 8) {
position.setPosition(2, 0);
} else if (number == 0) {
position.setPosition(3, 0);
}
}
private int calcDistance(String direction, int number) {
Position currentPosition = null;
if (direction.equals("left")) {
currentPosition = currentLeftPosition;
} else if (direction.equals("right")) {
currentPosition = currentRightPosition;
}
if (number == 2) {
return Math.abs(currentPosition.getX() - 0) + Math.abs(currentPosition.getY());
} else if (number == 5) {
return Math.abs(currentPosition.getX() - 1) + Math.abs(currentPosition.getY());
} else if (number == 8) {
return Math.abs(currentPosition.getX() - 2) + Math.abs(currentPosition.getY());
} else if (number == 0) {
return Math.abs(currentPosition.getX() - 3) + Math.abs(currentPosition.getY());
} else {
return 0;
}
}
static class Position {
private int x;
private int y;
public Position(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setPosition(int x, int y) {
this.x = x;
this.y = y;
}
}
}
'Computer Sciences > Problem Solve' 카테고리의 다른 글
[Programmers] 오픈채팅방 - Java (0) | 2021.12.23 |
---|---|
[Programmers] 크레인 인형뽑기 게임 - Java (0) | 2021.12.14 |
[Programmers] 숫자 문자열과 영단어 - Java (0) | 2021.12.12 |
[Programmers] 신규 아이디 추천 - Java (0) | 2021.12.11 |
[Programmers] 로또의 최고 순위와 최저 순위 - Java (0) | 2021.12.10 |