나의 답)
import Foundation
func solution(_ n:Int) -> Int {
return n % 2 == 1
? (1...n).filter { $0 % 2 == 1}.reduce(0, +)
: stride(from: 0, through: n, by: 2).map { $0 * $0 }.reduce(0, +)
}
문제에서 "홀수라면 n 이하의 홀수의 합", "짝수라면 n 이하의 짝수의 제곱의 합"이라는 두 가지 조건이 주어졌는데,
이걸 어떻게 효율적으로 나눠서 처리할지 고민했다.
처음에는 조건별로 따로따로 구현하려다 보니 코드가 완전 장황해져서 유지보수가 어려워질 것 같다는 생각이 들다가
얼마 전에 코테를 풀며 알게된 메서드를 이용해보면 될 것 같다는 생각이 들었다.
조건에 맞는 값을 필터링하면서도 반복문을 효율적으로 작성하고 싶었지만,
처음에는 stride 메서드의 존재를 잊고 있었고.. for문으로 처리하려 했었다.
func solution(_ n: Int) -> Int {
var sum = 0
for i in 1...n {
if n % 2 == 1 { // 홀수 조건
if i % 2 == 1 { // i도 홀수인 경우만 합산
sum += i
}
} else { // 짝수 조건
if i % 2 == 0 { // i가 짝수인 경우만 제곱하여 합산
sum += i * i
}
}
}
return sum
}
이건 내 기준 코드가 길어지고 가독성이 떨어지게 만들었다...
짝수 조건과 홀수 조건을 for i in 1...n
반복문 안에서 모두 처리하려 하다 보니, 매번 조건을 확인해야 했고
짝수일 때 짝수만 처리하면 되는 문제를 불필요하게 i
값마다 조건을 검사하게 만들었다.
if
문 안에 또 다른 if
문이 중첩되면서 코드가 읽기 어려워지기도 했고,
특히 if i % 2 == 1
과 같은 조건들이 여러 번 반복되면서 실수하기 쉬운 구조가 된 것 같았다.
예를 들어 n
이 1
이거나 2
인 경우에도 for
반복문이 실행되어야 하는데,
결과값이 잘못 나오는 경우가 있었다.
n = 1일 때, i % 2 == 1
조건은 만족했지만 다른 경계값에서는 놓칠 가능성이 있었고 결국 ..
n = 2일 때 짝수 조건에서 i % 2 == 0
가 제대로 동작하지 않았다...
.
.
.
.
func solution(_ n: Int) -> Int {
if n % 2 == 1 { // n이 홀수인 경우
return stride(from: 1, through: n, by: 2).reduce(0, +)
} else { // n이 짝수인 경우
return stride(from: 2, through: n, by: 2).map { $0 * $0 }.reduce(0, +)
}
}
if-else
구문을 사용해 stride
로 간단하게 두 가지 조건을 처리할 수 있었다.
특히, "짝수냐, 홀수냐"
라는 조건을 나누는 데서 n % 2 == 0
표현이 얼마나 직관적인지 새삼 깨닫는 순간이었다
복잡하게 생각할 필요 없이, 조건을 깔끔하게 처리하는 것이 중요하다는 생각도 하고..
아무튼 그래서 stride(from:to:by:)
나 stride(from:through:by:)
를 활용하면 반복문에서 특정 범위의 값들을 간결하게 필터링할 수 있다는 것을 알고 있었으니,
이를 통해 짝수와 홀수를 빠르게 구분하고, 불필요한 조건문을 줄일 수 있었다.
처음에는 문제를 한꺼번에 처리하려고 했지만,
"홀수 합"
과 "짝수 제곱의 합"
을 별도로 나눠서 생각하니 훨씬 접근이 좀 쉬워졌던 것 같다.
공책에 적으며 문제를 작은 단계로 나누고 각 부분을 해결한 뒤 합치는 방식을 글로 써본 것이 도움이 많이 됐다.
.
.
.
.
import Foundation
func solution(_ n:Int) -> Int {
return n % 2 == 1
// 삼항 연산자 이용
? (1...n).filter { $0 % 2 == 1}.reduce(0, +)
: stride(from: 0, through: n, by: 2).map { $0 * $0 }.reduce(0, +)
}
사실 2차코드에서 마무리하려했는데,
문제 자체가 1
아니면 2
이런식으로 둘 중 하나의 형태로 되어있으니 삼항연산자를 이용해보고 싶다는 생각이 들었다.
결론적으로 filter
함수가 더 추가되긴 했지만,
삼항 연산자를 활용해 코드의 길이를 줄이면서도 조건을 좀더 명확하게 구분할 수 있었다고 느꼈다.
filter
를 사용해 원하는 조건의 값만 걸러낼 수 있어 불필요한 반복문을 제거할 수 있고,
stride
로 짝수만 쉽게 생성해주면 가독성과 효율성을 동시에 높여주는 것 같다는 생각이 들었다.
그리고 reduce
를 통해 합계를 간결하게 구할 수 있었다.
삼항 연산자를 활용해 조건별 로직이 잘 드러날 수 있게 고차 함수와 적절히 조합해본 도전이었다.
이런 방식으로 문제를 작게 나눠 간결하게 만든 뒤 해결하는 방법과
Swift 고차 함수의 활용성이 정말 무궁무진하다라고 생각하며 푼 것 같다.
앞으로도 다양한 문제를 효율적으로 플고 싶은 욕심이 생기기도 했고,,
가독성 높은 코드를 작성하는 데 주력해야겠다고 다짐도 해보는 시간이었달까
와 50번째 틸,,,
진짜 살면서 처음 하는 작업을
이렇게 바로 유지할 수 잇다니 멋져요