Harvard CS50X
cs에 대해 제대로된 수업을 받아보지 않고 지난 2년간 웹사이트와 게임들을 만들면서
항상 새로운 툴들을 익히는 것에 급급했고 깊은 이해 없이 빠른 제작에 집중했었다.
이런 시간이 길어지면서 컴퓨터의 기본과 cs 지식에 대한 갈증이 있었고
하버드에서 진행하는 CS50이라는 코스를 알게되었다.
https://cs50.harvard.edu/x/2024/
개인적으로 정말 좋은 프로그램이라고 생각하고
만약 누군가 컴퓨터와 관련된 분야를 새롭게 익히고 싶다한다면 자신 있게 이 강의를 추천할 것 같다.
앞으로의 포스팅은 해당 주차의 CS50 강의를 정리/요약하고 ProblemSet 을 어떻게 해결했는지 공유할 예정이다.
Computer Science
CS 즉 컴퓨터 사이언스란 Computational thinking 컴퓨터팅 사고를 기반으로 문제를 해결하는 것이다.
결국 이 모든 것은 어떤 문제를 해결하기 위한 것이다.
컴퓨팅 사고로 어떤 문제를 해결한다는 것은 다음 도표로 설명할 수 있다.
Binary
컴퓨터는 우리가 흔히 쓰는 언어나 10진수가 아닌 0,1 로 구성된 이진수로 정보를 저장한다.
그 이유는 컴퓨터 구성 원리에 있는데 컴퓨터는 트랜지스터와 미약한 전류를 이용한다.
전류가 없으면 0 전류가 있으면 1 이런 방식이다.
그렇다면 컴퓨터가 우리가 쓰는 Decimal(10진수) 대신 Binary(이진수) 를 채택한 것은 지극히 자연스럽다.
더 많은 경우의 수를 가질 수 있기 때문이다.
예를 들어 0과 1만 구분 할 수 있는 상태에서 숫자 0, 1, 2, 3을 표현한다고 해보자.
Decimal 의 경우엔 0, 1, 11, 111 이렇게 표현해야할 것이다.
Binary 의 경우엔 0, 01, 10, 11 이렇게 표현할 수 있다.
즉 Decimal은 3을 표현하려면 3칸을 써야하지만 Binary는 2칸으로 표현이 가능하다.
그리고 숫자가 커지면 커질 수록 이 차이는 훨씬 커진다.
컴퓨터에서 0과 1을 구분하는 1칸을 bit 라고 하는데 이것은 binary digit 에서 가져온 것이다.
더 익숙할 byte 의 경우엔 8bit 를 byte로 표현하는 것이다.
ASCII
컴퓨터가 이진수를 쓰는 것은 알겠는데 사실 우리는 일상에서 이진수를 거의 쓰지 않을 뿐더러 정보를 주로 언어로 저장한다.
01001000 01001001 00100001 이렇게 말하면 우리는 무슨 뜻인지 알 수가 없다.
그러면 0과 1밖에 모르는 컴퓨터에게 어떻게 정보를 전달 할 수 있을까? 그 해답이 ASCII 코드에 있다.
ASCII (American Standard Code for Information Interchange) 이름부터가 미국스러운..
이런 문제를 해결하기 위해 만든 일종의 규약이다.
앞서 말한 1001000 1001001 100001 이 이진수는 각각 72, 73, 33을 나타내고
ASCII 에 따르면 이건 HI! 이다. 드디어 우리가 알수 있는 언어가 됐다.
하지만 ASCII는 8bit 크기의 정보를 담고 있고 이것은 0~127 즉 128개의 문자만 담을 수 있다는 것이다.
Unicode
컴퓨터의 생태계가 커지면서 알파벳과 소수의 기호만 담은 ASCII코드는 한계가 분명했다.
😂😁 이런것은 ASCII로 표현 할 수 없다..
더 많은 언어와 이모티콘 같은 감정표현, 특수기호등을 표현하기 위해 Unicode가 탄생했다.
유니코드의 경우엔 32bit 크기의 정보를 커버하고 32bit 는 2의 23제곱으로 40억개가 넘는다.
이렇게 숫자가 많다보니 만약 1024819312에 해당하는 문자를 사용하려면 상당히 불편하다.
추후에도 자세히 다루지만 이렇게 10진수로 다루기 힘든 큰 숫자를 다룰때
주로 Hexadecimal(16진수)로 표현한다. (컴퓨터 분야에서)
유니코드의 경우에는 U+1F44D 이런 포맷으로 쓰인다.
Algorithms
컴퓨터가 어떻게 정보를 저장하고 소통하는지 알았으니 다시 우리가 컴퓨터를 쓰는 이유 문제 해결 에 대해 다시 말하고자 한다.
알고리즘은 우리가 문제를 해결하는 방법에 대한 것으로 과정 자체가 알고리즘이다.
만약 옛날 두꺼운 전화번호부에서 "중국집" 이라는 가게의 전화번호를 찾는다고 상상해보자.
전화번호부는 무려 1000장이다.
1. 처음부터 1장씩 넘겨본다.
ㄱㄴㄷ..을 거쳐 ㅈ 까지 1장씩 넘겨서 찾으려면 거의 600~800번 이상을 넘겨야 할 것이다.
누군가는 그냥 처음부터 ㅈ에서 찾으면 되는데? 라고 생각 할 것이다.
하지만 컴퓨터는 우리처럼 정보를 한눈에 직관적으로 가지고 있지 않다.
3차원 존재와 2차원 존재의 차이와 유사하다. 쭉 훑으며 탐색해야 한다는 것이다.
2. 2장씩 넘겨본다.
그렇다면 2장씩 넘기면 어떨까?
2장씩 넘기면 300~400번만에 ㅈ 근처에 도착할 것이다.
근데 만약 2장씩 넘겨진 페이지 사이에 내가 찾으려는 "중국집" 이 있다면 아주 치명적일 것이다.
3. 반씩 자르며 찾아본다.
반씩 자르며 찾아본다의 의미는 전화번호부가 ㄱㄴㄷㄹㅁㅂㅅㅇㅈㅊㅋㅌㅍㅎ 로 되어있을때
- 1. 중간 지점으로 간다.
ㄱㄴㄷㄹㅁㅂㅅ | ㅇㅈㅊㅋㅌㅍㅎ 이렇게 중간지점으로 이동
- 2. 중간 지점과 내가 찾으려는 목표와 비교
여기서 나의 중간지점 : ㅅ 언저리이고 이는 분명 내가 찾으려는 것보다 앞에 있는 것이다.
- 3. 목표가 없는 곳 삭제
내가 찾으려는것이 앞에 없는것이 확실해졌으므로 ㅇㅈㅊㅋㅌㅍㅎ 만 남기고 없애버린다.
이제 다시 -1 번으로 돌아가 중간지점에 찾는 목표가 있을 때 까지 반복한다.
이 방법으로 탐색하면 1000장으로 시작해도
1000 -> 500 -> 250 -> 125 -> 62 -> 30 -> 15 -> 7 -> 3 -> 2-> 1
이런식으로 10번언저리에 도달하게 될 것이다.
위의 1, 2, 3 방법을 시간과 문제 크기의 그래프로 표현하면
이렇게 1,2 번과 3번은 근본적으로 다른 그래프가 그려진다.
여기서 주목해볼만한 부분이 있는데 3번 방법은 단순히 빠른 정도가 아니다.
만약 전화번호부가 최신화 돼서 2000장으로 늘어난다면 1번과 2번은 작업량이 2배로 늘 것이다.
그러나 3번은 같은 작업을 1번 더 하는 것으로 처리할 수 있다.
경우에 따라선 1번과 2번이 해결할 수 없는 문제를 해결 할 수 있다.
Pseudocode
알고리즘의 힘을 살짝 맛봤다면 pseudocode는 이런 알고리즘을 구현할 때 도움되는 내용이다.
어떤 문제를 보자마자 최적의 해결방법을 고안하고 이것을 코드로 나타낼 수 있는 사람은 없다.
복잡한 문제일수록 먼저 자신이 편한 언어 (영어 / 한국어) 등으로 나타낸 후 코드로 바꾸는 것이 기본이다.
나도 여러 코딩테스트 문제를 풀어봤지만 pseudocode 를 쓰고 코드로 바꾼 적은 거의 없다.
굉장히 후회하는 부분이다.
하지만 이것은 습관의 문제라고 생각한다.
어떤 문제를 접할때 이건 쉬우니깐 pseudocode 안쓰고 어려울 때 쓰겠다는 생각은 좋지 않다.
쉬운 문제부터 버릇이 들어야 어려운 문제에서도 적용하고 접근 할 수 있다.
Scratch / Problem Set 0
이번 Problem Set은 스크래치에 자신의 프로젝트를 업로드 하는 것이다.
스크래치에 대한 설명과 예시는 CS50 강의에서 충분히 들을 수 있다.
나는 스페이스바로 슛하는 간단한 농구게임을 만들어보았다.
끝으로 내가 만든 스크래치 프로젝트이다.
https://scratch.mit.edu/projects/961491018
https://scratch.mit.edu/projects/961491018
scratch.mit.edu
'입문 > CS50X' 카테고리의 다른 글
[CS50X] 2024 Week3 Algorithms (1) | 2024.02.23 |
---|---|
[CS50X] 2024 Week2 Arrays Problem Set 2 (Scrabble, Readability, Substitution) (0) | 2024.02.22 |
[CS50X] 2024 Week2 Arrays (0) | 2024.02.22 |
[CS50X] 2024 Week1 C Problem Set 1 (Mario, Credit) (0) | 2024.02.21 |
[CS50X] 2024 Week1 C (1) | 2024.02.21 |