문제
입력
places: [[String]] = 5개의 문자열 배열이 주어진다.
[["POOOP", "OXXOX", "OPXPX", "OOXOX", "POXXP"], .... ]
각 문자열 배열은 5x5 형태로 주어진다.
P : 응시자
O : 비어있는 자리
X : 파티션
출력
result: [Int] = 각 방마다 거리제한을 지켰는 지 여부
지켰다면 = 1
지키지 않았다면 = 0
해석
먼저 입력 형태가 문자열의 2중 배열 형태로 주어지기 때문에 반복문을 통해 순회를 하긴해야할 것 같다.
1. 순회를 하면서 "P" 즉, 응시자가 앉아있다면 검사를 시작한다.
2. 검사를 시작하는 함수 check를 만들고 매개변수에 현재 검사 위치와 거리를 넘겨준다.
3. 상하좌우를 검사하며 재귀를 반복한다.
4. check 함수의 판단 조건은 다음과 같다.
- 거리가 3 이상이 되면 안전수칙을 지킨 것
- 거리 3 전에 P를 만나면 안전수칙을 지키지 않은 것
- 거리을 넘겼지만 두 응시자 사이에 파티션이 있다면 거리를 지킨 것
코드
import Foundation
func solution(_ places:[[String]]) -> [Int] {
var ans: [Int] = []
var places = places.map{ $0.map{ Array($0) } } // 문자열을 배열로 변경
for place in places {
var tmpPlace = place //
func check(_ r: Int, _ c: Int, _ dist: Int) -> Bool {
// 규칙을 지킴
// 1.범위를 벗어 났거나
// 2. 맨해튼 거리가 2초과
// 3. 중간에 파티션 있음
if !(0..<5 ~= r) || !(0..<5 ~= c) || dist == 3 || tmpPlace[r][c] == "X" {
return true
} else if tmpPlace[r][c] == "P" { return false } // 맨해튼 거리 2안에 또다른 응시자 있으면 불통
let nextDist = dist+1
// 모든 방향에 대하여 판단
return check(r-1,c,nextDist) && check(r+1,c,nextDist) && check(r,c-1,nextDist) && check(r,c+1,nextDist)
}
// 규칙을 지켰는 . 지여부
var isAuthorized: Bool = true
for (row, seat) in place.enumerated() {
for (col, p) in seat.enumerated() {
if p == "P" { // 응시자 발견
tmpPlace[row][col] = "-" // 현재 앉은 곳을 하이픈으로 표시
isAuthorized = check(row,col,0)
}
if !isAuthorized { break } // 지키지 않았다면 더이상 순회 붚필요
}
if !isAuthorized { break } // 지키지 않았다면 더이상 순회 붚필요
}
if isAuthorized {
ans.append(1)
} else {
ans.append(0)
}
}
return ans
}
'PS > 프로그래머스' 카테고리의 다른 글
[프로그래머스] 이모티콘 할인행사 (1) | 2024.09.21 |
---|---|
[프로그래머스] 양궁대회 (0) | 2024.09.20 |
[프로그래머스] 메뉴 리뉴얼 (0) | 2024.09.18 |
[프로그래머스] 괄호 변환 (0) | 2024.09.17 |
[프로그래머스] 문자열 압축 (1) | 2024.09.16 |