function solution(numbers) {
var answer = -1;
const MAX_NUM = 9;
let sum = 0;
for (let i = 0 ; i <= MAX_NUM; i++) {
sum += i;
}
let numbers_sum = numbers.reduce((total, current) => total + current, 0);
answer = sum - numbers_sum;
return answer;
}
풀이 과정
1. 문제에서 요구사항을 보고 reduce 함수를 사용 하면 될 것 같았다. reduce 함수로 들어온 배열의 모든값을 더하고,
0 ~ 9 까지의 합에서 해당 값을 빼면 된다고 생각했다!
너무 간단한 문제지만 고차 함수인 reduce 를 모르면 코드가 훨씬 길어졌을 것이다.
개발할때는 항상 모든 상황에 대한 경우의 수를 생각해야 한다고 했다. 간단하게 0~9 까지의 더한 값을 바로 사용하면 코드가 더 간결해 지겠지만...
숫자의 범위가 9 까지가 아니고, 10 , 100, 4000.. 등등 범위값이 달라지면 해당 코드를 다시 작성해야 하는 것 이 아닌, MAX_NUM 상수의 값만 변경하면 바로 적용되도록 코드를 작성 하였다!
The frame rectangle, which describes the view’s location and size in its superview’s coordinate system.
-> 슈퍼뷰 를 기준으로 위치 및 크기를 정의
강조한 부분을 잘 기억해야한다! 기준점이 자신보다 한단계 위의 뷰인 슈퍼뷰 이다!
var frame: CGRect { get set }
2) Bounds
The bounds rectangle describing the item’s location and size in its own coordinate system.
-> 자기 자신을 기준으로 위치 및 크기를 정의
강조한 부분을 잘 보자! 기준점이 자기 자신이다!
var bounds: CGRect { get }
💡CGRect는 직사각형의 위치와 치수를 포함하는 구조체 이며, 해당 구조는
public struct CGRect {
public var origin: CGPoint
// 위치 정보
public var size: CGSize
// 크기 정보
public init()
public init(origin: CGPoint, size: CGSize)
}
/*
...
...
...
기타 확장 기능들이 구현되어 있음
*/
로 정의되어 있습니다.. 이부분은 Code로 앱을 구현할때 사용하게 되는데
제가 아직 스토리보드 밖에 다룰줄을 몰라서.. 알게되면 포스팅 하겠슴다ㅎㅎ..
다시 본론으로 돌아가서
자! 공식문서만 봐도 차이점을 바로 알아버렸다 ^_-
간단하게 차이점을 이야기 하자면..
Frame 은 기준점이 슈퍼뷰에서부터 위치 및 크기를 지정하게 되는 반면,
Bounds 는 기준점이 자기 자신으로부터 위치 및 크기를 지정하게 된다!
로 끝내기엔 뭔가.. 이해가 되지 않으니 예시로 살펴 봐야겠다..
예시로 살펴보기
1. 먼저 frame 이다, 분홍색(빨간색) View가 superview고, 파란색 뷰가 frame을 적용한 뷰이다,
코드 를 살펴보자
class ViewController: UIViewController {
@IBOutlet var superView: UIView!
var view1 = UIView()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
view1.frame = CGRect(origin: CGPoint(x: 50, y: 50), size: CGSize(width: 300, height: 300))
view1.backgroundColor = .blue
superView.addSubview(view1)
superView.backgroundColor = .systemPink
}
}
위치 정보를 (50.50) 으로 주었고, 크기 정보를 (300 * 300) 으로 설정했다.
우리는 위에서 슈퍼뷰기준 으로 위치와 크기를 나타낸다고 배웠다
각 수치값을 표현다면 위와 같이 될것이다
분홍배경의 슈퍼뷰 로 부터 50.50 만큼 떨어진 거리에 300 * 300 크기의 뷰를 그려준것이다.
2. Bounds 를 살펴보자!
배경에 대한 설명은 같고, 위 코드에서 frame 을 bounds로 변경하여 적용하였다!
@IBOutlet var superView: UIView!
var view1 = UIView()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
view1.bounds = CGRect(origin: CGPoint(x: 50, y: 50), size: CGSize(width: 300, height: 300))
view1.backgroundColor = .blue
superView.addSubview(view1)
superView.backgroundColor = .systemPink
}
뭔가 이상하다..
frame 같은 경우는 어쩌면 자연스럽게 저렇게 되는구나 를 알수있는데
bounds 는 당최 어떻게 동작하는지를 모르겠다..
300 * 300 크기의 뷰를 (50.50) 위치에 놓았는데 어쩐지 왼쪽상단으로 쭈욱.. 올라갔다
기준점이 자기 자신 이란건 알겠는데 왜 저렇게 되는걸까?
이해하기가 좀 어려워서 zeddios 님의 블로그를 열심히 읽어 보았다!
그림하나로 저렇게 되는 이유가 종결된다!
정리하자면 bounds를 변경하는 것은, 변경된(설정된) 위치에서 내 자신의 View 를 다시 그려줘! 라고 하는것이다!
ARC는 메모리를 스스로 관리하는 기능을 수행한다 일반적으로 Swift가 자동으로 ARC를 이용해 메모리를 관리하기 때문에 사용자는 메모리는 어떻게 처리해야하는지 깊게 생각할 필요는 없다고.. (공식문서에 써있다..)
💡 Objective-C 에서는 MRC 라고 하는 수동 메모리 관리 기법을 사용하였다, Objective-C 에서는 수동으로 관리해야 하기 때문에 retain / release 를 사용해 사용수의 증가/감소 를 확인하여 메모리를 관리하였는데 ARC 로 넘어오면서 이걸 자동으로 해준다! 그래서 프로그래머는 더이상 메모리관리에 관한 코드를 따로 작성하지 않아도 된다!
그래서 ARC 어떻게 동작하는데?
Class 의 인스턴스가 생성될때마다, ARC는 해당 인스턴스에 대한 정보를 저장하는 Memory 할당하게 된다!
이 메모리는 당연히 인스턴스의 method, property 의 값 등의 정보를 가지고있다!
그리고 해당 인스턴스가 더이상 필요가 없어지면 해당 메모리를 확보하여 다른 목적으로 사용가능케한다!!
그러니까.. 한마디로 요약하면 “ Class가 필요 없어지면 해당 메모리를 해제함 “
그럼.. Class가 필요한지 필요없는지 어떻게 판단하게될까..? 이름에서 유추할수 있다!
해당 Class의 인스턴스가 참조되고 있는 수를 세어 가지고 있다!
이 수를 세기위해 클래스 인스턴스를 할당할 때마다 강력한(Strong) 참조를 하게되며, 이 강력한 참조가 유지되는 동안은 할당 해제를 허용하지 않게된다!
백문이 불여일견 직접 예시로 살펴보자
class OS {
let kind: String
// 초기화
init(kind: String) {
self.kind = kind
print("[인스턴스 생성] 현재 운영체제는 \\(kind)")
}
// 소멸자
deinit {
print("[인스턴스 할당 해제] \\(kind) 운영체제 종료")
}
}
일단.. Class를 맹글어 주고..
var os1: OS?
var os2: OS?
var os3: OS?
이렇게 하면 인스턴스가 생성이!!!!
안됩니다.
예 안돼요..
Optional 로 선언되어 있어서 기본적으로 nil 값이 할당되기 때문에 class 인스턴스를 할당하지 않아요!
os1 = OS(kind: "MacOS")
// [인스턴스 생성] 현재 운영체제는 MacOS
이제야 비로소 인스턴스가 할당되었습니다! 그러면 ARC에 의해 강한 참조로 os1 변수가 counting 될거에요!
/*
문제
양수 A가 N의 진짜 약수가 되려면, N이 A의 배수이고, A가 1과 N이 아니어야 한다. 어떤 수 N의 진짜 약수가 모두 주어질 때, N을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 N의 진짜 약수의 개수가 주어진다. 이 개수는 50보다 작거나 같은 자연수이다. 둘째 줄에는 N의 진짜 약수가 주어진다. 1,000,000보다 작거나 같고, 2보다 크거나 같은 자연수이고, 중복되지 않는다.
출력
첫째 줄에 N을 출력한다. N은 항상 32비트 부호있는 정수로 표현할 수 있다.
*/
import Foundation
let inputCount = readLine().map{Int($0)!}!
var inputNum = readLine()!.components(separatedBy: " ").map{Int($0)!}
if inputCount == 1 {
print(inputNum[0]*inputNum[0])
} else {
let even = (inputNum.count / 2)
inputNum = inputNum.sorted()
if inputNum.count % 2 == 0 {
print(inputNum[even] * inputNum[even - 1])
} else {
print(inputNum[even - 1] * inputNum[even + 1])
}
}
알고리즘 문제를 많이 풀어봐야 겠다고 느낀 문제..
문제를 보고 무슨뜻인지 잘 이해가 안되서 한참을 쳐다봤다 ㅋㅋㅋ
해당 풀이 방법은 이렇게 수행된다
1. 약수의 갯수가 1개이면 고민할 필요도 없이 해당 값을 제곱하여 출력하면 된다
2. 약수의 갯수가 2개 이상이라면 입력받은 배열을 정렬하고,[ 갯수 / 2 ] 를 하여 배열의 중간값위치를 구한다!
3. 약수의 갯수가 짝수 라면 중간값의 계산한 [ 인덱스의 값 * 이전 인덱스의 값 ] 을 하여 구한다!
4. 약수의 갯수가 홀수 라면 중간인덱스의 [ 이전 값 * 이후 값 ] 을 수행하여 구한다!
/*
문제
2와 5로 나누어 떨어지지 않는 정수 n(1 ≤ n ≤ 10000)가 주어졌을 때, 1로만 이루어진 n의 배수를 찾는 프로그램을 작성하시오.
입력
입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스는 한 줄로 이루어져 있고, n이 주어진다.
출력
1로 이루어진 n의 배수 중 가장 작은 수의 자리수를 출력한다.
*/
import Foundation
//while let input = readLine() {
// var one = "1"
// while Int(one)! % Int(input)! != 0 {
// print(one)
// one.append("1")
// }
// print(one.count)
//}
while let input = readLine() {
var one = 1
var count = 1
while one % Int(input)! != 0 {
one = one * 10 + 1
one %= Int(input)!
count += 1
}
print(count)
}
단순히 문자열에 "1" 을 추가하고, 해당 문자열의 길이를 출력하는 방법으로 풀었으나 Runtime 오류가 발생했다.
실행 할때마다 결과값이 잘 나와서 왜 안되는지 한잘 머리를 굴렸다.. ( 주석처리한 부분! )