-
Deep dive!!
[Swift] enum에서 사용되는 CaseIterable, RawRepresentable protocol 깊게 탐구하기!!
안녕하세요. 오늘은 enum에서 enum type의 모든 case를 Collect해서 배열로 반환할 수 있는 protocol인 CaseIterable을 소개하려고 합니다. 그리고 RawRepresentable도 소개하려고 합니다. Enum 타입으로 case에 rawValue, associated value 뿐 아니라 더 다양하게 활용할 수 있는 protocol이 제공되는 Swift가 정말 좋다고 느껴집니다: ) CaseIterable Protocol CaseIterable은 protocol입니다. Protocol 장점은 상속이 되지 않는 값 타입 자료형인 Enum에 여러 개의 protocol을 채택할 수 있습니다. allCases의 타입은 Self.AllCases입니다. 이는 Collection을 준수하..
-
Deep dive!!
[Swift] OOP. ObjectOrientedProgramming의 객체 설계 파해치기!!! | struct vs class | Class 설계 탐구하기 +_+
안녕하세요! 오랜만에 OOP를 공부하면서 캡슐화, 상속, class vs struct, 다형성, Composition(조합)등의 잠시 잊고 있었던 개념을 머릿속으로 불러오게 되었습니다. 바이시클 카드, 포커 카드 등 다양한 카드의 parent가 될 수 있는 Card클래스를 구현해봤습니다.ObjectiOrientedProgramming간략하게 OOP(ObjectOrientedProgramming)를 소개하자면 객체라는 기본 단위를 모델링하고 이를 다양한 곳에서 원하는 목적에 맞게 상속받아서 사용하는 것입니다. 모델링이라는 개념은 현실 세계의 개념을 추상화해서 우리가 개발하는 xcode에서 swift 언어로 클래스와 프로퍼티가 있는 객체를 만드는 과정을 의미합니다. (관련 DB 개념 정리 링크) cf. 참고..
-
Deep dive!!
[Swift] private(set) var vs computed property | Read-Only 프로퍼티는 왜 사용할까?
private(set) vs computed property(연산 프로퍼티). 우선 read-only에 대해서..Read-Only property란?외부에서 임의대로 값을 변경하지 못하게 클래스나 구조체 내부 변수를 보호할 수 있습니다. Concurrent한 환경에서 concurrecy problems이 발생되지 않음으로 안정합니다. 외부에서 클래스 내부의 read-only 변수의 값은 직접 접근해서 변경할 수 없지만 읽기는 가능하다는 뜻입니다.private(set) var vs computed propertyclass Card { // MARK: - Properties private let _number: Number private let _shape: Shape private var _appe..
-
Error & Issue
[iOS/UIKit] UIStackView에 containerView를 추가했는데 containerView의 subview만 보여지는 경우 | AutoLayout
안녕하세요. 오늘은 스택뷰에 뷰들을 넣어서 side menu를 쉽게 구현하려고 개발을 하던 도중에 stackView안에 있는 4개의 container view는 사라지고 container의 subviews만 stackview에 추가됬던 이슈와 해결했던 경험을 글로 기록하려고 합니다. stackview에 추가될 제 컨테이너 뷰들은 Icon과Label을 가지고 있는 뷰 입니다. 그래서 이렇게 4개 선언했고 요기에 addArrangedSubviews로 넣어서 stackView를 구성했습니다. (subviews 레이아웃 지정 안해도 되니 정말 편하다고 느꼈습니다. 문제의 시작은 각각의 containerView(type: IconAndLabelView)에 tap gesture를 선언했을 때 이 stackview의..
-
Deep dive!!
[Swift] 프로토콜 선언시 발생할 수 있는 경고창 Class Delegate Protocol Violation
델리게이트 사용하기 위해 프로토콜을 선언하고 있었는데 Class Delegate Protocol Violation 경고가 나타났습니다. ( swiftLint 적용중입니다.) Delegate 로 설계된 protocol이 클래스 전용으로 선언되지 않았기 때문입니다.. Delegate는 일반적으로 사용하는 쪽에서 옵셔널 타입으로 선언합니다. 그 이유는 약한 참조로 선언해야 delegate가 메모리에서 해제될 때 더 이상 호출되지 않도록 할 수 있기 때문입니다. 서로가 강한 참조를 갖고 있다면 retain cycle이 발생될 수 있습니다. 이렇게 될 경우 한쪽에서만 해제가 된다해도 다른쪽에서 참조를 하고 있기 때문에 메모리에 계속해서 불필요한 인스턴스가 할당되어 있습니다. 이는 memory leak를 발생시킵니..
-
Deep dive!!
[Swift] 스위프트로 백준 편하게 시작하기 | 코딩테스트 준비 | readLine() | split(separator:) | map() 탐구
안녕하세요. 이번 글은 Swift로 백준 사이트에서 알고리즘 문제의 입력을 받는 방법에 대해서 소개하려고 합니다. 백준 사이트를 처음 접한 후 어느 문제를 봤을 때, 알고리즘으로 어떻게 풀 지 생각이 떠오르는 것 같은데 입력을 어떻게 받을지 정말 몰랐습니다.C나 C++은 입력받는 다양한 방법을 문법 공부 하자마자 배웠는데.. Swift는 앱 만들때 입력도 텍스트 필드로 받은 기억만 있었습니다. UIKit 컴포넌트 백준 제출 사이트에 추가할 수도 없고,,,, 다른 블로그의 글을 봤을 때, 엄청 낯선 함수들이 많았습니다. readLine()!.split(separator:"").map{...} // 이게 뭐지,, "UIKit으로 앱 만들 때 이런 함수들 한 번도 안 써봤는데" 하면서 뒷걸음질 쳤던 적도 있었..
-
Combine Framework
[Swift] No7. Deep dive into AnyPublisher and eraseToAnyPublisher( )🤩 | Combine
안녕하세요. 이번 포스트는 Combine 프레임워크를 사용할 때 정말 많이 작성하고 호출했던 타입인 AnyPublisher와 eraseToAnyPublisher에 대해 탐구하려고 합니다. 왜 사용하는지, 어떻게 사용하면 좋을지에 대해 프로젝트를 하며 경험했고 알게 된 개념을 공유하려고 합니다😄. 컴바인 공부할 초기에는 기술 포스트에서 AnyPublisher를 왜 사용하는지, 왜 eraseToAnyPublisher를 사용하는지, 타입을 지워준다는 개념은 정말 잘 알겠는데 그렇게 확 와닿지가 않았었습니다. 그때 당시의 저와 같은 상황인 분들이 이 포스트를 보면서 Publishers의 구체적인 타입을 AnyPublisher로 wrapping하여 추상화하는 이유를 이해하시면 좋을것 같습니다😆 1. AnyPu..
-
Combine Framework
[Swift] MVVM에서 Combine을 활용한 ViewModel Input/Output binding 개념 완벽 부수기 +_+ | MVC와 MVVM 차이 진짜 뿌수기!!!!
안녕하세요! 이번 포스트는 MVVM 패턴을 사용할 때 Conbine framework로 ViewModel과 View를 Input/Output binding하는 방법에 대해 소개하려고 합니다. 뷰에서 발생 가능한 Input!, 그리고 View가 화면을 그려야 할 State!를 ViewModel은 Output!함으로 뷰의 render가 진행됩니다. 소프티어 부트캠프 활동을 하며 새로 배운 개념이 많아 기존의 글을 리빌딩 했습니다.그 전에! MVVM과 MVC 아키텍처 패턴의 차이가 무엇인지 명확하게 알아야합니다. 둘의 차이가 무엇인지 아시는 분들만이 MVVM을 잘 활용한다고 할 수 있습니다. 저는 제 나름대로 MVVM과 MVC 아키텍처의 차이점을 정리해봤습니다(관련 포스트 링크). MVC, MVVM 차이를 이..
-
Combine Framework
[Swift] No6. Transforming operator 개념 완전 뿌수기!! | Combine
안녕하세요! 이번 포스트는 Combine framework에서 publisher 와 subscriber간 subscription의 값을 바꾸는 operator 공부한 내용을 정리하려고 합니다. 주제는 transform 타입의 map, tryMap, flatMap + compactMap(_:) collect, scan. Upstram의 output value가 nil인 경우 대처 가능 한 replaceNil(with:), replaceEmpty(with:). 주의사항!! upstream publihser라는 말을 사용하는데 이는 operator보다 위에 있는 publisher의 흐름을 칭합니다. downstream은 특정 publihser가 값을 방출했을 때 그 하위에 있는 stream 입니다. subsc..
-
Combine Framework
[Swift] No5. Subscription, Cancellable 개념 뿌수기!!! | Combine
안녕하세요. 이번 포스트는 Combine에서 Cancellable과 Subscription에 대해 공부한 개념을 정리하려고 합니다. 1. What is Cancellable and AnyCancellable ? 컴바인 사용할 때 커스텀 subscriber 구현도 하긴 하지만?! 저는 sink(receiveCompletion:receiveValue:), sink(receiveValue:)를 많이 사용합니다. 물론 @Publihsed를 사용할 때 assign(to:on:)도 사용합니다. 이 세 개 operator의 공통적인 특징은 AnyCancellable을 반환하는 것입니다. AnyCancellable은 Cancellable 프로토콜을 채택하는 final class입니다. Cancellable은 cance..
-
Project
[Swift Package] No1. Swift Package 편하게 접근해보기🤩 | #의존성 #Package.swift #ACL
안녕하세요. 오랜만에.. 포스트를 다시 작성하네요. 이번 포스트는 Swift Package에 대해서 탐구해보려고 합니다. A Package의 특정 타겟에서 외부 repository 의존성 추가 및 로컬 library 의존성 추가. Package.swift에 대해 파해치려구 합니다."An Introduction to Swift Package Manager"( kodeco 링크 )글을 활용해서 제가 아는 지식도 정리할 겸... 이게 예전에 올려진 글이라 몇 명령어는 실행이 되지 않을 수 있어서, 제 스타일대로 커스텀을 하며 파해치려구 합니다. 오늘의 키워드!Package.swifttargetLibraryProductDependency[ 주요 개념들 ]약간 개념을 간단하게 정리하겠습니다. 1. Package..
-
Combine Framework
[Swift] No7. Deep dive into AnyPublisher and eraseToAnyPublisher( )🤩 | Combine
안녕하세요. 이번 포스트는 Combine 프레임워크를 사용할 때 정말 많이 작성하고 호출했던 타입인 AnyPublisher와 eraseToAnyPublisher에 대해 탐구하려고 합니다. 왜 사용하는지, 어떻게 사용하면 좋을지에 대해 프로젝트를 하며 경험했고 알게 된 개념을 공유하려고 합니다😄. 컴바인 공부할 초기에는 기술 포스트에서 AnyPublisher를 왜 사용하는지, 왜 eraseToAnyPublisher를 사용하는지, 타입을 지워준다는 개념은 정말 잘 알겠는데 그렇게 확 와닿지가 않았었습니다. 그때 당시의 저와 같은 상황인 분들이 이 포스트를 보면서 Publishers의 구체적인 타입을 AnyPublisher로 wrapping하여 추상화하는 이유를 이해하시면 좋을것 같습니다😆 1. AnyPu..
-
Deep dive!!!
[iOS] ARC의 개념, Class vs Struct 및 Memory Leak발생 이유 탐구하기 | ARC 진짜 뿌수기 #2
안녕하세요. 이번 포스트에서는 ARC의 기본 개념 및 class와 struct의 차이, GC's Mark and Sweep은 왜 메모리 릭을 예방하는지 등의 ARC와의 차이점, memory leack의 발생을 Debug Memory Graph를 통해 탐구하고 해결하는 과정까지 소개하려고 합니다: ]Class vs StructARC를 탐구하기 위해서 Value type, Reference type의 개념을 알아야 합니다. 대표적으로 Struct, Class가 있습니다.Value Type의 Struct 특징!! Potato 구조체가 있습니다. 그리고 thread에 의해 execute()가 호출되어 해당 함수의 scope에 들어왔을 때의 상황입니다. Memory(memory layout link)의 stack..
-
Deep dive!!!
[iOS] Dynamic view를 추가하는 상황에서 layoutIfNeeded() 활용 및 개념 완벽 뿌수기 +_+ | UIView life cycle
안녕하세요. 이번 포스트는 UIView와 AutoLayout이라면 빠질 수 없는 layoutIfNeeded()의 개념과 언제, 왜 사용해야 하는지 등을 정리하려고 합니다. 또한 커스텀 뷰 내부에 특정 subview를 동적으로 추가 후 화면에 render 해야할 때, subview's layoutIfNeeded와 super view's layoutIfNeeded 중 무엇을 호출해야 하는지에 대해 간단한 프로젝트를 통해 다양하게 탐구하며 알게된 개념을 소개하려고 합니다. 기본적으로 main run loop와 update cycle 관련해서 설명하는 해외 포스트(관련 링크)를 우선 꼭 보셔야 좋습니다. 지금부터 버튼을 클릭하면 동적으로 애니메이션과 함께 고양이 사진이 나온 후에 간단한 레이블이 아래로 보여지는..
-
Deep dive!!!
[iOS] CALayer의 mask 프로퍼티와 gradient animation 파해치기!!
안녕하세요. 이번 포스트는 CALayer의 mask와 gradient 주는 방법과 CABasicAnimation으로 애니메이션 처리하는 방법에 대해서 소개하려고 합니다. 이런 느낌으로 말입니다!! 시작하기 전에 프로젝트 링크 참고해주시면 감사합니다.(깃허브 프로젝트 링크 바로 들여다보기) 위와같이 화면을 구성하기 위해 알아야 할 개념은 3가지 입니다. CALayer와 mask CABasicAnimation (keyPath: locations) UIGraphicsImageRenderer(size:) CALayer와 Mask CALayer는 UIView와 같이 아래 사진처럼 계층구조를 가질 수 있습니다. CALayer는 mask란 프로퍼티가 있습니다. 이는 alpha channel을 통해서 layer's c..
-
Deep dive!!!
[iOS] collectionView(_:cellForRowAt:)에서 중복 선언 및 호출되는 로직 간소화 | POP와 OOP, 프로토콜 composition
안녕하세요. 지난 포스트에서는 최근 진행중인 프로젝트에서 재사용 가능한 cell의 UI에서 특정 영역에만 UI가 서로 다른 경우, 하나의 cell에 데이터가 들어올 때마다 데이터에 맞게 레이아웃을 잡는 경우 vs 서로 다른 UI별로 cell을 만드는 경우 중 뭐가 성능상 좋은지 실험(관련 포스트 링크) 후 리빌딩 했었습니다. 이번 포스트에선 지난 포스트에서의 리빌딩 과정 중 collectionView(_:cellForRowAt:) 델리게이트에서 중복 코드가 너무 많이 보여서 프로토콜 지향적 + 객체지향 개념을 활용해 리빌딩한 경험을(리빌딩한 코드 관련 커밋 링크) 소개하려고 합니닷!! 프로젝트 구조 간단 소개 진행중인 프로젝트의 피드 화면입니다. 자세히 보면, 회색 영역은 ui가 같지만 이미지 영역은 서..
Database 이론
-
Database 이론
[Database] 11. 보안과 권한 관리 개념 정리
안녕하세요. CS지식 정리도 할 겸, 학교에서 배운 데이터베이스 개념 + "데이터베이스 개론-IT COOKBOOK" 의 책을 공부하며 알게 된 내용을 정리하려고 합니다. 지난 포스트"트랜잭션과 동시성관련 개념 정리"에 이어 이번 포스트는 데이터베이스에서의 보안과 권한 개념을 정리하려고 합니다. 주관적으로 작성된 글이기에 틀린 내용이 있을 수 있습니다.(댓글로 알려주시면 감사합니다 :) 데이터베이스 보안 데이터베이스는 중요한 정보나 개인정보같은 민감한 정보가 있습니다. 권한 관리를 통해 기밀성이 보호되오야 합니다. 데이터의 정확성과 일관성을 위해 무결성을 유지하는 것도 중요합니다. 데이터베이스 시스템은 항상 사용가능해야 합니다. 외부 공격, 시스템 장애 등등 으로부터 보호됨으로 가용성을 유지해야 합니다. ..
-
Database 이론
[Database]10. 트랜잭션 개념과 회복 기법. 동시성 문제와 수행. 2PL 개념 부수기 +_+ | 직렬 가능성 스케줄
안녕하세요. CS지식 정리도 할 겸, 학교에서 배운 데이터베이스 개념 + "데이터베이스 개론-IT COOKBOOK" 의 책을 공부하며 알게 된 내용을 정리하려고 합니다. 지난 포스트"정규화 개념 정리"에 이어 이번 포스트는 트랜잭션 개념과 회복 기법.Concurrency에서 발생할 수 있는 문제, 제어에 관한 개념. 트랜잭션의 concurrent execution 중 serial schedule과 같은 연산 결과를 보장할 수 있는 직렬 가능성과 로킹, 2단계 로킹 기법에 대해 개념을 정리하려고 합니다. 주관적으로 작성된 글이기에 틀린 내용이 있을 수 있습니다.(댓글로 알려주시면 감사합니다 :) 1. 트랜잭션(Transaction)이란? 데이터베이스에서 수행되는 하나의 논리적인 작업, 연산집합(SQL문들의..
-
Database 이론
[Database] 9. Normalization 정규화 개념 정리 | 정규형(1...BCNF), 함수 종속 개념 완전 뿌수기 +_+
안녕하세요. CS지식 정리도 할 겸, 학교에서 배운 데이터베이스 개념 + "데이터베이스 개론-IT COOKBOOK" 의 책을 공부하며 알게 된 내용을 정리하려고 합니다. 지난 포스트 "데이터베이스 설계 | 요구사항분석, 개념적, 논리적 설계 정리"에 이어 이번에는 데이터베이스의 논리적 설계 중 정규화 과정과 함수 종속에 관한 개념을 정리하려고 합니다. 주관적으로 작성된 글이기에 틀린 내용이 있을 수 있습니다.(댓글로 알려주시면 감사합니다:) 데이터베이스 논리적 설계 과정 중 하나인 정규화는 정말 중요한 작업입니다. E-R D를 Relational Schema로 변환 후에 정규화 과정을 거쳐야 데이터베이스의 데이터는 중복성이 줄어들고 일관성, 무결성 등이 향상되게 됩니다. "정규화 과정은 왜 거치는 것일까..
-
Database 이론
[Database] 8. 데이터베이스 설계 | 요구사항분석, 개념적, 논리적, 물리적 설계 개념 정리
안녕하세요. CS지식 정리도 할 겸, 학교에서 배운 데이터베이스 개념 + "데이터베이스 개론-IT COOKBOOK" 의 내용을 정리할 것입니다. 지난 포스트 "Database의 View에 관한 개념"에 이어 이번에는 데이터베이스의 설계( 요구사항 분석 -> 개념적 -> 논리적 -> 물리적 설계에 관한 개념을 정리하려고 합니다. 데이터베이스 설계 Db에서 원하는 데이터를 얻기 위해서는 특정 테이블이 필요합니다. 테이블의 열은 PK, FK, 후보키 등 다양한 속성으로 정의되어 있습니다. FK를 통해 다른 테이블의 PK와 연결됩니다. 이런 테이블의 속성들은 relational schema를 기반으로 만들어집니다. relational schema는 Entity-Relationship model로부터 정의됩니다..
-
구현
[백준/Swift] 16917: 양념 반 후라이드 반 | PS일지
문제 간단한 문제 요약 치킨은 양념 치킨, 후라이드 치킨, 반반 치킨 세 종류를 판매한다. 각각 A원, B원, C원이다. 파티를 위해 양념취킨 최소 X마리, 후라이드 치킨 최소 Y마리 구매해야한다. 반반 치킨 두마리를 구입하면 양념치킨 하나, 후라이드 치킨 하나를 만들 수 있다. 치킨을 구매하는 금액의 최소값을 구하자. 고려해야 할 사항 최소한으로 양념 X마리, 후라이드 Y마리를 구매해야 한다. X, Y를 구매할 수 있는 최소 가격을 찾어야한다. 문제 풀이, 했갈렸던 점 대박.. 접근 방법은 크게 두가지 였습니다. 첫째는 후라이드 X마리 + 양념 Y마리 구매하는 경우 두번째는 최소 X, Y중 작은 값 만큼 반반 * 2로 구매한 가격 + 남은 치킨 * 해당 치킨 가격 만큼 구매한 가격 이 두가지 중 비교를..
-
String
[백준/Swift] 모음의 개수: 1264 | PS일지
문제 간단한 문제 요약 영문 입력 받았을 때 모음 "a,e,i,o,u" 개수를 세시오!!!!!!!! 고려해야 할 사항 # 입력 받을 시 종료! 코드 while let input = readLine(), input != "#" { print( input .lowercased() .filter { "aeiou".map { String($0) }.contains(String($0)) }.count) }
-
BruteForce
[백준/Swift] 사탕 게임: 3085 | PS일지
문제 간단한 문제 요약 N*N 크기의 상자에 사탕을 채워 놓는다. 사탕색이 모두 같지 않을 수 있다. 상자 안 사탕의 색이 다른 인접한 두 칸을 골라 서로 교환한다. 모두 같은 색으로 이루어져 있는 가장 긴 연속 부분(행, 열)을 고른 다음 그 사탕을 모두 먹을 때, 그 최대 개수를 구하시오. 문제 풀이, 했갈렸던 점 맨 처음에 문제를 읽으면서 사탕 안 색이 다른 인접한 두 칸을 골라 서로 교환하는데.. "언제까지 이걸 교환하지?"라는 생각에 문제의 의도와는 다른 방향으로 생각을 계속 했었습니다... 말 그대로 정말 심플하게 사탕안에 색이 다르면서 인접한 두 칸을 골라 서로 교환하면 됩니다. 그리고 나서 모든 행. 모든 열을 탐색 후 가장 긴 연속 부분을 찾으면 됩니다. 또 하나 문제를 풀면서, 열 우선..
-
Greedy
[백준/Swift] 2217: 로프 | PS일지 | enumerated().map()에 관해..
문제 간단한 문제 요약 여러 개의 로프가 있다. 로프를 통해 물체를 들어올리는데 각각의 로프마다 중량이 있고, 병렬로 로프들을 연결할 수 있다. 그 대신 w/k 로 해서 로프들의 중량이 일치하도록 해야 병렬적으로 로프를 물체에 묶어 들어올릴 수 있다. 문제 풀이 정말 어려운 그리디.. 어떻게 풀어야 할지 곰곰이 생각해봤습니다. 1 2 4 7 10 의 로프가 있을 때, "어떻게 최대한의 무게를 들 수 있을것인가?..." 이때 든 의문점은 중량 1의 로프와 중량 10의 로프를 같이 사용해서 물체를 올린다면 (10 + 1) / 2 = 5? 최대한으로 5씩 중량을 나눠서 들 수 있는데, 최대 중량 1짜리가 5를 들 수 있을까? 그럴 수 없을 것 같아서 내린 결론은 1로프와 10 로프를 같이 병렬적으로 사용할 땐..
-
Greedy
[백준/Swift] 1789: 수들의 합 | PS일지
문제 간단한 문제 요약 서로 다른 N 개의 자연수의 합이 S일 때, 자연수 N의 최대 값은 얼마일까? 문제 풀이 최대한 많이 서로 다른 자연수를 더해주어 S를 만들어야 합니다. 가장 작은 자연수 1부터 더해가는게 최대한 많은 서로다른 N개의 자연수를 사용할 수 있습니다. 이때 이전 자연수들의 덧셈 + 특정 자연수를 더한 값이 S라면, 서로 다른 자연수는 특정 자연수 개수만큼 존재합니다. 예를들어 S = 3이고 자연수의 덧셈이 1부터 시작한다면, 1. 1+2 = 3 답은 2입니다. 만약 특정 자연수의 덧셈이 S를 초과한다면, 초과한 값 - S를 한 자연수만 빼면 됩니다. 그럼으로 특정 자연수 -1이 답입니다. 예를들어 S = 5이고, 자연수의 덧셈은 1부터 시작합니다. 1 + 2 = 3 3 + 3 = 6..
-
String
[백준/Swift] 1302: 베스트셀러 | PS일지
문제 1302번: 베스트셀러 첫째 줄에 오늘 하루 동안 팔린 책의 개수 N이 주어진다. 이 값은 1,000보다 작거나 같은 자연수이다. 둘째부터 N개의 줄에 책의 제목이 입력으로 들어온다. 책의 제목의 길이는 50보다 작거나 같고 www.acmicpc.net 간단한 문제 요약 오늘 하루 동안 팔린 책의 제목이 입력으로 들어왔을 때, 가장 많이 팔린 책의 제목을 출력하는 프로그램을 작성하시오. 고려해야 할 사항 책은 가장(최대) 많이 팔린 책의 이름이 출력되야 하는데, 가장 많이 팔린 책의 개수가 같다면, 사전순(최소)으로 가장 앞서는 제목 출력해야 합니다. 문제 풀이, 새로 배운 개념 팔린 책들 중 이름이 같은 책이 있기에, 배열로 저장하기 보단 딕셔너리로 저장했습니다. 그리고 max함수를 통해, val..