[Level 2] 거리두기 확인하기 + Swift

sanghee·2021년 11월 12일
0

🙈코딩테스트

목록 보기
43/52
post-thumbnail

문제 링크

코딩테스트 연습 - 거리두기 확인하기

문제

5개의 대기실을 본 죠르디는 각 대기실에서 응시자들이 거리두기를 잘 기키고 있는지 알고 싶어졌습니다. 자리에 앉아있는 응시자들의 정보와 대기실 구조를 대기실별로 담은 2차원 문자열 배열 places가 매개변수로 주어집니다. 각 대기실별로 거리두기를 지키고 있으면 1을, 한 명이라도 지키지 않고 있으면 0을 배열에 담아 return 하도록 solution 함수를 완성해 주세요.

입력

let places = [["POOOP", "OXXOX", "OPXPX", "OOXOX", "POXXP"], ["POOPX", "OXPXP", "PXXXO", "OXXXO", "OOOPP"], ["PXOPX", "OXOXP", "OXPOX", "OXXOP", "PXPOX"], ["OOOXX", "XOOOX", "OOOXX", "OXOOX", "OOOOO"], ["PXPXP", "XPXPX", "PXPXP", "XPXPX", "PXPXP"]]

출력

[1, 0, 1, 1, 1]

문제 풀이

String 확장

"POOOP"를 배열처럼 사용하기 위해서 String을 확장하였다. 다음과 같이 사용할 수 있다.

extension String {
    subscript(_ index: Int) -> Character {
        self[self.index(self.startIndex, offsetBy: index)]
    }
}
let str = "POOOP"
str[0] // "P"

Solution 함수

  1. places에서 place마다 돈다.
  2. place의 P의 [행, 열] 위치값을 저장하는 pArr 배열과 해당 place가 안전한 지를 저장하는 isSafe Bool 타입의 변수를 선언한다.
  3. place에서 각 열마다 돌면서 P의 [행, 열] 위치값을 pArr에 저장한다.
  4. pArr에서 각 P를 서로 비교해본다. 두 P의 거리가 2를 초과하는 경우 for문을 continue 한다.
  5. 두 P의 거리가 1이라면, 안전하지 않으므로 isSafe를 false로 저장한 이후에 for문을 break한다.
  6. 두 P의 거리가 2라면 몇가지를 체크해야 한다.
    1. 행이 일치하는 경우: 사이의 값이 O가 아닌지 체크한다.
    2. 열이 일치하는 경우: 사이의 값이 O가 아닌지 체크한다.
    3. 행과 열이 1씩 차이나는 경우: 사이의 값 두개가 O가 아닌지 체크한다.
  7. 모두 체크한 이후에도 isSafe가 true이면 result에 1을 추가하고, isSafe가 false이면 0을 추가한다.
func solution(_ places:[[String]]) -> [Int] {
    var result: [Int] = []
    
    // place = ["POOOP", "OXXOX", "OPXPX", "OOXOX", "POXXP"]
    for place in places {
        var pArr: [[Int]] = []
        var isSafe = true
        
        // row == "POOOP"
        // pArr에 P의 [행, 열] 위치값을 넣는다.
        for (i, row) in place.enumerated() {
            for (j, v) in row.enumerated() {
                if v == "P" {
                    pArr.append([i, j])
                }
            }
        }

        for i in 0..<pArr.count {
            if !isSafe { break }
            
            for j in (i+1)..<pArr.count {
                let first = pArr[i] // (1, 0)
                let second = pArr[j] // (2, 1)
                let distance = abs(first[0] - second[0]) + abs(first[1] - second[1])
                
                // 거리가 2 초과인 경우 계속
                if distance > 2 { continue }
                
                // 거리가 1인 경우 X
                if distance == 1 {
                    isSafe = false
                    break
                }
                
                // 거리가 2인 경우 체크
                if distance == 2 {
                    if (first[0] == second[0]) {
                        // 행이 일치하는 경우
                        if place[first[0]][min(first[1], second[1]) + 1] == "O" {
                            isSafe = false
                            break
                        }
                    } else if (first[1] == second[1]) {
                        // 열이 일치하는 경우
                        if place[min(first[0], second[0]) + 1][first[1]] == "O" {
                            isSafe = false
                            break
                        }
                    } else {
                        // 행과 열이 1씩 차이나는 경우
                        if place[first[0]][second[1]] == "O" || place[second[0]][first[1]] == "O" {
                            isSafe = false
                            break
                        }
                    }
                }
            }
        }
        result.append(isSafe ? 1 : 0)
    }
    return result
}
profile
👩‍💻

0개의 댓글