🐥 Records/Daily | Today I Leared

[TIL] 99클럽 코테 스터디 5일차 TIL + 슬라이딩 윈도우, 큐, 스택

이오🐥 2025. 4. 5. 01:42

✅ 오늘의 TODO

- 알고리즘

  - 오늘의 문제 ✅

  - Class2 문제 2개

- 컴피

  - 위치 기능 구현 🔜

  - 컴피존 설정 화면 구현 🔜

  - 호랑 PR 리뷰

- TIL 작성 

 

🌼 오늘의 문제 - 백준 2559. 수열

수열에서 k만큼 연속된 누적합을 구하는 문제로, 슬라이딩 윈도우 알고리즘을 활용해서 풀었다. 처음에는 단순히 sum을 활용해 모두 더하는 방식으로 문제를 풀었는데, 바로 시간초과가 나버렸다. ^^ 대신에 '슬라이딩 윈도우'를 활용하면 그동안 더한 값에서 빠지는 값을 빼고, 새로운 값을 더하면 된다. 직접 다 더하는 것보다 값을 바로 찾아서 더하는 과정이 훨씬 시간이 적게 걸린다. 비슷한 알고리즘으로는 '투 포인터' 알고리즘이 있는데, 고정된 크기를 더하는 슬라이딩 윈도우와 다르게 개수가 고정되어 있지 않을 때 사용하는 방식이다.

def solution(n, k, arr):
    if n == k:
        return sum(arr)

    max_total = sum(arr[:k])
    total = sum(arr[:k])
    for i in range(k, n):
        total = total + arr[i] - arr[i - k]  # 기존 값에서 왼쪽 빼고 오른쪽 더하고~
        max_total = max(max_total, total)

    return max_total


n, k = map(int, input().split())
arr = list(map(int, input().split()))

print(solution(n, k, arr))

 

🌼 알고리즘 - 백준 11866. 요세푸스 문제0

이번에는 queue 자료구조를 활용하는 문제였다. 원형의 사람들 중 k 번째 사람들을 빼서 만든 수열을 구하는 문제였다. 나는 큐를 활용해서 먼저 들어간 아이들을 뺄 수 있도록 활용했고, 순서가 아닐 땐 다시 큐에 넣었다. 이 문제도 첫 번째 시도는 틀렸었는데, 출력 조건이 <#, #, #> 이렇게 평소와 다르게 요구되고 있었다. 하하. 하하하.

from collections import deque


def solution(n, k):
    people = [x for x in range(1, n+1)]
    queue = deque(people)
    result = []

    while queue:
        for _ in range(k - 1):
            queue.append(queue.popleft())
        result.append(queue.popleft())

    print("<" + ", ".join(map(str, result)) + ">")


n, k = map(int, input().split())
solution(n, k)

 

🌼 알고리즘 - 백준 1874. 스택수열

어쩌다 보니 자료구조 문제를 많이 풀게 되었다. 이번에는 스택을 활용하는 문제였다. 1부터 순서대로만 쌓을 수 있는 스택에서 더하거나 빼는 방법으로 주어진 수열을 만들 수 있는지 확인하는 문제였다. 처음에는 안 되는 경우의 처리가 헷갈려서 잘 풀지 못했는데, 손으로 과정을 써 내려가면서 풀다 보니 잘 해결됐다. 숫자를 쭉 돌면서 수열의 값에 해당하는 값이 나올 때까지 더하다가, 마지막 수열 값이 찾던 값일 때 빼준다. 그런데 이때 나보다 작거나 같은 값들을 모두 넣었는데도 내가 나오지 않는다? 그러면 수열을 만들 수 없기 때문에 NO를 출력한다.

def solution(n):
    numbers, result = [], []
    count = 1

    for _ in range(n):
        value = int(input())
        # '나'의 값이 나올 때까지 numbers에 값을 담는다
        while count <= value:
            numbers.append(count)
            result.append("+")
            count += 1
		
        # numbers의 마지막 값이 '나'라면 뺀다
        if numbers[-1] == value:
            numbers.pop()
            result.append("-")
        # 아니라면 수열을 만들 수 없으므로 "NO" 출력
        else:
            return ["NO"]

    return result


n = int(input())

for x in solution(n):
    print(x)

 

👀 컴피 - 호랑 PR 리뷰

호랑이 메모 View를 개발하고 PR을 남겨주었다. PR이 꽤 커서 확인할 내용이 꽤 많다. 사실 PR 내용이 많더라도 익숙하고 금방 읽히는 내용은 금방 볼 수 있을 수도(?) 있지만, 사실상 우리의 Intent를 활용한 거의 첫 화면이었기 때문에 규칙과 관련된 이야기를 많이 하게 되었다. 초기에 Navigation 화면 전환 로직을 분리하기 위해 Router를 생성했고, View와 다른 의존성들을 주입하기 위한 객체를 생성했었다. SwiftUI에서 NavigationStack을 쓰고, NavigationLink를 활용하면서 View가 갖는 화면 전환 책임을 완전히 빼기 위함이었다. 그런데 반대로 호랑은 화면 전환이 UI의 역할이라고 생각해서 View에 router를 활용하고 있었다. 흠.. 흠.. 최근에는 정말 '의견'의 차이라고 느끼는 논의를 주로 해왔는데, 이번에는 의견보다는 규칙이나 음... 그 이상의 무언가ㅎㅎ 인 것 같다.

(왼쪽) 내가 후루룩 말하고 넘겨버린 이야기를 (오른쪽) 호랑이 잘 정리해주고 생각해준 과정

 

이렇게 논의하고 이야기할 수 있는 개발자가 있는 게 너무나도 즐겁다. 내가 틀렸다면 틀린 대로 내용을 정정하고, 옳으면 옳은 대로 설득하는 과정을 거치고, 의견이 달랐다면 다양한 의견을 받아들이는 과정인 것 같다. 이 내용 말고도 이번 PR에서 느끼는 내용이 많다. 호랑이 사용한 Combine의 Publisher 중 하나도 처음 봤고, Preview에서 @Previewable을 사용하는 것도 처음 봤다. 그리고 View를 생성하고 주입할 의존성이 Intent 뿐이어서 ViewFactory라고 붙였던 아이가 Repository도 가지게 되고, 점점 규모가 커지면서 DIContainer로 개명하는 논의도 했다. 유후 호랑 PR 또 봐야지 ㅎㅎ

 

👀 컴피 - 컴피존 세팅 화면 개발

꽤 오래전(1-2주?)부터 하고 있던 컴피존 세팅 화면 개발.. 위치 기능을 먼저 넣으려고 화면 개발이 늦어졌는데, 공부할 내용이 조금 더 있는 것 같다는 판단에 화면부터 끝내기로 했다. Onboarding에서 Intent를 쓰긴 했지만, 버튼 하나뿐인 화면이라 크게 체감하지 못했는데, 이번 화면을 개발하면서 Intent의 명확한 의도 파악 및 가독성과 함께!!! 작은 기능에서 이렇게 분리해야 하나 싶은 귀찮은 일까지 모두 체감하고 있다. 곧 있을 마디 리팩토링에서 TCA를 써볼까 고민 중인데, TCA도 결국 MVI의 단방향 흐름을 추구하는 설계이니.. 비슷한 느낌이지 않을까 생각한다. 여기서 개발하면서 어떤 점이 좋은지 그리고 어떤 식으로 활용하는 게 좋은지 느껴보면 좋을 것 같다.

 

한 화면에서 정말 다양한 정보를 이용해 활용하는 앱이 되었다. 메모 화면도 컴피존인지 아닌지, 그리고 텍스트로 이모지로 변환되고, ... 화면 하나가 가지는 기능이 많다고 느꼈다. 그런데 컴피존 세팅도 꽤나 분기 처리해야 하는 내용이 많다. 위치 권한 여부, 컴피존 내부인지 여부, 컴피존이 있는지 없는지 여부 등등.. 개발하고 나면 '가독성' 좋은 코드를 만들기 위해 한 번 더 고민할 필요가 있어 보인다. 이번에는 빠른 구현보다 잘 만든 코드를 쓰고 싶어서 더 그런 것 같기도 하다.

 

💻 앨런 Concurrency 강의 시작

대략 5개월 전 무료 강의를 신청했던 Concurrency Part1 강의 마감이 4월 19일로 이제 엄청나게 다가왔다. 어젯밤에 교재를 구매했지만, 아직 교재를 받지 못했다. 그치만 우선 듣기 시작!! 1강 듣자마자 '캡처', '순환 참조', 냄새 맡고 호다닥 다시 공부하고 왔다. 좋다. 사실 아직 제대로 된 Concurrency 부분은 들어가지도 않았지만 ㅎㅎ..

 

🍀 오늘의 회고

새로운 스터디카페와 알고리즘 스터디로 공부 집중력과 효율이 엄청 오르고 있다. 알고리즘을 하다 보니 너무 재밌어서 그동안 왜 우선순위에서 밀어둔 걸까 후회했다. 그래 남들이 내가 알고리즘 제대로 시작하면 진짜 좋아할 것 같다고 한 이유를 이제야 알았다. 진짜 재밌다. 유후. 얼마 전에 '그동안 뭐 했지' 병에 걸린 것 같다고 했었는데, 그동안 주워들은 것들이 나의 뇌공간을 만들어 준 것 같다고 느꼈다. '그래 그동안 뭐 했네'로 생각이 바뀌는 것 같다. 그동안 뭐라도 했기 때문에 지금 하고 있는 공부나 개발에 또 차곡차곡 쌓을 공간이 있는 거다!

 

내일은 벚꽃 구경을 하러 가려고 했는데, 비가 온다고 한다. 벚꽃들아 아직 떨어지면 안돼ㅠㅠㅜ

 

내일 할 일

- 알고리즘 1문제

- 컴피존 설정 화면 개발

- 앨런 Concurrency 강의

- 이력서/포트폴리오 보강하기

- TIL 작성하기