CodingTest/Programmers

프로그래머스[programmers] - 교점에 별 만들기(Kotlin)[LV2]

재한 2023. 9. 17. 13:31

문제

https://school.programmers.co.kr/learn/courses/30/lessons/87377

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제 풀이

문제를 끝까지 읽어야 한다. 끝까지 읽으면 교점을 구할 수 있는 공식을 친절하게 제공한다.

나는 공식의 존재를 모르고 있다가, 문제를 끝까지 읽고, 친절한 공식을 발견하고 좌절했다..

 

참고 사항을 참고하자.

해당 공식을 이용하면 쉽게 교점을 구할 수 있다.

교점을 구하고, 교점의 x와 y좌표를 통해서 최종적으로 그리게 될 그래프의  위아래 끝점을 구해줘야 한다.

그러한 끝점을 구하면 이제 그래프에서 내가 구한 교점에 해당하는 좌표에 *을 찍어 주면 되는 문제이다.

교점을 구하는 과정은 간단하지만, 교점을 그래프 상으로 표현하고, 그래프의 row와 col을 결정하는 과정이 조금 어렵다고 느꼈다.

문제 코드

import java.io.*
import java.util.*
import kotlin.math.*

class Solution {
    private val expression : MutableList<Triple<Long,Long,Long>> = mutableListOf()
    private val meet : MutableList<Pair<Int,Int>> =mutableListOf()
    private var minX =Int.MAX_VALUE
    private var minY =Int.MAX_VALUE
    private var maxX = Int.MIN_VALUE
    private var maxY=Int.MIN_VALUE
    fun solution(line: Array<IntArray>): Array<String> {
        for(i in 0 until line.size){
            expression.add(Triple(line[i][0].toLong(),line[i][1].toLong(),line[i][2].toLong()))
        }
        for(i in 0 until expression.size){
            for(j in i+1 until expression.size){
                val item = checkMeet(expression[i],expression[j])
                if(item!=null)
                    meet.add(item)
            }
        }
        val graph = Array(maxY-minY+1){CharArray(maxX-minX+1){'.'}}
        for(dot in meet){
            val r=maxY-dot.second
            val c=dot.first-minX
            graph[r][c]='*'
        }
        val answer = Array(graph.size){String(graph[it])}
        return answer
    }
    fun checkMeet(first : Triple<Long,Long,Long>,second:Triple<Long,Long,Long>) : Pair<Int,Int>?{
        //평행한 경우는 교점이 없다.
        val adbc = first.first*second.second-first.second*second.first //adbc
        if(adbc.toInt()==0) //평행 혹은 일치
            return null
        val bfed = first.second*second.third-first.third*second.second //bfed
        val ecaf=first.third*second.first-first.first*second.third
        
        if((bfed%adbc).toInt()!=0 || (ecaf%adbc).toInt()!=0)
            return null
        
        val meetX = (bfed/adbc).toInt()
        val meetY = (ecaf/adbc).toInt()
        maxX = max(maxX,meetX)
        minX = min(minX,meetX)
        maxY = max(maxY,meetY)
        minY = min(minY,meetY)
        return Pair(meetX,meetY)
    }
}