문제

https://programmers.co.kr/learn/courses/30/lessons/42841

직접 플레이 해보기


코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

private static final int BEGIN_INDEX = 123;
private static final int END_INDEX = 987;

public int solution(int[][] baseball) {
List<String> allNumber = getAllNumber();

int answer = 0;
for (int i = 0; i < allNumber.size(); i++) {
if (isAnswer(baseball, allNumber.get(i).toCharArray())) {
++answer;
}
}

return answer;
}

private List<String> getAllNumber() {
List<String> list = new ArrayList<String>();
for (int i = BEGIN_INDEX; i <= END_INDEX; i++) {
char[] tochar = String.valueOf(i).toCharArray();

if (tochar[0] == tochar[1] || tochar[0] == tochar[2] || tochar[1] == tochar[2]) {
continue;
}

if (tochar[0] == '0' || tochar[1] == '0' || tochar[2] == '0') {
continue;
}

list.add(new String(tochar));
}

return list;
}

private boolean isAnswer(int[][] baseball, char[] number) {
boolean isAnswer = true;

for (int i = 0; i < baseball.length; i++) {
char[] requestBall = String.valueOf(baseball[i][0]).toCharArray();

int[] strikeAndBall = getStrikeAndBall(requestBall, number);

if (baseball[i][1] != strikeAndBall[0] || baseball[i][2] != strikeAndBall[1]) {
isAnswer = false;
break;
}
}

return isAnswer;
}

private int[] getStrikeAndBall(char[] requestBall, char[] number) {
int strike = 0;
int ball = 0;

for (int i = 0; i < 3; i++) {
if (number[i] == requestBall[i]) {
++strike;
}

if (isBall(requestBall, number[i])) {
++ball;
}
}

ball -= strike;

return new int[] {strike, ball};
}

private boolean isBall(char[] requestBall, char number) {
boolean isBall = false;
for (int i = 0; i < 3; i++) {
if (number == requestBall[i]) {
isBall = true;
break;
}
}

return isBall;
}

흐름

  1. 숫자 야구에서 나올 수 있는 모든 숫자를 구함(123~987)
  2. 구할 때 같은 숫자가 중복 될 수 없고 0이 들어갈 수 없으므로 확인해서 continue
  3. 구한 숫자들의 갯수만큼 돌면서 가능한 숫자인지 확인하는데
  4. 우선 나올 수 있는 모든 수 중 하나씩 돌면서 그 수와 배열로 받은 상대 수를 비교
  5. 받은 수와 뽑은 수를 한 자리씩 비교하면서 자리도 같고 숫자도 같으면 스트라이크
  6. 자리는 틀리지만 뽑은 수가 받은 수 안에 포함되어 있으면 볼로 처리
  7. 스트라이크이면서 볼인 경우는 있을 수 없기 때문에 볼에서 스트라이크의 갯수를 뻄
  8. 구한 스트라이크와 볼의 개수를 받은 수의 스트라이크와 볼 수와 비교해서 둘 중 하나도 같지 않으면 false를 저장하고 반복문을 빠져 나오고
  9. 조건에 맞다면 정답의 갯수를 증가 시킴
  10. 반복문이 끝나면 정답 갯수 return

결과

번호 속도
테스트 1 통과 (3.49ms, 52.4MB)
테스트 2 통과 (4.55ms, 50.7MB)
테스트 3 통과 (3.33ms, 52.6MB)
테스트 4 통과 (3.48ms, 52MB)
테스트 5 통과 (4.26ms, 50.4MB)
테스트 6 통과 (4.69ms, 52.5MB)
테스트 7 통과 (3.68ms, 50.8MB)
테스트 8 통과 (4.35ms, 52.3MB)
테스트 9 통과 (3.60ms, 52.7MB)
테스트 10 통과 (3.33ms, 50.3MB)

테스트 케이스

1
2
assertEquals(2, test.solution(new int[][] {{123, 1, 1}, {356, 1, 0}, {327, 2, 0}, {489, 0, 1}}));
assertEquals(2, test.solution(new int[][] {{659, 0, 1}, {264, 1, 1}, {126, 1, 2}}));

참고 사이트