[프로그래머스] Level0. 평행

Benjamin·2023년 2월 21일
0

프로그래머스

목록 보기
25/58


처음에 두 점씩 이어서 선분을 만드는 경우의 수를 잘못계산했다.
총 점이 4개이기떄문에, 4*3=12. 즉 12가지 경우의수가 있을거라생각하고 진행했다가 틀렸다.

위 로직대로하면 말이안된다.
예를들어 점 a,b,c,d가 있을때 a-b, b-c 이렇게 연결되는 경우가있기때문이다.
이때에는 b가 겹치기도하고, d는 선분에 포함되어있지않게때문에 문제조건과 맞지않다.

잘 생각해보면 4개의 점을 모두 선분에 포함시켜야하고, 각 선분에는 겹치지않는 점 2개만 있어야한다.

따라서 경우의수는 3가지밖에없고 이를 코드로 직접 다 작성했다.

내 코드

class Solution {
    public int solution(int[][] dots) {
        int answer = 0;
        int[][] line = new int[3][4];

        line[0][0] = Math.abs(dots[0][0] - dots[1][0]);
        line[0][1] = Math.abs(dots[0][1] - dots[1][1]);
        line[0][2] = Math.abs(dots[2][0] - dots[3][0]);
        line[0][3] = Math.abs(dots[2][1] - dots[3][1]);
        
        line[1][0] = Math.abs(dots[0][0] - dots[2][0]);
        line[1][1] = Math.abs(dots[0][1] - dots[2][1]);
        line[1][2] = Math.abs(dots[1][0] - dots[3][0]);
        line[1][3] = Math.abs(dots[1][1] - dots[3][1]);
        
        line[2][0] = Math.abs(dots[0][0] - dots[3][0]);
        line[2][1] = Math.abs(dots[0][1] - dots[3][1]);
        line[2][2] = Math.abs(dots[1][0] - dots[2][0]);
        line[2][3] = Math.abs(dots[1][1] - dots[2][1]);
           
        for(int i =0; i<3;i++) {
            
            int gcd1 = GCD(line[i][0] ,line[i][1]);
            if(gcd1 != 1) {
                line[i][0] = line[i][0]/gcd1;
                line[i][1] = line[i][1]/gcd1;
            }
            int gcd2 = GCD(line[i][2] ,line[i][3]);
            if(gcd2 != 1) {
                line[i][2] = line[i][2]/gcd2;
                line[i][3] = line[i][3]/gcd2;
            }
            
            if(line[i][0] == line[i][2] && line[i][1] == line[i][3]) {
                answer=1;
                break;
            }
        }   
        return answer;
    }
    
     public int GCD(int a,int b) {
        int max = 1;
        for(int i=1; i<=a && i<=b; i++) {
            if(a%i ==0 && b%i==0) {
                max = i;
            }
        }
        return max;
    }      
}

내 코드의 가독성이 조금 좋지않은것같아서 다른 코드도 공부한다.

다른 코드

import java.lang.Math;
class Solution {
    private int xPos = 0;
    private int yPos = 1;
    private int[][] checkCases = {{0, 1, 2, 3}, {0, 2, 1, 3}, {0, 3, 1, 2}};
    public int solution(int[][] dots) {
        int answer = 0;
        for (int[] checkCase : checkCases) {
            if (checkParallel(checkCase, dots)) {
                answer = 1;
                break;
            }
        }

        return answer;
    }

    private boolean checkParallel(int[] checkCase, int[][] dots) {
        int xPos1 = dots[checkCase[0]][xPos];
        int yPos1 = dots[checkCase[0]][yPos];
        int xPos2 = dots[checkCase[1]][xPos];
        int yPos2 = dots[checkCase[1]][yPos];
        int xPos3 = dots[checkCase[2]][xPos];
        int yPos3 = dots[checkCase[2]][yPos];
        int xPos4 = dots[checkCase[3]][xPos];
        int yPos4 = dots[checkCase[3]][yPos];
        // (y4 - y3)(x2 - x1) - (x4 - x3)(y2 - y1) 평행여부 조건
        int chk = ((yPos4 - yPos3) * (xPos2 - xPos1)) - ((xPos4 - xPos3) * (yPos2 - yPos1));
        if (chk == 0) {
            return true;
        }
        return false;
    }
}

가능한 경우의 수 조합을 checkCases 배열에 넣어준다.
앞에거 2개 뒤에거 2개끼리의 점을 잇는다는 뜻이다.

기울기가 같으면 평행하는것이므로 차이의 결과가 0이다.
이를 이용해서 진행할 수 있다.

다른 코드 2

class Solution {
    public int solution(int[][] dots) {
        int x1 = dots[3][0];
        int y1 = dots[3][1];
        for (int i = 0; i < 3; i++) {
            int x2 = dots[i][0];
            int y2 = dots[i][1];
            int x3 = dots[(i+1)%3][0];
            int y3 = dots[(i+1)%3][1];
            int x4 = dots[(i+2)%3][0];
            int y4 = dots[(i+2)%3][1];
            if((y2-y1)/(double)(x2-x1)==(y4-y3)/(double)(x4-x3)){
                return 1;
            }
        }
        return 0;
    }
}

기울기가 분수형태이므로 나눗셈을 했을 때 무한소수가 되는게있을것이다.
그리고 유한소수라고 하더라도 결과적으로 double형 유효자릿수의 이하 자리수가 다르다면, 기울기가 아주 살짝이라도 다르지않을까?
하는 의문에 나눗셈은 이용할 생각을 안했다.
그런데 이렇게 해도 정답처리가된다.
내가 잘못생각한걸까?

0개의 댓글