본문 바로가기
코딩 테스트/프로그래머스

[프로그래머스] (Swift) 정수를 나선형으로 배치하기

by Dev.Andy 2023. 6. 5.

머리말

문제 링크

코딩테스트 연습 - 정수를 나선형으로 배치하기 | 프로그래머스 스쿨

이 문제를 선택한 이유

  • 구현 문제 연습

풀이

한번 4부터 6까지 배열을 직접 만들어 보았다.

/*
[[1,  2,  3, 4],
[12, 13, 14, 5],
[11, 16, 15, 6],
[10,  9,  8, 7]]

[[1,  2,  3,  4, 5],
[16, 17, 18, 19, 6],
[15, 24, 25, 20, 7],
[14, 23, 22, 21, 8],
[13, 12, 11, 10, 9]]

[[1,  2,  3,  4,  5, 6],
[20, 21, 22, 23, 24, 7],
[19, 32, 33, 34, 25, 8],
[18, 31, 36, 35, 26, 9],
[17, 30, 29, 28, 27, 10]]
[16, 15, 14, 13, 12, 11]]
*/

풀이를 찾아 보니 여러 가지가 있던데, 나는 4개의 함수로 구분해서 풀었다. 1부터 n의 제곱까지 값을 넣게 될 전역변수 count를 이용하여 4개의 함수를 반복하여 푸는 방식이다.

풀이 순서

  • n * n 형태이며, 기본값이 0인 배열로 초기화한다.
  • 크게 나선형을 그리는 것은 4가지의 함수로 나누어 볼 수 있다.
    1. 오른쪽으로 이동(toRight)
    2. 아래로 이동(toBottom)
    3. 왼쪽으로 이동(toLeft)
    4. 위로 이동(toTop)
  • 이제 관건은 각 함수를 어떻게 구현할지이다.
  • 오른쪽으로와 아래로 이동은 배열의 관점에서 봤을 때 인덱스가 증가하는 방향이기에, 인덱스 i가 오름차순인 반복문을 이용했다.
  • 반면에 왼쪽으로와 위로 이동은 인덱스가 감소하는 방향이라서 Swift의 for-in stride 구문을 사용하하여 점차 감소하는 반복문을 이용했다.
  • ⭐️ 이제 여기서 중요한 점은 단순히 반복문만으로 값을 증가시키면 이동하면서 값의 중첩이 일어날 수 있어서 조건문이 하나가 필요하다.
    • 조건문은 바로 해당 인덱스가 0인지 아닌지를 판별하는 것이다.
import Foundation

func solution(_ n:Int) -> [[Int]] {
    
    var matrix = Array(repeating: Array(repeating: 0, count: n), count: n)
    var count = 1
    
    func toRight(_ rowIndex: Int) -> () {
        for i in 0..<n {
            if matrix[rowIndex][i] == 0 {
                matrix[rowIndex][i] = count
                count += 1
            }
        }
    }
    
    func toBottom(_ colIndex: Int) -> () {
        for i in 0..<n {
            if matrix[i][colIndex] == 0 {
                matrix[i][colIndex] = count
                count += 1
            }
        }
    }
    
    func toLeft(_ rowIndex: Int) -> () {
        for i in stride(from: n-1, through: 0, by: -1) {
            if matrix[rowIndex][i] == 0 {
                matrix[rowIndex][i] = count
                count += 1                
            }
        }
    }
    
    func toTop(_ colIndex: Int) -> () {
        for i in stride(from: n-1, through: 0, by: -1) {
            if matrix[i][colIndex] == 0 {
                matrix[i][colIndex] = count
                count += 1
            }
        }
    }
    
    for i in 0...n/2 {
        toRight(i)
        toBottom(n-1-i)
        toLeft(n-1-i)
        toTop(i)
    }
    
    return matrix
}

 

다른 풀이

모각코를 하면서 다른 분의 풀이를 좀 변경했는데,

(closedRange).reversed()이랑 x, y, m 변수를 이용해 이중 반복문으로 접근했다.

import Foundation

func solution(_ n:Int) -> [[Int]] {
    
    var answer: [[Int]] = Array(repeating: Array(repeating: 0, count: n), count: n)
    
    for i in 0..<n {
        answer[0][i] = i + 1
    }
    
    var x: Int = 0
    var y: Int = n-1
    var m: Int = 1
    
    for count in (1..<n).reversed() {
        
        for _ in 0..<count {
            let current = answer[x][y]
            x += m
            answer[x][y] = current + 1
        }
        
        for _ in 0..<count {
            let current = answer[x][y]
            y -= m
            answer[x][y] = current + 1
        }
        m = m * -1
    }
    
    return answer
}

 

댓글