Codewars(알고리즘)/6Kyu

[Codewars] [6Kyu] Give me a Diamond

Dannian 2022. 1. 26. 16:06
반응형
 

Codewars: Achieve mastery through coding challenge

Codewars is a coding practice site for all programmers where you can learn various programming languages. Join the community and improve your skills in many languages!

www.codewars.com

이번 문제는 별 그리기 같은 문제입니다.

해당 문제에서 한 가지 오류가 있는데 메서드 리턴값이 옵셔널이 아닙니다. 반면 테스트 케이스는 옵셔널을 가정하고 있습니다.

따라서 func diamond(_ size: Int) -> String? { 과 같이 변경해주셔야 합니다.

일단 문제 자체는 크게 어렵지 않으니 방법만 간단히 보겠습니다.

1. Swift

1-1. 본인의 풀이

func diamond(_ size: Int) -> String? {
  if size != abs(size) {
    return nil
  }
  guard size % 2 == 1 else {
    return nil
  }
  let val : Int = (size - 1) / 2
  var totalStr : String = ""
  for i in 0 ..< size {
    var tempStar: String = ""
    let spacebar = abs(val - i)
    for _ in 0 ..< spacebar {
      tempStar += " "
    }
    for _ in 0 ..< size - (spacebar * 2) {
      tempStar += "*"
    }
    totalStr += tempStar + "\n"
  }
  return totalStr
}

저는 최대한 단순하게 생각하기 위해서 모두 풀어서 썼습니다. 다만 for문 안에 또 for문이 반복되기 때문에 시간복잡도로는 좋지 않다고 할 수 있겠네요.

먼저 size값이 음수 또는 홀수가 아닌 수일 때는 return nil을 해줍니다.

그 후 size만큼 for문을 돌리게 됩니다. 그 이유는 형태를 보면 금방 이해하실 수 있으신데, size가 3인 경우 3줄, 5일 경우 5줄 이런 식으로 규칙이 존재하기 때문입니다.

그 다음 *을 그리기 전 space bar 갯수를 계산하여 앞에 추가하고 그 후에 *을 특정 갯수만큼 그려줍니다.

 

1-2. Best Solution

hmccabe유저의 답이 가장 많은 Best Practice와 Clever를 받았습니다.

func diamond(_ size: Int) -> String? {
    guard size > 0 && size % 2 == 1 else {
        return nil
    }
    var diamond = ""
    let centerRow = size/2 + 1
    for row in 1...size {
        let spaces = abs(centerRow - row)
        diamond += String(repeating: " ", count: spaces) + String(repeating: "*", count: size-spaces*2) + "\n"
    }
    return diamond
}

코드를 보면 일단 guard문은 제가 풀어 쓴 if문을 한 번에 처리한 것입니다.

centerRow의 경우는 swift int의 특징을 이용한 것이라고 보시면 되겠는데, 예를 들어 size가 5인 경우 2로 나누면 값이 2가 나오기 때문에 위의 코드처럼 사용한 것입니다.

for문은 5만큼 돌게 될 것이고, spaces는 각 row와 centerRow의 차이의 절대값을 이용한 것입니다.

그 다음 줄에서 제가 생각을 안 하고 있던 부분이었는데, 위의 유저의 경우 String(repeating:, count:) 를 사용했습니다.

실무에서 저는 거의 쓴 적이 없는 방식이다보니 생각을 못 했네요.

 

이번 문제는 각 값의 규칙성을 찾아내면 그나마 쉽게 풀 수 있는 문제였습니다.

반응형