SwiftUI Tutorials. Handling User Input

랜드마크 앱에서 사용자는 좋아하는 장소를 플래그하고, 그들이 좋아하는 장소만 필터해서 볼 수 있다. 이런 기능을 만들기 위해서, 리스트에 스위치를 추가하여 유저들이 그들이 좋아하는 장소에만 포커스를 맞출 수 있도록 해야한다. 그리고 별 모양 버튼을 추가하고, 탭하면 유저들이 랜드마크에 favorite 플래그를 할 수 있도록 한다. Section 1. Mark favorite landmarks 리스트를 개선해서 사람들이 한 눈에 favorite를 찾을 수 있도록 시작한다. Landmark 스트럭처에 프로퍼티를 하나 추가해서, 이 랜드마크가 favorite인지 초기 상태를 읽을 수 있도록 한다. 그리고 favorite 표시된 랜드마크에는 별 아이콘을 보여준다. ...

June 25, 2024

SwiftUI Tutorials. Creating and Combining Views

Section 1. Create a new project and explore the canvas SwiftUI를 사용하는 새로운 Xcode 프로젝트를 만든다. 캔버스, 미리보기 및 SwiftUI 템플릿 코드를 탐색한다. Step 1-3 프로젝트 생성 부분 Step 4 SwiftUI 앱 라이프 사이클을 사용하는 앱은 App 프로토콜을 컨펌하는 스트럭처를 가지고 있다. 스트럭처의 body 프로퍼티는 디스플레이에 보여줄 컨텐츠를 제공하는 하나 이상의 씬이 있다. @main 어트리뷰트는 앱의 엔트리 포인트를 지정한다. // // LandmarksApp.swift // Landmarks // // Created by Kelly Chui on 6/25/25. // import SwiftUI @main struct LandmarksApp: App { var body: some Scene { WindowGroup { ContentView() } } } Step 5-7 기본적으로, SwiftUI 뷰 파일은 스트럭처와 프리뷰를 선언한다. 구조체는 View 프로토콜을 컨펌하며, 뷰의 내용과 레이아웃을 정의한다. preview 선언은 해당 뷰의 미리보기를 생성한다. ...

June 25, 2024

SwiftUI Tutorials. Building Lists and Navigation

사용자가 전체 랜드마크 목록을 보고 각 위치에 대한 세부 정보를 볼 수 있는 방법을 제공해야 한다. 모든 랜드마크에 대한 정보를 표시할 수 있는 뷰를 생성하고 사용자가 탭하여 랜드마크에 대한 디테일 뷰를 볼 수 있는 스크롤 목록을 동적으로 생성한다. UI를 미세 조정하고 싶으면 Xcode를 사용하여 다양한 장치 크기에서 미리보기를 렌더링 하면 된다. Section 1. Create a landmark model 첫 번째 튜토리얼에선, 모든 정보들을 커스텀 뷰에 하드코딩했다. 이제는 뷰로 전달할 수 있는 데이터를 저장하는 모델을 만들 것이다. ...

June 25, 2024

BOJ 13144. list of unique numbers

문제 https://www.acmicpc.net/problem/13144 풀이 매우 특이한 유형의 투 포인터 문제다. start, end가 증가만 해서는 모든 경우의 수를 나타낼 수 없으며, 모든 경우의 수를 탐색하려면 O(n^2)이 된다. 1 2 3 1 2 라는 수열이 있을 때를 생각해보자 겹치는 원소가 나오지 않도록 작성한 일반적인 투 포인터는 1, 12, 123, 231, 312 이렇게 5번 탐색을 하고 종료한다. 하지만 1 2 3 1 2의 정답은 5가 아니라 15이다. 하지만 이 5번의 탐색만으로도 15라는 결과를 얻을 수 있는데, 우리는 정확한 부분 수열의 형태보다 경우의 수만 알면 되기 때문이다. ...

June 12, 2024

BOJ 7490. 0 만들기

문제 https://www.acmicpc.net/problem/7490 풀이 DFS 문제이다. 3가지 연산자 (" ", "+", "-")를 배치하는 모든 경우의 수를 수식으로 만든 후 계산하면 된다. 코드 import Foundation func calcuate() { var rawExpression = "" for idx in 0..<n - 1 { rawExpression += String(seq[idx]) rawExpression += cal[idx] } rawExpression += String(seq[n - 1]) let expression = rawExpression.replacingOccurrences(of: " ", with: "") var numbers = [Int]() var operators = [Character]() var numBuffer = "" for element in expression { if element.isNumber { numBuffer.append(element) } else { numbers.append(Int(numBuffer)!) operators.append(element) numBuffer = "" } } if let lastNumber = Int(numBuffer) { numbers.append(lastNumber) } var result = numbers[0] for idx in 0..<operators.count { if operators[idx] == "-" { result -= numbers[idx + 1] } else { result += numbers[idx + 1] } } if result == 0 { print(rawExpression) } } func dfs() { if cal.count == n - 1 { calcuate() return } for op in [" ", "+", "-"] { cal.append(op) dfs() cal.removeLast() } } let t = Int(readLine()!)! var n = Int() var seq = [Int]() var cal = [String]() for _ in 0..<t { n = Int(readLine()!)! seq = Array(1...n) cal = [] dfs() print() }

June 10, 2024

BOJ 4179. 불

문제 https://www.acmicpc.net/problem/4179 풀이 지훈이가 움직이고, 불을 퍼뜨리면 된다. 순서대로 진행하면 되는데 주의해야 할 점이 두 가지 있다. 1분마다 기준으로 번갈아서 움직여야 한다. 지훈이가 움직이기 전에 불에 타면 안된다. 코드 from collections import deque def bfs(jihun, fires): is_jihun_Visited = [[-1] * c for _ in range(r)] fire_queue = deque() jihun_queue = deque() fire_queue.append(fires) jihun_queue.append([jihun]) is_jihun_Visited[jihun[0]][jihun[1]] = 0 while jihun_queue or fire_queue: if jihun_queue: jihun_temp_queue = [] jihun_nodes = jihun_queue.popleft() for cur in jihun_nodes: if graph[cur[0]][cur[1]] == "F": continue for move in [(-1, 0), (0, 1), (1, 0), (0, -1)]: next = (cur[0] + move[0], cur[1] + move[1]) if next[0] == -1 or next[1] == -1 or next[0] == r or next[1] == c: return is_jihun_Visited[cur[0]][cur[1]] + 1 if next[0] < 0 or next[0] >= r or next[1] < 0 or next[1] >= c: continue if is_jihun_Visited[next[0]][next[1]] != -1: continue if graph[next[0]][next[1]] == ".": jihun_temp_queue.append(next) is_jihun_Visited[next[0]][next[1]] = is_jihun_Visited[cur[0]][cur[1]] + 1 if jihun_temp_queue: jihun_queue.append(jihun_temp_queue) if fire_queue: fire_temp_queue = [] fire_nodes = fire_queue.popleft() for cur in fire_nodes: for move in [(-1, 0), (0, 1), (1, 0), (0, -1)]: next = (cur[0] + move[0], cur[1] + move[1]) if next[0] < 0 or next[0] >= r or next[1] < 0 or next[1] >= c: continue if graph[next[0]][next[1]] == ".": fire_temp_queue.append(next) graph[next[0]][next[1]] = "F" if fire_temp_queue: fire_queue.append(fire_temp_queue) return "IMPOSSIBLE" r, c = map(int, input().split()) graph = [] for _ in range(r): graph.append(list(input())) jihun = (0, 0) fires = [] for row in range(r): for column in range(c): if graph[row][column] == "J": jihun = (row, column) elif graph[row][column] == "F": fires.append((row, column)) print(bfs(jihun, fires))

June 10, 2024

BOJ 2668. 숫자고르기

문제 https://www.acmicpc.net/problem/2668 풀이 문제를 간단하게 표현하면 그래프 내의 사이클을 모두 찾은 다음에, 사이클에 포함되는 노드을 모두 출력하면 된다. 사이클을 찾으려면 그래프내의 모든 노드에서 dfs를 쓰면 되는데 다음과 같은 케이스들로 나눌 수 있겠다. 1. 사이클에 도달하긴 하나 시작 노드는 사이클에 포함되지 않는 케이스 주어진 예제에서 2번, 4번, 6번, 7번 노드가 해당한다. 탐색을 시작한 노드에서 사이클에 도달하긴 하나, 시작한 노드는 사이클에 포함되지 않는다. 최적화를 위해 이러한 케이스에도 사이클만 따로 분리해 중복되는 연산을 줄일 수 있겠지만, 이 문제의 n이 큰 수가 아니므로, 그냥 아무런 행동도 하지 않는다. ...

June 4, 2024

BOJ 14719. 빗물

문제 https://www.acmicpc.net/problem/14719 풀이 스택 문제이다. 빗물은 양 옆이 블록으로 막혀있을 때, 낮은 블록의 높이를 기준으로 그 사이에 빗물이 고이게 된다. 따라서 스택을 하나 만들고 인덱스 순서대로 입력받은 다음에, “현재까지” 가장 높게 쌓여있던 블록의 높이(currentMax)와 같거나 더 높게 쌓여있는 블록이 스택에 들어오려 할 때, 스택에 쌓여있는 모든 블록들을 빼내면서 고여있는 물의 양을 더하면 된다(currentMax - 중간 블록의 높이). 하지만 이러한 방법을 쓰면 문제점이 하나 있는데, 블록이 계속 커진다는 보장이 없기 때문에, 마지막에 있는 블록들이 붕 뜨게 된다. 이 때는 스택을 뒤집어서 해결하면 된다. 현재 currentMax보다 더 큰 수가 앞에 존재하지 않는다면 뒤집힌 스택은 무조건 currentMax가 마지막에 존재하게 된다. (만약 currentMax보다 낮은 블록은 이미 pop된 상태일 것이기 때문에) 따라서 스택을 뒤집은 다음(혹은 다른 스택에 차례대로 옮긴 후에) 이 전의 과정을 한번 반복하면 문제가 해결된다. ...

May 28, 2024

BOJ 17266. 어두운 굴다리

문제 https://www.acmicpc.net/problem/17266 풀이 가로등 간의 최대 간격을 찾으면 되는 문제이다. 일반적인 가로등 간의 간격과, 시작점과 첫 가로등의 간격, 도착점과 마지막 가로등의 간격을 알아내면 된다. 가로등 사이의 간격은 양 사이드 모두가 가로등이기 때문에 간격에서 2를 나눠줄 필요가 있다. 이 문제에는 작은 함정이 하나 있는데, 가로등 사이의 간격이 만약 홀수인 경우에는 2로 나눴을 때 0.5가 내림 되기 때문에 주의해야 한다. 코드 import Foundation let n = Int(readLine()!)! let m = Int(readLine()!)! let x = readLine()!.split(separator: " ").map { Int($0)! } var answer = max(x.first!, n - x.last!) for idx in 1..<m { let interval = Int(ceil(Double(x[idx] - x[idx - 1]) / 2.0)) if interval > answer { answer = interval } } print(answer)

May 6, 2024

Network. Physical & Data Link Layer

Physical & Data Link Layer Physical Layer: 전기, 광, 무선 등의 신호를 통해 데이터를 전송하는 계층 Data Link Layer: 같은 LAN에서 데이터를 올바르게 전달하기 위한 계층 주요 기술 Ethernet 같은 LAN 안에서 데이터를 주고받는 대표적인 기술이다. Ethernet Frame 이더넷 기반의 네트워크에서 주고받는 프레임, 프리앰블, 송 · 수신 MAC 주소, 타입/길이, 데이터, FCS로 구성 프리앰블(preamble) 8 Bytes 이더넷 프레임을 수신하고 있다는 것을 알려주는 부분 MAC 주소(MAC address) 12(6 + 6) Bytes 이더넷 프레임을 송 · 수신할 장치의 MAC 주소를 가지고 있음 타입/길이(type/length) 2 Bytes 1500 이상의 값일 경우에는 프로토콜의 타입을 뜻함 1500 이하의 경우엔 LLC라는 값으로 타입 판별한다. 하지만 요즘은 거의 대부분 Ethernet II를 사용하기 때문에 명확하게 타입으로 사용함. 데이터(data) 최대 1500Bytes 실제로 송수신할 데이터 FCS 프레임의 오류가 있는지 여부를 확인하기 위한 트레일러 CRC(Cyclic redundancy check)라는 오류 검출용 값이 명시됨. Wireless 유선이 아닌 전파로 통신하는 방법이다. 대표적으로 와이파이가 있다. 주파수 간섭 문제를 최소화 하기 위해 채널이라는 하위 주파수 대역으로 세분화한다. ...

April 30, 2024