Water Bottles
문제 설명
보시는 바와 같이 콜라병 교환문제다.
1.numBottles
(병의 개수) 와numExchange
(몇병당 1병 교환해주는지)가 주어진다.
2. 먹고 교환하고를 반복했을 때 최종적으로 마실 수 있는 병의 개수를 구하라
문제 풀이
%
,/
를 사용하면서 종료조건만 잘 갖춰지면 while문으로 쉽게 풀 수 있을 것 같았다.- 한바퀴를 돌 때마다 병을 한사이클 돌린다고 생각하면은 비교적 쉽게 접근이 가능하다.
- 그래서 이번엔 종료조건을
numBottles >= numExchange
로 잡았다.- 교환 + 교환하고난 나머지로 numBottles를 계속 최신화 해주기 때문에 가능하다.
최종 코드
class Solution {
func numWaterBottles(_ numBottles: Int, _ numExchange: Int) -> Int {
// 교환값으로 나눠준 나머지값
var answer = numBottles
var numBottles = numBottles
while numBottles >= numExchange { // 병 소진 전까지
let rest = numBottles % numExchange
let exchangableBottles = numBottles / numExchange
numBottles = rest + exchangableBottles
answer += exchangableBottles
}
return answer
}
}
RunTime코드는 내거랑 같은게 나와서 이번엔 Memory로 점검을 해봤다.
타인의 코드
class Solution {
func numWaterBottles(_ numBottles: Int, _ numExchange: Int) -> Int {
var filledBottles = numBottles
var drankBottles = 0
var emptyBottles = 0
while filledBottles > 0 {
drankBottles += filledBottles
emptyBottles += filledBottles
filledBottles = emptyBottles / numExchange
emptyBottles %= numExchange
}
return drankBottles
}
}
코드 자체는 거의 동일했지만, 메모리 사용에서 차이가 발생한건 반복문에서
let
으로 새로운 변수를 계속 생성했기 때문이었다. 기존의 var을 활용해 값을 갱신해 주는 것이 메모리 측면에서 더 효율적이라는 것을 알게 되는 계기가 되었다.
근데 그러다 좀 알게된게 Swift에서는ARC(Automatic Reference Counting)
덕분에 좀 미미한 차이가 있다고 한다
ARC 자동참조 카운팅
_Swift는 앱의 메모리 사용량을 추적하고 관리하기 위해 자동 참조 카운팅 (Automatic Reference Counting) (ARC)를 사용합니다. 대부분의 경우에 Swift에서 메모리 관리는 "그냥 수행하라" 를 의미하고 메모리 관리에 대해서 생각할 필요가 없습니다. ARC는 인스턴스가 더이상 필요치 않을 때 자동으로 클래스 인스턴스에 의해 사용된 메모리를 할당 해제 합니다.
더 자세히 말을해보면,
클래스의 새로운 인스턴스가 생성될 때마다 ARC는 메모리 청크에 이 정보를 할당하는데, 참조가 존재하지 않게 되면 알아서 할당해제를 해버린다는 것이다. 반대로 하나라도 참조가 존재하면 인스턴스는 언제사용될지몰라서 할당을 해제하지 않기때문에, 메모리 누수가 생기지 않게 잘 파악하는것도 중요하다는 것이다.(이 부분을 강한 참조)라고 한다.
ARC 원본문서 좀 더 시각 자료가 많다