알고리즘/배열

프로그래머스 - 교점에 별 만들기[Java]

연향동큰손 2025. 8. 18. 21:44

https://school.programmers.co.kr/learn/courses/30/lessons/87377?language=java

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

문제 해결

 

이 문제에서 어려웠던 부분은 교점의 최대값 최솟값에 맞춰서 출력 배열을 조절하는 과정이었다.

 

  • 교점의 x좌표 - x의 최솟값
  • y의 최대값 - 교점의 y좌표

이렇게 좌표를 변환 해줘서 각 교점의 최대값 최솟값에 맞춰서 배열의 크기를 조절해야한다. 

 

또한 정수 좌표에 대해서만 별표를 넣어야 하기 때문에 정수임을 체크하는 방법은 1로 나누었을때 나머지가 0인가로 판별하였다.

if(x%1.0 != 0 || y%1.0 != 0){
            return null;
        }

 

<처음 작성한 코드>

import java.util.*;

class Solution {
    public String[] solution(int[][] line) {
        List<long[]> list = new ArrayList<>();
        long highX = Long.MIN_VALUE;
        long lowX = Long.MAX_VALUE;
        long highY = Long.MIN_VALUE;
        long lowY = Long.MAX_VALUE;
        
        for(int i=0; i<line.length-1; i++){
            for(int j=i+1; j<line.length; j++){
                Long x = getX(line[i], line[j]);
                Long y = getY(line[i], line[j]);
                if(x != null && y != null){
                    list.add(new long[]{x, y});
                    if(x > highX) highX = x;
                    if(x < lowX) lowX = x;
                    if(y > highY) highY = y;
                    if(y < lowY) lowY = y;
                }
            }
        }
        
        int width = (int)(highX - lowX + 1);
        int height = (int)(highY - lowY + 1);
        char[][] map = new char[height][width];
        
        for(int i=0; i<height; i++) {
            Arrays.fill(map[i], '.');
        }
        for(long[] coord : list){
            int x = (int)(coord[0] - lowX);
            int y = (int)(highY - coord[1]);
            map[y][x] = '*';
        }
        String[] answer = new String[height];
        for(int i=0; i<height; i++){
            answer[i] = new String(map[i]);
        }
        return answer;
    }
    
    public static Long getX(int[] a, int[] b){
        long a1 = a[0], b1 = a[1], c1 = a[2], a2 = b[0], b2 = b[1], c2 = b[2];
        long mod = a1 * b2 - b1 * a2;
        if(mod == 0) return null;
        long nx = b1 * c2 - c1 * b2;
        if(nx % mod != 0) return null;
        return nx / mod;
    }

    public static Long getY(int[] a, int[] b){
        long a1 = a[0], b1 = a[1], c1 = a[2], a2 = b[0], b2 = b[1], c2 = b[2];
        long mod = a1 * b2 - b1 * a2;
        if(mod == 0) return null;
        long ny = c1 * a2 - a1 * c2;
        if(ny % mod != 0) return null;
        return ny / mod;
    }
}

 

<책의 코드>

import java.util.*;

class Solution {
    private static class Point{
        private final long x,y;
        private Point(long x, long y){
            this.x=x;
            this.y=y;
        }
    }
    
    public String[] solution(int[][] line) {
        
        List<Point> points = new ArrayList<>();
        for(int i=0; i<line.length; i++){
            for(int j=i+1; j<line.length; j++){
                Point intersection = intersection(line[i][0],line[i][1],line[i][2],
                                                 line[j][0],line[j][1],line[j][2]);
                if(intersection != null){
                    points.add(intersection);
                }
            }
        }
        
        Point minimum = getMinimumPoint(points);
        Point maximum = getMaximumPoint(points);
        
        int width = (int)(maximum.x-minimum.x+1);
        int height = (int)(maximum.y-minimum.y+1);
        
        char[][] arr = new char[height][width];
        for(char[] row : arr){
            Arrays.fill(row,'.');
        }
        
        for(Point p : points){
            int x = (int)(p.x-minimum.x);
            int y = (int)(maximum.y-p.y);
            arr[y][x]='*';
        }
        String[] result = new String[arr.length];
        for(int i=0; i<result.length; i++){
            result[i]=new String(arr[i]);
        }
        return result;
    }
    
    private Point getMinimumPoint(List<Point> points){
        long x = Long.MAX_VALUE;
        long y = Long.MAX_VALUE;
        
        for(Point p : points){
            if(p.x<x){
                x=p.x;
            }
            if(p.y<y){
                y=p.y;
            }
        }
        return new Point(x,y);
    }
    private Point getMaximumPoint(List<Point> points){
        long x = Long.MIN_VALUE;
        long y = Long.MIN_VALUE;
        
        for(Point p : points){
            if(p.x>x){
                x=p.x;
            }
            if(p.y>y){
                y=p.y;
            }
        }
        return new Point(x,y);
    }
    
    
    private Point intersection(long a1, long b1, long c1, long a2, long b2, long c2){
        double x = (double)(b1*c2-b2*c1)/(a1*b2-a2*b1);
        double y = (double)(a2*c1-a1*c2)/(a1*b2-a2*b1);
        if(x%1.0 != 0 || y%1.0 != 0){
            return null;
        }
        return new Point((long)x, (long)y);
    }
   
}