x
, y
, n
3개의 숫자가 입력될 때, x
와 n
와 제한된 연산을 조합하여 최소한의 연산으로 y
를 만들고, 그때 연산 횟수를 return하는 문제이다.(y
를 만들 수 없다면 -1을 출력한다)
이때 사용할 수 있는 연산의 종류는 다음과 같다.
x
에 n
을 더한다.x
에 2를 곱한다.x
에 3을 곱한다.Test Case
case 1
x=10, y=40, n=5, result=2
-> 10 x 2 x 2
case 2
x=10, y=40, n=30, result=1
-> 10 + 30
case 3
x=2, y=5, n=4, result=-1
-> 불가능
case 4
x=10, y=432, n=13, result=5
-> (10 + 13 + 13) x 2 x 3 x 3
case 5
x=8, y=93, n=15, result=3
-> (8 x 2 + 15) x 3
방정식처럼 풀 수 있을까 하며 3시간정도 고민하다가, 트리구조를 들여다보니 아이디어가 하나 떠올랐다.
y
이면 result 값을 리턴한다.y
보다 크면 저장하지 않는다.Solution
public int mySolution(int x, int y, int n) {
int result = 1;
int currentNode = x;
Set<Integer> nodeSet = new HashSet<>();
// 처음에 x 가 y랑 같으면 0 리턴
if (x == y) {
return 0;
}
// 처음 nodeSet 만들기
// 연산 1
currentNode = x + n;
if (currentNode < y) {
nodeSet.add(currentNode);
} else if (currentNode == y) {
return 1;
}
// 연산 2
currentNode = x * 3;
if (currentNode < y) {
nodeSet.add(currentNode);
} else if (currentNode == y) {
return 1;
}
// 연산 3
currentNode = x * 2;
if (currentNode < y) {
nodeSet.add(currentNode);
} else if (currentNode == y) {
return 1;
}
// nodeSet에서 node확장
mainLoop:
while (true) {
result += 1;
Set<Integer> newNodeSet = new HashSet<>();
nodeSetLoop:
for (int parentNode : nodeSet) {
// 연산 1
currentNode = parentNode + n;
if (currentNode < y) {
newNodeSet.add(currentNode);
} else if (currentNode == y) {
break mainLoop;
}
// 연산 2
currentNode = parentNode * 3;
if (currentNode < y) {
newNodeSet.add(currentNode);
} else if (currentNode == y) {
break mainLoop;
}
// 연산 3
currentNode = parentNode * 2;
if (currentNode < y) {
newNodeSet.add(currentNode);
} else if (currentNode == y) {
break mainLoop;
}
}
// 새로 생긴 노드가 없다면 -1을 리턴
if (newNodeSet.size() == 0) {
return -1;
}
// nodeSet 최신화
nodeSet = newNodeSet;
}
return result;
}
Test 결과
프로그래머스도 통과!!
다른 사람의 풀이를 보다가
int a = 1000000
를 int a = 1_000_000
이렇게 표현하는 것을 보고 정말 깔끔해보인다고 생각했다.
다음에 긴 숫자를 표현할 일이 있으면 이렇게 해보자.