본문 바로가기
studylog

~231012 TIL

by Nam Kyeongmin 2023. 10. 12.

참 오랜만인 TIL. 사실 바쁘다는 핑계로 조금 미뤘던 TIL.

그래서 이번 TIL은 Today I Learned가 아닌 Thesedays I Learned가 되겠습니다.

앞으로는 TIL을 더 꾸준히 쓸 수 있도록..!!

 

📖 C언어

 전공교과목 <문제해결기법>을 통해 C언어를 배우고 있다. 1학기에는 <프로그래밍기초> 수업을 통해 기초적인 코드의 구조(변수, 조건문 등)와 포인터 개념에 대해 중점적으로 학습했고, 현재 2학기에는 이러한 내용을 다시금 복습한 후 구조체 개념을 배웠다.

 1학기에 전전사, 튜터링 같은 스터디를 진행하면서 선배들과 내용을 다시 학습하고 보고서 작성을 통해 스스로 복습할 수 있는 시간을 가지는 것이 좋아서 2학기에도 전전사, 튜터링의 튜티로 참여하게 되었다.

 

23-2 전전사 1주차 보고서.hwp
1.08MB

- 전전사 1주차 학습 보고서를 작성하면서 1학기 C언어 리뷰를 진행할 수 있었다. 분명 활동과정에 의해 작성하는 보고서이지만, 정해진 양식이 없어 스스로 내용을 되짚어보며 정리하면서 자연스레 복습이 되어 좋다.

23-2 전전사 3주차 보고서.hwp
5.16MB

- 특히 전전사 3주차 보고서는 교과목 진도와 비슷해 교수님이 말씀해주신 내용을 덧붙여 함께 정리했는데, 훨씬 좋았다. 수업을 듣다보면 이해되지 않는 부분이 생기기 마련이고, 이러한 부분을 선배의 설명을 통해 해소할 수 있는 경험을 했다. 그 반대의 경우 역시 마찬가지로 경험할 수 있었다. 모르는 부분이 있을 때, 인터넷이나 이미 그 언어에 익숙한 여러 사람의 도움을 받아 이해할 수 있다는 방법을 스스로 배웠다.

 

 

공유노션이 있지만 내 정보만 있는 것이 아니기 때문에 사진으로 대체합니다

사실 스스로가 발전하고 있다는 것을 실감하는 것 중 큰 몫을 차지하는 것은 튜터링이다.

 

[Before class]

백준 문제 하나 풀고 정리(노션 및 깃헙)

[In class]

풀어온 문제 멘티 각자 풀이 공유 및 다같이 트러블 슈팅과 멘토링

새로운 백준 문제 하나 더 풀기 및 공유, 또다시 트러블 슈팅과 멘토링

[After class]

모임 내 푼 문제에 대해 스스로 노션 정리

 

 우리 튜터링의 운영규칙. 어떻게 보면 기본적이고, 단순하다고 볼 수 있다. 그런데 실은 이 모든 과정의 주체는 스스로이기 때문에, 매 과정에서 나의 의지를 가지고 활동에 임하게 된다. 1~2문제를 제대로 푸는 것이 많은 문제를 흐지부지 푸는 것보다 효과적이라고 생각한다. 물론 많은 문제를 제대로 푸는 것이 베스트이겠지만, 꾸준히 이를 지키기 위해 최소한의 문제를 풀고 있다. 

.

.

.

.

.

1주차

접근과정 - sudo code 그려보기

문해기 전공수업시간에 교수님이 강조하셨던 문제접근방법을 떠올려 그 순서대로 문제를 접근했다.

‘문제 인식 → 구상 및 계획 (sudo code) → 코드 작성 → Test 및 error 수정 → 주석달기’

문제를 소리내서 읽어보고 접근했다.

  1. 사실 이런 식으로 필요하다고 생각되는 것들을 먼저 써 내려갔다. 저 과정들을 설명해 보자면, 우선 input으로 받아야 하는 값들을 정리(array 갯수, array들)하고 그 변수들을 어떻게 굴릴건지 생각했다.
  2. 이후 점수를 받는 변수와 점수의 총합을 받는 변수가 필요하다고 생각해 각각의 변수들(sum, score)를 선언했다.
  3. input 값 중, array 갯수를 받는 변수를 이용해 for 문을 구상하고, if문을 활용해 ‘O’ 와 ‘X’ 일 때를 구분하여 각각 필요한 과정을 구상했다.

처음 스스로 구상한 코드

 

에러가 떠서 좀 애를 먹었다. 그래서 이 부분을 멘토님과 되짚어보면서 수정해야 할 부분들을 정리했다.

오류가 난 이유들

  • str[0]과 str[j]를 굳이 구분할 필요가 없었는데 구분했다. 이 부분은 지금 생각해봤을 때, 그 사고과정이 기억나지 않는다. 다음엔 주석을 좀 더 꼼꼼히 써야겠다는 생각이 든다.
  • int j 를 이용한 for문에서 j의 최대값을 10으로 설정한 점. input을 꼼꼼하게 보지 않아 생긴 문제였다. 그래서 앞서 str를 선언한 것처럼 80으로 수정했다. → 80으로 설정하니 특정 array에서 정확한 값으로 연산되지 않는 상황을 발견했다. 결국 array(str)가 null 값을 갖기 전까지로 조건문을 수정한 후 에러를 해결할 수 있었다.
  • 총합 값에 점수를 더하는 코드를 else일 때(X일 때) 넣어야한다고 판단했는데, O일때 그 코드를 넣어야한다는 것을 새롭게 깨닫게 되었다. 그래야 총합값에 각 점수가 누적될 수 있었다.
  • 그리고 sum과 score을 새로운 array 시작할 때 초기화해야 한다는 것도 깨달았다. 즉, int i를 이용한 for문에 sum과 score을 각각 0으로 초기화하는 코드가 필요한 것.

최종적으로 완성한 코드

앞서 발견한 오류들을 수정사항들을 확인하고 반영한 최종 코드.

 

=> 튜터링에서 처음으로 풀이과정을 길게 써본 코드. 마침 문해기 교수님께서 문제 풀이에 대해 강조하실 때여서 풀이과정에 적용해보기 좋았던 기억이 난다. (당일에 TIL을 썼더라면,, 더 좋았겠지?) 문제는 C언어 리뷰에 적합한 문제로 선정되었고, 배열개념이 약하다고 느꼈던 나에게 빈틈을 채우기 적합한 문제였다. 수도코드 구상, 오류 정확히 판단하기를 제대로 해본 코드 풀이였다.

멘토님이 노션에 댓글도 달아주셨다 히히

.

.

.

.

.

2주차

문제 인식하기

input: 입력값 M,N은 완전제곱수를 구하는 각각의 범위.

특징으로는 첫째 줄에 M, 둘째 줄에 N 입력. M과 N은 10000이하의 자연수이며 M은 N보다 같거나 작다는 것.

output: 주어진 입력값 M이상 N이하 범위에서 완전제곱수를 찾아 총합과 가장 작은 완전제곱수를 차례대로 출력한다. 단, M이상 N이하의 자연수 중 완전제곱수가 없을 경우는 첫째 줄에 -1을 출력한다.

문제 접근하기

처음에는 완전제곱수를 어떻게 판별하지? 라는 막연한 생각이 들었다.

https://youtu.be/X7yDU4aUULc?si=NxscjHWEzrAO0RYM

그래서 결국 완전제곱수 판별하는 원리에 대한 영상을 찾아보고 이해했다. 이제는 도움을 받았으니 내걸로 만들기 위해 다시 한번 내용을 정리해보자.

<완전 제곱수의 약수의 갯수는 항상 홀수다.>

약수의 갯수: (지수+1)개

따라서 a의 제곱, (a의 세제곱)의 제곱, ((a의 세제곱)*(b의 제곱))의 완전제곱이 주어져도 각각

(2+1)개, (32+1)개, ((32+1)(22+1))개로 언제나 홀수다.

이 원리를 이용하여 code 짜기 start

코드 작성하기

<첫시도>

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h>

int main() { int M, N; int little = 0; int sum = 0; scanf("%d", &M); scanf("%d", &N);

for (int i = M; i <= N; i++) {
	int num = 0;
	for (int j = 1; j <= i; j++) {
		if (i % j == 0) {
			num++;
			/*최소값을 어떻게 완전제곱수 총합보다 뒤에 출력할까*/
		}
	}
}

→ 이제 완전제곱수 판별의 원리도 알았겠다, 호기롭게 도전했으나

최솟값을 어떻게 변수에 저장하고 완전제곱수의 총합보다 뒤에 출력할 것인가하는 장애물 봉착.

포기하기엔 이미 감을 잡았다는 생각이 들어서(!!) 무지성 총합 구하기 코드로 진도를 나갔다.

<돌파를 통해 깨우치다>

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h>

int main() { int M, N; int little = 0; int sum = 0; scanf("%d", &M); scanf("%d", &N);

for (int i = M; i <= N; i++) {
	int num = 0;
	for (int j = 1; j <= i; j++) {
		if (i % j == 0) {
			num++;
			/*최소값을 어떻게 완전제곱수 총합보다 뒤에 출력할까 -> 라고 고민했는데 해결 완료!*/
		}
	}
	if (num % 2 == 1) {
		sum = sum + i;
		if (little == 0) {
			little = little + i;
		}
	}
}
	printf("%d\\\\n", sum);
	printf("%d", little);
}

→ 그렇게 총합 연산 코드를 작성하다보니 if 문을 이용해 조건을 제시하여 가장 작은 완전제곱수를 구할 수 있는 방법을 알아차리게 되었다. 여기서 얻은 교훈은 모르는 부분이 나오더라도 할 수 있는 부분이라도 작성해보기.

이렇게 해결이 된 줄 알았으나, 마지막 한 단계가 더 남았다.

바로 “단, M이상 N이하의 자연수 중 완전제곱수가 없을 경우는 첫째 줄에 -1을 출력한다.”라는 출력 조건을 놓쳤던 것! 지금 작성하고 있는 노션정리 과정을 통해 알게 되었다. 여기서 얻은 교훈이 바로 “문제의 조건을 꼼꼼히 분석하는 습관 들이기&문제풀이 정리하는 습관 들이기”

<최종코드>

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h>

int main() { int M, N; int little = 0; int sum = 0; scanf("%d", &M); scanf("%d", &N);

for (int i = M; i <= N; i++) {
	int num = 0;
	for (int j = 1; j <= i; j++) {
		if (i % j == 0) {
			num++;
			/*최소값을 어떻게 완전제곱수 총합보다 뒤에 출력할까 -> 라고 고민했는데 해결 완료!*/
		}
	}
	if (num % 2 == 1) {
		sum = sum + i;
		if (little == 0) {
			little = little + i;
		}
	}
}
if (sum != 0) {
	printf("%d\\\\n", sum);
	printf("%d", little);
}
else {
	printf("-1");
}
}

짜잔

 

이 문제도 기억에 남는 이유는 포기하지 않고 끝까지 할 수 있는 것을 작성하다가 마침내 돌파구를 얻은 경험을 했기 때문이다. 코드 작성 경험이 많지는 않지만, 이전의 나는 한 번 막히는 부분이 있으면 조금 고민해보다가 그 문제를 포기한 경우가 대부분이었다. 그런데 이 문제를 풀 때는, 정말 끝까지 풀고싶다는 마음에 할 수 있는 것부터 먼저 차근차근 밟는 경로를 택했다. 그러다 보니 막혔던 부분에 대해 사고가 환기되면서 위 기록처럼 마침내 코드를 완성할 수 있었다. 또한 이 코드를 작성한 과정이 특별한 이유는 모르는 부분을 유튜브 강의나 인터넷으로 찾아보며 스스로 학습한 경험이 있기 때문이기도 하다. 이러한 모든 경험은 교훈이 되어 앞으로의 나의 올바른 프로그래밍 습관이 될 것이다.

.

.

.

.

.

3주차

문제 인식하기

input: 학생 N명의 몸무게와 키

첫 줄에는 전체 사람의 수 N, 이어지는 N개의 줄에는 각 사람의 몸무게와 키를 나타내는 양의 정수 x와 y가 하나의 공백을 두고 각각 나타난다.

  • 2 ≤ N ≤ 50
  • 10 ≤ x, y ≤ 200

output: 각 사람의 덩치 등수를 계산하여 입력된 순서대로 첫 줄에 출력. 단, 각 덩치 등수는 공백문자로 분리되어야 함.

문제 접근하기

과제로도 몇번 구조체를 써봤겠다! 싶은 자신감에 무작정 코드짜기 돌입. 그러다가 순간 for문과 if문을 여러 개 사용해야 하는 부분에서 확신이 들지 않아 손으로 시뮬레이션을 그려봤다.

코드를 작성하기 전에 이 부분에 대해 미리 구체적으로 구상했다면, 코드를 더욱 빠르고 간편하게 짤 수 있었을 것 같다.

코드 작성하기

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h>

struct EMPRECORD{ int weight; int height; int score; };

int main() { int N; /총 비교군의 수(사람 수)/ struct EMPRECORD build[51]; /array 선언/ scanf("%d", &N); for (int i = 0; i < N; i++) { scanf("%d %d", &build[i].weight, &build[i].height); } for (int i = 0; i < N; i++) { build[i].score = 1; }

/*input 값들 인식완료*/
for (int j = 0; j < N; j++) {
	for (int k = 0; k < N; k++) {
		if (j != k) {
			if (build[j].weight > build[k].weight && build[j].height > build[k].height) {
				build[k].score++;
			}
		}
	}
}
for (int l = 0; l < N; l++) {
	printf("%d ", build[l].score);
}

}

<실행결과>

 이 코드는 TIL(Today I Learned)의 본질에 걸맞는다고 볼 수 있겠다. 오늘 작성한 따끈따끈한 코드! 최근 전공 수업의 과제가 자주, 많이 주어졌는데, 그걸 해결하면서 자연스레 개념에 대한 이해도와 자신감이 높아져 있는 나를 실감할 수 있었다. 그렇지만 프로그래밍 단계에 무작정 덤비는 것은 길을 돌아가는 것이라는 걸 다시금 깨우쳤다. 간단하게라도 가장 중요한 연산(조건문)은 수도코드를 반드시 그려보고 프로그래밍을 시작해야겠다.

 

 조금은 길어진 것 같지만, 어쩔 수 없다. 그동안 미룬 것이 있으니.

 미룬 것에 대한 반성을 하고, 다시 쓰자!! 진심으로 화이팅

'studylog' 카테고리의 다른 글

231015~16 TIL  (2) 2023.10.16
231013 TIL  (2) 2023.10.13
230924 TIL  (0) 2023.09.24
230923 TIL  (0) 2023.09.23
230922 TIL  (0) 2023.09.22