제로베이스 데이터 파트타임 스쿨 학습 일지 [25.04.16]

[강의 요약]

[Part 02. 수학_Ch 01. 기초 수학] 강의 수강

31_[연습문제] 약수와 소수부터 37_[연습문제] 등비수열까지 강의 수강하였음

🐢 100일 챌린지 🔥 : [▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰░                                         ] 31/100일 (31%)

 

 

 

 

 

[연습문제_약수와 소수]

  • 약수 : 나누어 떨어지는 수
  • 소수 : 1 외에 약수가 자기 자신 뿐인 수
  • 소인수 : 약수(인수)이면서 소수인 수

▶ 코드

100부터 1000사이의 난수에 대해서 약수, 소수, 그리고 소인수를 출력하는 프로그램을 만들어보자

import random

# 100 ~ 1000 사이의 정수 중 난수 생성
rNum = random.randint(100, 1000)
print(f'rNum: {rNum}')

for num in range(1, rNum + 1):
    soinsuFlag = 0  # 소인수 판별용 플래그

    # 약수 출력
    if rNum % num == 0:
        print(f'[약수]: {num}')
        soinsuFlag += 1

    # 소수 판별
    if num != 1:
        flag = True
        for n in range(2, num):
            if num % n == 0:
                flag = False
                break
        if flag:
            print(f'[소수]: {num}')
            soinsuFlag += 1

    # 소인수 출력: 약수이면서 소수일 경우
    if soinsuFlag >= 2:
        print(f'[소인수]: {num}')
  • random.randint()를 이용해 100~1000 사이의 수 생성
  • 약수는 % 연산을 이용해 나누어 떨어지는지 판단
  • 소수는 2부터 자기 자신보다 작은 수까지 나누어보며 판별
  • 소인수는 약수이면서 동시에 소수인 경우만 출력
  • soinsuFlag 플래그는 해당 수가 약수인지 + 소수인지 체크하는 데 활용됨

 

★ 출력 결과 ★

rNum: 120
[약수]: 1
[소수]: 2
[약수]: 2
[소인수]: 2
[약수]: 3
[소수]: 3
[소인수]: 3
...
[약수]: 5
[소수]: 5
[소인수]: 5
...

 

 

 

 

[연습문제_소인수와 소인수분해]

소인수분해 : 어떤 수를 소수의 곱으로 표현하는 것

▶ 코드 

100부터 1000사이의 난수를 소인수분해를 하고 각각의 소인수에 대한 지수를 출력하는 프로그램을 만들어보자

import random

# 100~1000 사이의 난수 생성
rNum = random.randint(100, 1000)
print(f'rNum: {rNum}')

soinsuList = []  # 소인수를 저장할 리스트

n = 2
while n <= rNum:
    if rNum % n == 0:
        print(f'소인수: {n}')
        soinsuList.append(n)
        rNum /= n
    else:
        n += 1

# 소인수 리스트 출력
print(f'soinsuList: {soinsuList}')

# 소인수별 등장 횟수(지수) 출력
tempNum = 0
for s in soinsuList:
    if tempNum != s:
        print(f'{s}\'s count: {soinsuList.count(s)}')
        tempNum = s
  • while문을 사용해 가장 작은 소수부터 나눠가며 소인수 추출
  • soinsuList에 소인수를 저장하고, count()로 지수 계산
  • 중복된 출력 방지를 위해 tempNum 변수를 사용해 중복 체크

 

★ 출력 결과 ★

rNum: 360
소인수: 2
소인수: 2
소인수: 2
소인수: 3
소인수: 3
소인수: 5
soinsuList: [2, 2, 2, 3, 3, 5]
2's count: 3
3's count: 2
5's count: 1

 

 

 

 

[연습문제_최대공약수]

▶ 코드 

100부터 1000사이의 2개의 난수에 대해서 공약수와 최대공약수를 출력하고,

서로소(공약수가 1뿐인 경우)인지 출력하는 프로그램을 만들어보자.

import random

rNum1 = random.randint(100, 1000)
rNum2 = random.randint(100, 1000)

print(f'rNum1: {rNum1}')
print(f'rNum2: {rNum2}')

maxNum =0
for n in range(1, (min(rNum1, rNum2) + 1)):
    if rNum1 % n == 0 and rNum2 % n == 0:
        print(f'공약수: {n}')
        maxNum = n

print(f'최대공약수: {maxNum}')

if maxNum == 1:
    print(f'{rNum1}과 {rNum2}는 서로소이다.')
  • random.randint()로 난수 2개를 생성
  • for 반복문으로 두 수의 공약수를 찾고, 그중 가장 큰 값을 저장
  • 최대공약수가 1이면 두 수는 서로소로 판단
  • 반복문과 조건문만으로도 간단하게 구현 가능

 

★ 출력 결과 ★

rNum1: 120
rNum2: 91
공약수: 1
최대공약수: 1
120과 91는 서로소이다.

 

 

 

 

[연습문제_최소공배수]

  • 공식
    • LCM(a, b) = (a × b) // GCD(a, b)

▶ 코드

100부터 1000사이의 2개의 난수에 대해서 최대공약수와 최소공배수를 출력하는 프로그램을 만들어보자

import random

rNum1 = random.randint(1, 100)
rNum2 = random.randint(1, 100)

print(f'rNum1: {rNum1}')
print(f'rNum2: {rNum2}')

maxNum = 0
for n in range(1, (min(rNum1, rNum2) + 1)):
    if rNum1 % n == 0 and rNum2 % n == 0:
        print(f'공약수: {n}')
        maxNum = n

print(f'최대공약수: {maxNum}')

minNum = (rNum1 * rNum2) // maxNum
print('최소공배수: {}'.format(minNum))
  • 최대공약수는 for문을 통해 공약수를 모두 탐색하고 최댓값을 저장
  • 최소공배수는 두 수의 곱을 최대공약수로 나누는 공식으로 효율적 계산 가능

 

★ 출력 결과 ★

rNum1: 30
rNum2: 45
공약수: 1
공약수: 3
공약수: 5
공약수: 15
최대공약수: 15
최소공배수: 90

 

 

 

 

[연습문제_진법]

▶ 코드

dNum = int(input('10진수 입력: '))

# 10진수 > 2, 8, 16진수
print('2진수: {}'.format(bin(dNum)))
print('8진수: {}'.format(oct(dNum)))
print('16진수: {}'.format(hex(dNum)))


# X진수 -> 10진수
print('2진수(0b10101) -> 10진수({})'.format(int('0b10101', 2)))
print('8진수(0o135) -> 10진수({})'.format(int('0o135', 8)))
print('16진수(0x5f) -> 10진수({})'.format(int('0x5f', 16)))


# X진수 -> X진수
print('2진수(0b10101) -> 8진수({})'.format(oct(0b10101)))
print('2진수(0b10101) -> 10진수({})'.format(int(0b10101)))
print('2진수(0b10101) -> 16진수({})'.format(hex(0b10101)))


print('8진수(0o675) -> 2진수({})'.format(bin(0o675)))
print('8진수(0o675) -> 10진수({})'.format(int(0o675)))
print('8진수(0o675) -> 16진수({})'.format(hex(0o675)))


print('16진수(0x45d) -> 2진수({})'.format(bin(0x45d)))
print('16진수(0x45d) -> 8진수({})'.format(oct(0x45d)))
print('16진수(0x45d) -> 10진수({})'.format(int(0x45d)))
  • 10진수를 다른 진법으로 변환할 때: bin(), oct(), hex()
  • 문자열로 된 진법 값을 10진수로 변환할 때: int(문자열, 진법)
  • 진법 간 변환은 우선 int()로 10진수로 바꾼 뒤 다시 bin(), oct(), hex()를 이용하면 편리함
  • 각 진법은 고유 접두어(0b, 0o, 0x)를 사용해 구분함

 

★ 출력 결과 ★

10진수 입력: 125
2진수: 0b1111101
8진수: 0o175
16진수: 0x7d
2진수(0b10101) -> 10진수(21)
8진수(0o135) -> 10진수(93)
16진수(0x5f) -> 10진수(95)
2진수(0b10101) -> 8진수(0o25)
2진수(0b10101) -> 10진수(21)
2진수(0b10101) -> 16진수(0x15)
8진수(0o675) -> 2진수(0b110111101)
8진수(0o675) -> 10진수(445)
8진수(0o675) -> 16진수(0x1bd)
16진수(0x45d) -> 2진수(0b10001011101)
16진수(0x45d) -> 8진수(0o1055)
16진수(0x45d) -> 10진수(1117)

 

 

 


[연습문제_등차수열]

  • 일반항 공식
    • an = a₁ + (n - 1) × d
  • 합 공식
    • sn = n(a₁ + an) / 2

▶ 코드

inputA1 = int(input('a1 입력: '))
inputD = int(input('공차 입력: '))
inputN = int(input('n 입력: '))

valueN = 0
sumN = 0
n = 1
while n <= inputN:

    if n == 1:
        valueN = inputA1
        sumN += valueN
        print('{}번째 항의 값: {}'.format(n, valueN))
        print('{}번째 항까지의 합: {}'.format(n, sumN))
        n += 1
        continue

    valueN += inputD
    sumN += valueN
    print('{}번째 항의 값: {}'.format(n, valueN))
    print('{}번째 항까지의 합: {}'.format(n, sumN))
    n += 1

print('{}번째 항의 값: {}'.format(inputN, valueN))
print('{}번째 항까지의 합: {}'.format(inputN, sumN))





# 등차 수열(일반항) 공식: an = a1 + (n-1) * d
valueN = inputA1 + (inputN-1) * inputD
print('{}번째 항의 값: {}'.format(inputN, valueN))

# 등차 수열(합) 공식: sn = n(a1 + an) / 2
sumN = inputN * (inputA1 + valueN) / 2
print('{}번째 항까지의 합: {}'.format(inputN, int(sumN)))

 

  • 등차수열은 일정한 공차를 기준으로 항이 증가
  • while문을 통해 순차적으로 항과 합을 누적하며 출력 가능
  • 수식(an, sn)을 이용하면 반복 없이도 원하는 값을 바로 계산 가능

 

★ 출력 결과 ★

a1 입력: 4
공차 입력: 6
n 입력: 5
1번째 항의 값: 4
1번째 항까지의 합: 4
2번째 항의 값: 10
2번째 항까지의 합: 14
3번째 항의 값: 16
3번째 항까지의 합: 30
4번째 항의 값: 22
4번째 항까지의 합: 52
5번째 항의 값: 28
5번째 항까지의 합: 80
5번째 항의 값: 28
5번째 항까지의 합: 80

 

 

 


[연습문제_등비수열]

▶ 코드

inputA1 = int(input('a1 입력: '))
inputR = int(input('공비 입력: '))
inputN = int(input('n 입력: '))

valueN = 0
sumN = 0
n = 1

# 반복문을 통한 항과 합 계산
while n <= inputN:
    if n == 1:
        valueN = inputA1
        sumN += valueN
        print('{}번째 항의 값: {}'.format(n, valueN))
        print('{}번째 항까지의 합: {}'.format(n, sumN))
        n += 1
        continue

    valueN *= inputR
    sumN += valueN
    print('{}번째 항의 값: {}'.format(n, valueN))
    print('{}번째 항까지의 합: {}'.format(n, sumN))
    n += 1

# 일반항 공식 적용
valueN = inputA1 * (inputR ** (inputN - 1))
print('{}번째 항의 값: {}'.format(inputN, valueN))

# 합 공식 적용
sumN = inputA1 * (1 - (inputR ** inputN)) / (1 - inputR)
print('{}번째 항까지의 합: {}'.format(inputN, int(sumN)))
  • 등비수열은 항마다 일정한 공비를 곱해가는 수열
  • 반복문을 통해 수열의 흐름을 시각적으로 확인 가능
  • 수식 사용 시 반복 없이도 원하는 항과 합을 빠르게 계산 가능
  • r = 1인 경우 합 공식이 적용되지 않으므로 예외처리 필요할 수 있음

 

 

★ 출력 결과 ★

a1 입력: 2
공비 입력: 3
n 입력: 5
1번째 항의 값: 2
1번째 항까지의 합: 2
2번째 항의 값: 6
2번째 항까지의 합: 8
3번째 항의 값: 18
3번째 항까지의 합: 26
4번째 항의 값: 54
4번째 항까지의 합: 80
5번째 항의 값: 162
5번째 항까지의 합: 242
5번째 항의 값: 162
5번째 항까지의 합: 242

 

 

 

 

[나의 생각 정리]

알고있던 이론적인 내용(공식)을 파이썬 코드로 구현하면서 복습할 수 있었다.

 

 

[적용점]

반복문을 먼저 활용하고, 이후 수식을 적용해 결과를 검산하는 방식으로 연습하면 좋을 것 같다.

공비가 1일 때는 합 공식이 적용되지 않으므로 코드 작성 시 조건 처리에 신경을 써야 한다.

 

 

 

“이 글은 제로베이스 데이터 스쿨 주 3일반 강의 자료 일부를 발췌하여 작성되었습니다.”