sw사관학교정글/회고 및 생각정리

[week01] WIL - 1주차 회고 및 배운내용 정리

D cron 2021. 11. 14. 23:03

📷 회고

정말 정신없었고, 개발실력에 관한 나의 무능함을 일깨워준 정글에서의 0주차(4일)가 지나가고 팀원들과 합심하여 주어진 문제를 해결하는 1주차가 다가왔다. 

같은팀 조원들과 이제 막 친해진것 같은데 바로 헤어지게 되어서 아쉬운 감정이 컸다. 그러나 아쉬운 감정을 길게 가져갈 새도 없이 과제가 쏟아져나왔다.

 

1 ~ 4주차는 알고리즘 문제풀이 주차인데,

1주차의 키워드는 다음과 같다.

[정수론, 배열, 문자열, 재귀함수, 정렬, 완전탐색, 시간복잡도]

기초적인 문제들이 많았기 때문에 시간은 넉넉할 것이라고 판단하고 각자 문제를 풀고 모르는 문제는 서로 도와주는 식으로 이번 주를 진행하기로 했다.

 

그러나 정말 큰 착각이었다. 주어진 시간 안에 모든 문제를 풀기조차 빠듯했고 시험 전날 밤이 되어서야 모두 풀 수 있었다. 내가 할 일을 끝내지 못하고서는 다른 사람을 도와줄 수 없다는 걸 크게 배웠다. 팀 활동인데 팀적으로 여러가지 장치들을 마련해서 모두가 다 제 시간에 끝낼 수 있도록 처음부터 계획했어야 했다. 조원 모두가 문제를 풀면 체크하는 칸이 있었는데, 우리 조는 결국 모든 문제를 체크하지 못하고 week1을 마무리 했다. 다음 팀 활동에서는 모두가 통과할 수 있는 시스템을 만들어야겠다.

 

특히 재귀가 너무너무 어려웠다. 구현은 커녕 이해도 어려웠다. 재귀를 나처럼 포기할까 생각했던 분들은 밑의 코치님 조언을 보면 도움을 받을 수 있을 것이다.

 

조원들에게 배울 점이 많았다. git과 github에 관해서 많이 배웠고 오늘 배운 것을 간단하게 정리하는 것을 보고 나도 따라서 notion에 정리를 하게 되었다. 또한 나이에 상관없이 상대방이 편하게 대할 수 있도록 해주는 모습도 인상깊었다. 정글에서는 정말 배울점이 많은 사람들이 널렸다. 나도 다른 사람이 봤을 때 배울점이 있는 사람이 되었으면 좋겠다.

📗 배운 내용 정리

파이썬 입력

  • 경험적으로 input()함수 대신 sys.stdin.readline()함수를 사용하면 더 빠르다. 백준에서 input()을 썼을 때 시간초과가 난 코드가 sys.stdin.readline()을 쓰면 통과되는 경험을 한 적이 있기 때문이다.
  • 더 자세하게 알아보면 input()함수는 parameter로 prompt 메시지를 받을 수 있다. 이것이 약간의 부하로 작용할 가능성이 있다. 또한, input() 함수는 입력받은 값의 개행 문제를 없애준다. sys.stdin.readline()은 개행 문자를 포함한 한 줄 전체를 입력받는다.
  • 위의 이유들로 백준에서 문제를 풀 때는 sys.stdin.readline()을 쓰는 것이 속편하다.

파이썬 다중조건 정렬

  • 리스트를 정렬할 때 두 가지 조건을 둘 다 적용시켜야 할 경우가 있다. 그럴때 유용한 방법을 소개한다.
  • 아래의 a 리스트에서 첫 번째 인자를 기준으로 오름차순 정렬을 한 상태에서 두 번째 인자를 기준으로 내림차순 정렬하는법
  • a = [(1,7),(3,4),(4,8),(1,4),(3,1)]
    a_sorted = sorted(a,key=lambda x: (x[0],-x[1]))
    # a_sorted = [(1,7),(1,4),(3,4),(3,1),(4,8)]
  • quick sort를 직접 구현해서 쓰는 것 보다 파이썬 내장함수 sort,sorted를 쓰는 것이 더 빠른 것 같다. 시간복잡도는 같은 O(NlogN)인데 파이썬 sort, sorted 함수는 최적화가 더 잘되어있나보다. 퀵정렬이 가장 빠른 알고리즘이라고 해서 썼는데 시간초과가 떠서 깜짝 놀랐다.

얕은 복사와 깊은 복사

  • import copy
    # 깊은 복사
    x = [[1,2,3],[4,5,6]]
    y = copy.deepcopy(x)
    ------------------------
    # 얕은 복사 -> y에서 변경하면 x에 영향감
    x = [[1,2,3],[4,5,6]]
    y = x.copy()
  • 얕은 복사는 참조값만 복사하는 방식이다. 깊은 복사는 참조값 뿐만 아니라 참조하는 객체 자체를 복사한다. 따라서 복사한 y에서 값을 변경하더라도 x에 영향이 없다.(x,y 서로 독립적)

백준 문제풀때 recursionError 해결방법

  • recursionError는 재귀와 관련된 에러다. 가장 많이 발생하는 이유는 python이 정한 최대 재귀 깊이보다 내 코드의 재귀의 깊이가 더 깊어질 때다.(백준에서는 1000으로 설정되어있음)
  • 이럴 때는 python이 정한 최대 재귀 깊이를 변경하면 된다.
  • import sys
    sys.setrecursionlimit(10**6)

💻 코치님 조언

재귀 함수(recursive function)나 수학적 귀납법 (induction)  어려워서 피하실 분 계신 것 같은데요,
빨리 친해지실 수 있으면 친해지시는 게 정말, 정말, 정말 도움이 됩니다.
생각해 보면 저도 대학교 2학년 때 C언어 recursion 이해하느라고 일주일 썼던 것 같습니다.
네, 이해하기 어려운거 이해해요.
그런데요,
이해하고 나면 이렇게 쓰기 좋은 도구가 거의 없습니다.
사실 알고 나면 어렵지 않습니다.
함수가 자기 자신을 부르기 때문에 코드 보면서 쫓아가면 헛갈릴 수 밖에 없습니다. 처음 불렸던 함수와 그 안에서 부른 함수, 그 안의 안에서 부른 함수 다 다른 함수인 겁니다. 함수 인자(argument)를 call depth와 함께 종이나 칠판에 적어서 어떻게 돌아가는지 직접 하나하나 쫓아가는 것도 이해하는 방법 중에 하나입니다.
고등학교때 수열의 점화식과 일반식 배우셨던 기억을 되살려 보십시오. 컴퓨터 프로그램은 일반식을 구하라고 요구하지 않습니다. 점화식과 초항만 잘 넣으면 컴퓨터가 알아서 계산해 주죠. 문제를 풀 때 점화식초항만 쉽게 찾아낼 수 있다면 이렇게 짜기 쉬운게 없습니다.
recursion이 WEEK01에 있는 이유가 있습니다. WEEK04까지 recursion이 연관됩니다. recursion을 이해하면 다른 것도 쉽게 이해가 되는데 모르고 지나가면, 이해 못하지는 않는데, 좀 다른 식으로, 어렵게 이해하게 될 것 같습니다.
"작은 문제의 해결법을 사용해서 더 큰 문제를 푼다"는 기본 개념이 더 중요하기는 한데, 그 개념 그대로 프로그래밍 언어도 쓸 수 있다는 점을 이해하실수 있다면 정말 좋은 도구가 되리라고 생각합니다.

코치님은 어떻게 1주일만에 재귀를 이해한것인가...

 


참고자료