3 minute read



입출력 예시

Input-1
v = [[1, 4], [3, 4], [3, 10]]
Output-1
[1, 10]

Input-2
v = [[1, 1], [2, 2], [1, 2]]
Output-2
[2, 1]


문제 풀이


이 문제는 직사각형에서 3개의 좌표를 가지고 나머지 한 좌표를 구해야 한다.
조건문 및 비트연산자를 활용하여 풀어봤다.

1. 조건문 활용

조건문을 활용한 풀이는 간단한데, 먼저 x좌표와 y좌표를 구분된 조건으로 구해보자.
2차원 배열이고, 세 점은 이미 주어졌기에 3개의 좌표를 모두 돌면서 중복되지 않은 x좌표와 y좌표를 찾으면 된다.

코드로 작성해보자.

1
2
3
4
5
6
7
8
// x좌표 
if(v[0][0] == v[1][0]) x=v[2][0];
else if(v[0][0] == v[2][0]) x=v[1][0];
else if(v[1][0] == v[2][0]) x=v[0][0];
// y좌표
if(v[0][1] == v[1][1]) y=v[2][1];
else if(v[0][1] == v[2][1]) y=v[1][1];
else if(v[1][1] == v[2][1]) y=v[0][1];

이미 세 점의 위치를 알고 있기에 별도로 반복문을 돌릴 필요없이 x좌표가 존재하는 v[0][0], v[1][0], v[2][0]을 모두 확인하여 중복되지 않은 좌표가 x좌표가 된다. y좌표도 동일하게 v[0][0], v[0][1], v[0][2]을 모두 확인하여 중복되지 않은 y좌표를 찾으면 된다.

2. 반복문 내 조건문 활용

그런데, x좌표와 y좌표를 1번 풀이처럼 하드코딩으로 작성하는 것이 아니라 반복문에서 인덱스를 통해 접근해서 찾을 수 있지 않을까? 한 번 반복문에서 나머지 한 좌표를 구해보자.
반복문 0번 인덱스에서 x좌표를 먼저 구하고 1번 인덱스에서 y좌표를 구한다.

코드로 작성해보자.

1
2
3
4
5
for(int i=0; i<answer.length; i++) {
    if(v[0][i] == v[1][i]) answer[i]=v[2][i];
    else if(v[0][i] == v[2][i]) answer[i] = v[1][i];
    else if(v[1][i] == v[2][i]) answer[i] = v[0][i];
}

인덱스가 0일 때는 x좌표를 1일 때는 y좌표를 v[0][i], v[1][i], v[2][i]를 확인하여 찾을 수 있다.

3. 비트연산자 활용

마지막으로 비트연산자를 활용하면 위의 2가지 풀이보다 더 간단하게 풀 수 있다.

비트연산자란?
논리연산자와 비슷하지만, 비트(bit) 단위로 논리 연산을 할 때 사용하는 연산자이다.
또한, 비트 단위로 왼쪽이나 오른쪽으로 전체 비트를 이동하거나 1의 보수를 만들 때 사용한다.

이 문제에선 비트연산자 중에서 XOR 연산을 할 수 있는 ”^” 연산자를 이용한다. XOR연산은 두 수가 같으면 같은 값을, 다르면 다른 값을 반환한다.

A B A^B
1 1 0
1 0 1
0 1 1
0 0 0

v=[[1, 4], [3, 4], [3, 10]] 일 때, XOR 연산과정을 예를 들어 살펴보자.

1
2
3
4
5
x좌표 : v[0][0] ^ v[1][0] ^ v[2][0]
y좌표 : v[0][1] ^ v[1][1] ^ v[2][1]

v[0][0]^v[1][0]^v[2][0] = 1^3^3 = 1
v[0][1]^v[1][1]^v[2][1] = 4^4^10 = 10

위와 같이 A와 B에 XOR 연산을 하고 다시 B로 XOR연산을 하게 되면 처음 값 A가 나오게 된다.
이제 코드로 작성해보자.

1
2
answer[0] = v[0][0] ^ v[1][0] ^ v[2][0];
answer[1] = v[0][1] ^ v[1][1] ^ v[2][1];

한눈에 봐도 코드가 너무나도 간결해졌다.


작성 코드


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
import java.util.*;

class Solution {
    public static void main(String[] args) {
        int[][] v = {{1,4},{3,4},{3,10}};
        // int[][] v ={{1,1},{2,2},{1,2}};

        long start = System.currentTimeMillis();
        solution3(v);
        long end = System.currentTimeMillis();
        System.out.println("\n수행시간 = " + (end-start));
    }
    // 1. 조건문 활용
    public static int[] solution(int[][] v) {
        int x = 0;
        int y = 0;

        if(v[0][0] == v[1][0]) x=v[2][0];
        else if(v[0][0] == v[2][0]) x=v[1][0];
        else if(v[1][0] == v[2][0]) x=v[0][0];
        
        if(v[0][1] == v[1][1]) y=v[2][1];
        else if(v[0][1] == v[2][1]) y=v[1][1];
        else if(v[1][1] == v[2][1]) y=v[0][1];

        int[] answer = {x,y};
        return answer;
    }
    // 2. 반복문 내 조건문 활용
    public static int[] solution2(int[][] v) {
        int[] answer = new int[2];

        for(int i=0; i<answer.length; i++) {
            if(v[0][i] == v[1][i]) answer[i]=v[2][i];
            else if(v[0][i] == v[2][i]) answer[i] = v[1][i];
            else if(v[1][i] == v[2][i]) answer[i] = v[0][i];
        }

        return answer;
    }
    // 3. 비트연산자 활용
    public static int[] solution3(int[][] v ) {
        int[] answer = new int[2];

        answer[0] = v[0][0] ^ v[1][0] ^ v[2][0];
        answer[1] = v[0][1] ^ v[1][1] ^ v[2][1];

        return answer;
    }
}

회고

  • 프로그래머스 데브코스 코딩테스트 사전 테스트 중 나온 문제인데, 어떻게 푸냐에 따라서 코드의 가독성이 달라져 재미있게 풀었다.