티스토리 뷰

반응형

 

 

오늘은 프로그래머스의 레벨2 문제, 행렬테두리회전하기를 swift언어로 풀어보겠습니다. 2차원 배열의 특정 범위의 테두리 값들을 우측으로 shift 시키고, 그중 가장 작은 값을 반환해야하는 문제입니다. 이때 테두리 회전 동작은 여러번 진행될 수 있으며, 회전된 값들은 유지된 채 다른 테두리 회전을 진행하게 됩니다.

 

자세한 문제 내용은 아래 링크를 참고하시기 바랍니다. 이어서 바로 swift 언어 풀이를 해보겠습니다. 🤗

 

 

프로그래머스 Lv2 문제, 행렬 테두리 회전하기 문제 링크 ▼

 

코딩테스트 연습 - 행렬 테두리 회전하기

6 6 [[2,2,5,4],[3,3,6,6],[5,1,6,3]] [8, 10, 25] 3 3 [[1,1,2,2],[1,2,2,3],[2,1,3,2],[2,2,3,3]] [1, 1, 5, 3]

programmers.co.kr

 

 

 

 

 


프로그래머스 구현문제, 행렬테두리회전하기 swift 풀이

위 makeArray는 초기 배열을 만들어주는 메서드입니다. rows, columns(행, 열) 값을 받아 그만한 크기의 2차원 배열을 만들어줍니다. 문제 설명에 맞게 배열은 1 ~ rows * columns의 숫자를 차례대로 배열에 넣어줍니다. 예를들어, 2 X 2 행렬일 경우

 

1 2

3 4

 

와 같은 2차원배열이 생성되게 됩니다. 위 코드를 보자면, 0 ~ rows-1 범위의 행에 차례대로 [Int]배열을 넣어주고 있습니다.

[] -> [[1, 2]] -> [[1, 2], [3, 4]] 와 같은 방식으로 배열이 만들어지면 그 최종 결과값을 return 합니다.

 

 

 



좌표값 타입을 정의한 Pos, 테두리를 탐색하는 순서를 정의한 dx, dy입니다. 해당 배열의 동일 인덱스는 각각 현재 탐색할 x, y 좌표방향을 정의합니다. 그 순서는 인덱스 0부터 시작하여 우 -> 하 -> 좌 -> 상 이 되겠습니다.

 

 

 

 

13 ~ 14행) 특정 범위의 테두리 영역 값들을 우회전 시키면서 테두리 영역의 최솟값을 반환하는 메서드입니다. 메서드 인자값인 startPos 가 (1, 1), endPos가 (3, 3)인 경우, (1, 1) ~ (3, 3) 영역의 테두리 값을 회전하는 방식입니다. 

 

2차원배열 변수로부터 접근해서 사용할 수 있도록 extension Array where Element == [Int]를 사용했습니다. 또한 rotate는 구조체 내부 값을 변경하는 메서드로 mutating func 키워드를 붙여주어야 합니다.

 

15 ~ 17행) tempArray는 테두리 회전이 된 배열상태를 기록하기 위한 변수입니다. 원본 배열의 값은 고정시키면서, 원본 배열의 값을 기준을로 회전했을때 배치되어야 할 값을 판단하고, 값들을 회전시키면 최종적으로 29행에서 원본배열에 그 결과값을 넘겨줍니다.

minValue는 테두리 영역 값들 중 최솟값을 기록합니다. index는 회전시켜야할 영역을 하나하나 탐색하는데 사용할 인덱스로 초기값으로 startPos를 설정, 테두리 영역을 하나하나 탐색하게 됩니다.

 

18 ~ 28행) 이제 index를 기준으로 하나하나 테두리영역을 탐색합니다. 현재 탐색중인 index 위치를 기준으로 값이 변경되어야할 targetX, targetY값을 계산한 후, 이 타겟값들이 테두리영역을 벗어났는지를 22 ~ 23행에서 체크해줍니다. 이후 정상적인 테두리 영역 값일 경우, 배열의 값을 변경해줍니다. 이를 반복하여 최종적으로 테두리 영역의 값들은 우 shift가 됩니다. 

 

29 ~ 30행) 회전 연산을 수행한 결과 값은 tempArray에 저장이 되었습니다. 이를 원본 배열 넘겨주고, 최솟값을 반환하면서 메서드는 종료됩니다.

 

 

 

 

solution부분입니다. makeArray를 통해 2차월 배열을 생성하고, reduce 연산자를 통해 각 query에 대한 회전 및 최솟값 반환 연산을 수행하면서 답을 반환하게 됩니다.

 

지금까지 작성한 소스코드의 실행 결과 및 전체 소스코드는 아래와 같습니다.

 


프로그래머스 2단계 문제, 행렬테두리회전하기 swift 언어 풀이 제출 결과

func makeArray(_ rows: Int, _ columns: Int) -> [[Int]] {
    return (0..<rows).reduce(into: [[Int]]()) { (result, rowIndex) in
        let startNum = rowIndex * columns + 1
        result.append([Int](startNum..<startNum+columns))
    }
}

typealias Pos = (x: Int, y: Int)
let dx = [0, 1, 0, -1]
let dy = [1, 0, -1, 0]

extension Array where Element == [Int] {
    mutating func rotate(_ startPos: Pos, _ endPos: Pos) -> Int {
        var tempArray = self
        var minValue = self[startPos.x][startPos.y]
        var index = startPos
        dx.indices.forEach { dirIndex in
            while true {
                let targetX = index.x + dx[dirIndex]
                let targetY = index.y + dy[dirIndex]
                if (targetX < startPos.x || targetX > endPos.x 
                || targetY < startPos.y || targetY > endPos.y) { break }
                tempArray[targetX][targetY] = self[index.x][index.y]
                index = (targetX, targetY)
                minValue = minValue > self[targetX][targetY] ? self[targetX][targetY] : minValue
            }
        }
        self = tempArray
        return minValue
    }
}

func solution(_ rows:Int, _ columns:Int, _ queries:[[Int]]) -> [Int] {
    var array: [[Int]] = makeArray(rows, columns)
    return queries.reduce(into: [Int]()) { (answer, query) in
        answer.append(array.rotate((query[0]-1, query[1]-1),
                               (query[2]-1, query[3]-1)))
    }
}

 

 

 

반응형
댓글
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함