BOJ 14658. 하늘에서 별똥별이 빗발친다

문제 https://www.acmicpc.net/problem/14658 풀이 우선 최악의 경우를 생각해보자. N, M이 각각 500,000 이고, L은 1, K가 100일 때가 최악인 경우가 된다. 이 상태에서 모든 경우의 수를 확인하려면 별의 위치를 250,000,000,000,000번 확인해야 한다. 따라서 모든 경우의 수를 판단하는건 불가능 하다. 따라서 트램펄린을 설치할 위치를 합리적으로 정해야 한다. 주어진 조건을 보면 별이 최대 100개 까지밖에 없으므로 이를 활용하여 생각해본다. 우선 별 하나를 기준으로 보면 L * L 크기의 트램펄린이고, 별이 최대 100개 있으므로 확인해야 할 위치는 최악의 경우에 100,000,000,000,000개 이다. 사실상 위의 경우와 다를바가 없으므로 불가능하다. ...

April 7, 2024

BOJ 10159. 저울

문제 https://www.acmicpc.net/problem/10159 풀이 노드간의 연결 여부를 따지는 따지는 문제이므로 처음에는 단순히 Union-Find Set을 사용하면 될 줄 알았다. 하지만 물건 A와 B의 관계가 있을 때 가능한 경우의 수는 ‘A가 B보다 무겁다’ 혹은 ‘B가 A보다 무겁다’ 두 가지의 경우가 있으므로 방향 그래프 가 된다. 따라서 Union-Find Set을 사용하는 것 보다는 방향 그래프에서도 적용 가능한 알고리즘을 사용해야 한다. (아래의 코드에서 엣지의 방향은 무거운 쪽에서 가벼운 쪽으로 했으며. 반대로 해도 상관 없다.) 문제에서 각 물건에 따라서 그 물건과의 비교 결과를 알 수 없는 물건의 개수를 출력하라고 했기 때문에, 노드에서 다른 노드로 가는 모든 경우의 수를 알아야 한다. 따라서 다익스트라 알고리즘을 n번 쓰거나 플로이드-워셜 알고리즘을 한 번만 쓰면 된다. ...

April 7, 2024

Combine. Combine in Practice - WWDC19

A unified, declarative API for processing values over time Combine에서는 값이 시간의 흐름에 따라 전달되는 과정을 Publisher로 표현하고, 여러 연산자를 연결해 데이터가 변환되는 흐름을 선언적으로 작성한다. 아래 예제에서는 Notification으로 전달된 Data를 MagicTrick으로 디코딩한다. let trickNamePublisher = NotificationCenter.default.publisher(for: .newTrickDownloaded) .map { notification in return notification.userInfo?["data"] as! Data } // Output: Data, Failure: Never .tryMap { data in let decoder = JSONDecoder() try decoder.decode(MagicTrick.self, from: data) } // Output: MagicTrick, Failure: Error decode 연산자를 사용하면 위 변환을 다음과 같이 줄여서 작성할 수 있다. let trickNamePublisher = NotificationCenter.default.publisher(for: .newTrickDownloaded) .map { notification in return notification.userInfo?["data"] as! Data } // Output: Data, Failure: Never .decode(MagicTrick.self, JSONDecoder()) // Output: MagicTrick, Failure: Error Error Handling 모든 Publisher는 자신이 발생시킬 수 있는 실패의 종류를 명확하게 정의한다. 실패가 발생하지 않거나 이미 처리된 경우에는 Never를 Failure 타입으로 사용한다. Combine은 실패를 감지하고 복구할 수 있는 다양한 연산자를 제공한다. Combine의 Publisher는 전달하는 값의 타입인 Output과 실패할 때 전달하는 오류의 타입인 Failure를 함께 가진다. 두 타입이 연산자를 거치며 어떻게 바뀌는지 확인하면 데이터 흐름과 오류 흐름을 함께 추적할 수 있다. ...

March 18, 2024

Combine. Introducing Combine - WWDC19

Combine Customize handling of asynchronous events by combining event-processing operators. 결합된 이벤트 처리 연산자를 이용하여 비동기 이벤트 처리를 커스터마이즈 하는 방법 Combine은 데이터 흐름을 간편하게 처리하고 비동기 이벤트를 관리하기 위한 프레임워크다. 다양한 소스에서 발생하는 이벤트를 같은 방식으로 다루고, 이벤트 사이의 상호작용을 연산자로 조합할 수 있다. 특징 Generic: 제네릭을 사용해 다양한 타입의 데이터 흐름을 표현한다. Type safe: Publisher의 출력 타입과 실패 타입을 컴파일 타임에 확인한다. Composition first: 작은 Publisher와 연산자를 조합해 더 큰 흐름을 만든다. Request driven: Subscriber가 필요한 만큼의 값을 요청하는 방식으로 흐름을 제어한다. 핵심 개념 Publisher 값과 에러가 어떻게 생성되는지를 정의한다. ...

March 17, 2024

Network. 네트워크 기기

네트워크 기기의 처리 범위 네트워크 장비는 주로 어떤 계층의 정보를 보고 전달 여부를 결정하는지에 따라 구분한다. 실제 장비는 여러 계층의 기능을 함께 제공할 수 있으므로 아래 구분은 대표적인 처리 기준이다. 애플리케이션 계층: L7 스위치 인터넷 계층: 라우터, L3 스위치 데이터 링크 계층: L2 스위치, 브리지 데이터 링크·물리 계층: NIC, 무선 AP 물리 계층: 리피터 애플리케이션 계층을 처리하는 기기 애플리케이션 계층의 정보를 기반으로 트래픽을 처리하는 장비 L7스위치(로드 밸런서) HTTP 헤더, URL 경로, 쿠키처럼 애플리케이션 계층의 정보를 읽어 요청을 적절한 백엔드 서버로 분산하는 장비 또는 소프트웨어 ...

March 14, 2024

Network. HTTP(HyperText Transfer Protocol)

HTTP HTTP: HyperText Transfer Protocol HTTP는 웹에서 클라이언트와 서버가 데이터를 주고받기 위한 애플리케이션 계층 프로토콜이다. 클라이언트가 요청(Request)을 보내면 서버가 응답(Response)을 반환하는 Request-Response 방식으로 동작한다. 동작 방식 Client ↓ HTTP Request Server ↓ HTTP Response Client 특징 Request-Response 방식으로 동작한다. Stateless를 기본으로 한다. HTTP/1.x와 HTTP/2는 TCP를 기반으로 동작한다. 버전별 변화 HTTP/1.0 기본적으로 요청마다 연결을 새로 만드는 방식이 널리 사용됐다. 서버에서 여러 파일을 가져올 때 TCP 연결을 반복해서 설정하면 지연이 커질 수 있다. 다만 HTTP/1.0에서도 Connection: keep-alive를 확장 기능으로 사용할 수 있었다. ...

March 14, 2024

TCP/IP 4계층

소개 TCP/IP 4계층은 OSI 7계층과 더불어 인터넷에서 데이터를 주고받기 위해 사용하는 대표적인 네트워크 참조 모델이다. 네트워크 통신 과정을 역할에 따라 계층으로 분리하여 관리하며, 각 계층은 독립적인 역할을 수행한다. 덕분에 특정 계층의 구현이 변경되더라도 다른 계층에 미치는 영향을 최소화할 수 있다. 계층 구성 애플리케이션(Application) 대표 프로토콜: HTTP, HTTPS, DNS, FTP, SMTP 응용 프로그램이 사용되는 프로토콜 계층 이메일, 웹 서비스 등 서비스를 실질적으로 제공 전송(Transport) 대표 프로토콜: TCP, UDP 송신자와 수신자 간의 데이터 전송을 담당하는 계층 ...

March 13, 2024

Swift. Meta Type

소개 메타 타입은 이러한 타입 자체를 값으로 다루기 위한 타입이다. 즉, 인스턴스가 아니라 타입 그 자체를 표현하는 타입이라고 생각하면 된다. 종류 .Type 구조체, 클래스, 열거형 등 구체적인 타입의 메타 타입이다. let type: Int.Type = Int.self .Protocol 프로토콜 자체의 메타 타입이다. let type: AnyObject.Protocol = AnyObject.self 언제 사용할까? 메타 타입은 생각보다 자주 등장한다. 타입 자체를 함수의 인자로 전달할 때 런타임에 타입을 비교하거나 확인할 때 타입 정보를 저장해야 할 때 type(of:)를 사용할 때 필요한 이유 메타 타입이 필요한 가장 큰 이유는 타입 자체를 값처럼 다루기 위해서이다. ...

January 26, 2024

The Swift Programming Language. Memory Safety (1)

Memory Safety 스위프트는 기본적으로 코드에서 일어나는 안전하지 않은 행동들을 방지한다. 예를 들어, 스위프트는 변수를 사용하기 전에 초기화가 되어있는지 확인하고, 할당 해제된 메모리에는 접근하지 않으며, 배열의 인덱스 값들이 범위 안에 있는지 확인한다. 또한 스위프트는 메모리를 수정하는 코드가 해당 메모리에 독점적으로 접근하도록 요구하여 같은 위치에 있는 메모리에 대한 동시 접근이 충돌하지 않게 한다. 스위프트가 메모리를 자동적으로 수정하기 때문에, 대부분의 경우에는 메모리 접근에 대해 생각하지 않아도 된다. 하지만, 충돌이 발생할 수 있는 잠재적인 위치를 이해하여, 메모리에 접근할 때 충돌하는 코드 작성을 회피하는 것도 중요하다. 만약 충돌을 일으키는 코드라면, 컴파일 에러 혹은 런타임 에러를 발생시키게 된다. ...

August 26, 2023

The Swift Programming Language. Automatic Reference Counting (3)

Strong Reference Cycles for Closures 두 클래스 인스턴스의 프로퍼티들이 서로를 강한 참조하면서 강한 참조 사이클이 만들어지는지를 이전에 보았고, 약한 참조와 미소유 참조가 이러한 강한 참조 사이클을 깨뜨리는 것도 보았다. 강한 참조 사이클은 클래스의 인스턴스에 클로저를 할당하고, 해당 클로저의 본문에서 그 인스턴스를 캡처할때도 발생한다. 이러한 캡처는 self.someProperty처럼 그 클로저가 해당 인스턴스의 프로퍼티에 접근하거나, self.someMethod()처럼 해당 인스턴스의 메소드에 접근할 때 발생한다. 두 경우 모두, 이러한 접근으로 그 클로저가 self를 “캡처"할때, 강한 참조 사이클을 생성하게 된다. ...

August 21, 2023