πŸ“– Problem Solution/Programmers

[Swift] ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€ μœ„ν΄λ¦¬ μ±Œλ¦°μ§€ ꡐ점에 별 λ§Œλ“€κΈ°

Fomagran πŸ’» 2021. 12. 14. 14:13
728x90
λ°˜μ‘ν˜•



Problem

 

 

μ½”λ”©ν…ŒμŠ€νŠΈ μ—°μŠ΅ - ꡐ점에 별 λ§Œλ“€κΈ°

[[2, -1, 4], [-2, -1, 4], [0, -1, 1], [5, -8, -12], [5, 8, 12]] ["....*....", ".........", ".........", "*.......*", ".........", ".........", ".........", ".........", "*.......*"] [[0, 1, -1], [1, 0, -1], [1, 0, 1]] ["*.*"] [[1, -1, 0], [2, -1, 0], [4, -

programmers.co.kr


Solution

 

ν•΄λ‹Ή 문제의 핡심은 두 직선(방정식)의 ꡐ점을 μ°ΎλŠ” 방법을 μ•„λŠ” κ²ƒμž…λ‹ˆλ‹€.

 

μ•„λž˜ 두 직선이 μžˆλ‹€κ³  κ°€μ •ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

1. ax + by + c
2. dx + ey + f

 

ꡐ점을 μ°ΎλŠ” 식은 μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

 

x = (bf - ed) / (ad - bc)
y = (ec - af) / (ad - bc)

 

μ—¬κΈ°μ„œ ad - bcκ°€ λ§Œμ•½ 0이라면 두 직선은 ν‰ν–‰ν•˜λ‹€λŠ” μ˜λ―Έμž…λ‹ˆλ‹€.

 

μœ„ λ°©μ‹λŒ€λ‘œ λͺ¨λ“  μ§μ„ μ˜ ꡐ점을 찾으며 x의 κ°€μž₯ 큰 κ°’κ³Ό μž‘μ€ κ°’, y의 κ°€μž₯ 큰 κ°’κ³Ό μž‘μ€ 값을 μ°Ύμ•„ μ΅œμ†Œ μ‚¬κ°ν˜•μ˜ λ²”μœ„λ₯Ό μ •ν•©λ‹ˆλ‹€.

 

λ§ˆμ§€λ§‰μœΌλ‘œ λ²”μœ„ μ•ˆμ—μ„œ ꡐ점의 μœ„μΉ˜λ₯Ό λ³„λ‘œ λ°”κΏ”μ€€ λ’€ λ°˜ν™˜ν•©λ‹ˆλ‹€.

 

μ½”λ“œ ν•΄μ„€

 

ꡐ점,μ΅œμ†Œ μ‚¬κ°ν˜•,μ§μ„ μ˜ ꡬ쑰체λ₯Ό λ§Œλ“€μ–΄μ€λ‹ˆλ‹€.

 

struct Line {
    let x:Int,y:Int,c:Int
}

struct Square {
    var minX:Int = Int.max
    var maxX:Int = -Int.max
    var minY:Int = Int.max
    var maxY:Int = -Int.max
}

struct Meet {
    let x:Int,y:Int
}

 

1. ꡐ점을 μ°ΎλŠ”λ‹€.

 

μœ„μ—μ„œ ꡐ점을 κ΅¬ν•˜λŠ” μ‹μœΌλ‘œ 두 μ§μ„ μ˜ ꡐ점을 κ΅¬ν•΄μ€λ‹ˆλ‹€.

 

λ‹€λ§Œ λ¬Έμ œμ—μ„œ x와 y λͺ¨λ‘ μ •μˆ˜μΈ ꡐ점만 ν•„μš”ν•˜λ―€λ‘œ μ •μˆ˜κ°€ μ•„λ‹Œ 것은 nil둜 λ°˜ν™˜ν•©λ‹ˆλ‹€.

 

func findMeet(_ l1:Line,_ l2:Line) -> Meet? {
    let adbc = l1.x*l2.y - l1.y*l2.x
    if adbc == 0 { return nil }
    let bfed = l1.y*l2.c - l1.c*l2.y
    let ecaf = l1.c*l2.x - l1.x*l2.c
    let meet = Meet(x:bfed/adbc, y:ecaf/adbc)
    return bfed % adbc == 0 && ecaf % adbc == 0 ? meet : nil
}

 

2. λͺ¨λ“  μ§μ„ μ˜ ꡐ점을 κ΅¬ν•œλ‹€.

 

λͺ¨λ“  μ§μ„ μ˜ ꡐ점을 μ°Ύμ•„ μ €μž₯ν•©λ‹ˆλ‹€.

 

func getIntegerMeet(lines:[[Int]]) -> [Meet] {
    var lines:[[Int]] = lines
    var meets:[Meet] = []
    while !lines.isEmpty {
        let first = lines.removeFirst()
        let firstLine = Line(x:first[0], y:first[1], c: first[2])
        for l in lines {
            let otherLine = Line(x: l[0], y: l[1], c: l[2])
            if let meet = findMeet(firstLine,otherLine) {
                meets.append(meet)
            }
        }
    }
    return meets
}

 

3. λͺ¨λ“  ꡐ점듀을 μ΄μš©ν•΄ μ΅œμ†Œ μ‚¬κ°ν˜•μ˜ λ²”μœ„λ₯Ό μ •ν•œλ‹€.

 

func getSquare(meets:[Meet]) -> Square {
    var square:Square = Square()
    meets.forEach {
        square.minX = min(square.minX,$0.x)
        square.maxX = max(square.maxX,$0.x)
        square.minY = min(square.minY,$0.y)
        square.maxY = max(square.maxY,$0.y)
    }
    return square
}

 

4. μ΅œμ†Œ μ‚¬κ°ν˜•μ— ꡐ점을 λ³„λ‘œ λ°”κΏ”μ€€λ‹€.

 

x의 μ΅œλŒ€κ°’ - μ΅œμ†Œκ°’ + 1만큼의 배열을 y의 μ΅œλŒ“κ°’ - μ΅œμ†Œκ°’ + 1만큼 λ§Œλ“€μ–΄μ€λ‹ˆλ‹€.

 

κ·Έ λ‹€μŒ ꡐ점듀을 ν™•μΈν•˜λ©΄μ„œ λ³„λ‘œ λ°”κΏ”μ€λ‹ˆλ‹€.

 

μ£Όμ˜ν•˜μ‹€ 점은 μ’Œν‘œμ—μ„œ y값은 μœ„λ‘œ 갈수둝 컀지기 λ•Œλ¬Έμ— μ΅œλŒ“κ°’μ—μ„œ ν˜„μž¬ y값을 λΉΌμ€λ‹ˆλ‹€.

 

func changeMeetsToStar(meets:[Meet],square:Square) -> [String] {
    var sqaureDot = Array(repeating: Array(repeating: ".", count: square.maxX-square.minX+1), count: square.maxY-square.minY+1)
    for meet in meets {
        let x = meet.x - square.minX
        let y = square.maxY - meet.y
        sqaureDot[y][x] = "*"
    }
    return sqaureDot.map{$0.joined()}
}

 

5. λ³„λ‘œ λ°”κΎΌ μ‚¬κ°ν˜•μ„ λ°˜ν™˜ν•œλ‹€.

 

func solution(_ line:[[Int]]) -> [String] {
    let meets:[Meet] = getIntegerMeet(lines:line)
    let square = getSquare(meets: meets)
    return changeMeetsToStar(meets: meets, square: square)
}

Source Code

 

728x90
λ°˜μ‘ν˜•