opendoor_life

'개발자의 성장일기'가 되었으면 좋겠습니다만?

Dev/Algorithm

Swift Algorithm :: 백준 10998번 AxB 알고리즘 풀이 (+ TIL, Today I Learned)

opendoorlife 2021. 1. 6. 18:36
반응형

문제
두 정수 A와 B를 입력받은 다음, A×B를 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 A와 B가 주어진다. (0 < A, B < 10)

출력
첫째 줄에 A와 B가 주어진다. (0 < A, B < 10)

 

Solution 1

- 시간 : 8 ms

- 메모리 : 62,172 KB

- 코드길이 : 72 B

print((readLine()?.split(separator: " ").map{ Int($0)! }.reduce(1, *))!)

 

Solution 2

- 시간 : 8 ms

- 메모리 : 62,172 KB

- 코드길이 : 78 B (코드는 좀 더 길어졌지만 보다 직관적이다)

print((readLine()?.split(separator: " ").map{ Int($0)! }.reduce(1){$0 * $1})!)

 


 𝐓𝐨𝐝𝐚𝐲 𝐈 𝐋𝐞𝐚𝐫𝐧𝐞𝐝 

1. 트레일링 클로저(Trailing Closure)

- 공식문서 docs.swift.org/swift-book/LanguageGuide/Closures.html

- 트레일링 클로저는 함수의 마지막 인자값이 클로저일 때, 이를 인자값 형식으로 작성(Solution1)하는 대신 함수의 뒤에 꼬리처럼(Solution2) 붙일 수 있는 문법을 의미한다.

- 인자값이 하나일 때는 마지막 인자값 뿐만 아니라 인자값을 넣어주기 위한 괄호 부분도 생략이 가능하다.

 

Solution2의 Reduce function이 트레일링 클로저(Trailing Closure) 문법으로 쓰였는데, reduce(_:_:)의 정의를 들여다보면, 마지막 인자값(nextPartialResult) 이 클로저 형태이기 때문에 가능했다.

↗︎ reduce(_:_:)

- Generic Instance Method :: Returns the result of combining the elements of the sequence using the given closure.

- 주어진 클로져를 사용해 시퀀스의 요소들을 합친 결과를 반환한다.

- Complexity: O(n), where n is the length of the sequence.

 

Declaration

func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result

 

Discussion

1) 클로저(Closure)

let numbers = [1, 2, 3, 4]
let numberSum = numbers.reduce(0, { x, y in
    x + y
})
// numberSum == 10

 

2) 연산자 함수 (Operator Functions) 이용

클로저 표현식보다 더 간결하게 표현할 수 있는 방법. 연산자만을 사용하여 의미하는 바를 정확히 나타낼 수 있을 때 사용된다.

let numbers = [1, 2, 3, 4]
let numberSum = numbers.reduce(0, +)
// numberSum == 10

 

3) 트레일링 클로저(Trailing Closure)

마지막 인자값이 클로저 표현일 때, 함수의 코드블럭 밖으로 꺼내 꼬리처럼 붙일 수 있다.

// 1
let numbers = [1, 2, 3, 4]
let numberSum = numbers.reduce(0){ x, y in x + y }

// 2
let numbers = [1, 2, 3, 4]
let numberSum = numbers.reduce(0){ $0 + $1 }

 

2. Closure 클로저의 축약 과정

- 1000번 문제의 Review 섹션에서 map(_:)으로 다루긴 했는데 reduce(_:_:)로 한 번 더 정리! 

 

start

let numbers = [1,2,3,4]
let numberSum = numbers.reduce(0, {
  (result: Int, element: Int) -> Int in
  return result + element
})

 

step.1 반환 값의 타입 생략 (컴파일러가 추론)

let numbers = [1,2,3,4]
let numberSum = numbers.reduce(0, {
  (result: Int, element: Int) /*-> Int*/ in
  return result + element
})

 

step.2 매개변수 타입 생략 (컴파일러가 추론) + 매개변수 괄호 생략

let numbers = [1,2,3,4]
let numberSum = numbers.reduce(0, {
  /*(*/result/*: Int*/, element/*: Int) -> Int*/ in
return result + element
})

 

step.3 매개변수 생략, 내부 상수 이용 (인자값의 순서대로 $0, $1) + 실행구문(in)생략

let numbers = [1,2,3,4]
let numberSum = numbers.reduce(0, {
  /*(result: Int, element: Int) -> Int in*/
return $0 + $1
})

 

step.4 return 구문 생략 (컴파일러 추론)

let numbers = [1,2,3,4]
let numberSum = numbers.reduce(0, {
  /*(result: Int, element: Int) -> Int in*/
  /*return*/ $0 + $1
})

 

final

let numberSum = numbers.reduce(0, { $0 + $1 })
반응형