[Zero-Base DS]스터디노트_기초수학(01)

HAHAHAEUN·2024년 3월 20일
post-thumbnail

주요 학습 내용

1. 약수와 소수

2. 소인수와 소인수분해

3. 최대공약수

4. 최소공배수

5. 진법

6. 등차수열

7. 등비수열

8. 계차수열

I. 약수와 소수

  • 약수 구하기
inputNumber = int(input('0보다 큰 정수 입력: '))

lists = []
for i in range(1, inputNumber + 1):
    if inputNumber % i == 0:
        lists.append(i)
        print(f'{inputNumber}의 약수: {i}')

출력 결과 :

  • 소수 구하기
inputNum = int(input('0보다 큰 정수 입력: '))

for i in range(2, inputNum + 1):  # 1은 소수에서 제외
    flag = True
    for n in range(2, i):  # 입력 수 = 4 이면, 2~4까지, 5이면 2~5까지
        if i % n == 0:
            flag = False  # 중간에 나눠지는 수 있으면, 소수 X (flag = False), break
            break

    if flag:
        print('{}: 소수'.format(i))
    else:
        print('{}:\t\t합성수'.format(i))

출력 결과 :

II. 소인수와 소인수분해

  • 소인수: 약수(인수) 중에서 소수인 숫자
  • 소인수분해: 1보다 큰 정수를 소인수의 곱으로 나타낸 것
    소인수분해를 이용해서 약수를 정확하고 쉽게 구할 수 있음
inputNumber = int(input('1보다 큰 정수 입력: '))

n = 2
searchNumbers = []

while n <= inputNumber:
    if inputNumber % n == 0:
        print(f'소인수: {n}')
        if searchNumbers.count(n) == 0:  # .count() = 개수 구해줌
            searchNumbers.append(n)
        elif searchNumbers.count(n) == 1:
            searchNumbers.remove(n)  # 현재 개수가 홀수인 소인수를 찾고 있으므로, 1개 있는데 +1 = even => 제거함
        inputNumber /= n  # 반복 진행
        continue
    else:
        n += 1  # 0이 아닌 경우, +1 하여 시도

출력 결과 :

III. 최대공약수

  • 유클리드 호제법

    두 정수 a, b의 최대공약수를 G(a, b)라고 하자.
    정수 a, b, q, r (b ≠ 0)에 대하여 a = bq + r,이면 G(a, b) = G(b, r)가 성립한다.
    〈증명〉
    G(a, b) = g라고 하자. 최대공약수의 성질에 의해 a = a′g, b = b′g이고 G(a′, b′) = 1이다.
    a = bq + r로부터 r = a - bq = g(a′ - b′q) 이고, g는 r의 약수이다.
    G(b, r) = g임을 보이기 위해서는 G(b′, a′ - b′q) = 1임을 보이면 된다.
    귀류법을 적용하여 결론을 부정해보자.
    어떤 정수 d가 존재하여 G(b′, a′ - b′q) =d(≠ 1)라고 하면, b′ = dm, a′ - b′q = dn라고 할 수 있고, a′ = b′q + dn = dmq + dn = d(mq + n) 이므로 G(a′, b′) = 1라는 가정에 모순이다. 따라서 G(b′, a′ - b′q) = 1이므로 G(b, r) = g가 성립한다.

    [출처: 네이버 지식백과]
  • 최대공약수 구하기
num1 = int(input('1보다 큰 정수 입력: '))
num2 = int(input('1보다 큰 정수 입력: '))
maxNum = 0

for i in range (1, num1 + 1):
    if num1 % i == 0 and num2 % i == 0:
        print(f'공약수: {i}')
        maxNum = i

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

출력 결과 :

  • 유클리드 호제법 사용하여 최대공약수 구하기
inputNum1 = int(input('1보다 큰 정수 입력: '))
inputNum2 = int(input('1보다 큰 정수 입력: '))

temp1 = inputNum1
temp2 = inputNum2

while temp2 > 0:
    temp = temp2  # 3번째를 위해 임시로 저장
    temp2 = temp1 % temp2
    temp1 = temp  # temp = temp2로 할당 해놓음

print('{}, {}의 최대공약수: {}'.format(num1, num2, temp1))
# temp1 = temp = temp2

for i in range(1, temp1 + 1):
    if temp1 % i == 0:
        print('{}, {}의 공약수: {}'.format(num1, num2, i))

출력 결과 :

IV. 최소공배수

  • 공배수: 두 개 이상의 수에서 공통된 배수
    1. 소인수분해를 이용하면 최소공배수 및 공배수를 구할 수 있다
    2. 나눗셈을 통해 최소공배수를 구할 수 있다
  • 최소공배수 구하기
# 섬마을에 과일, 생선, 야채를 판매하는 배가 다음 주기로 입항한다고 할 때, 모든 배가 입항하는 날짜를 계산해보기
ship1 = 3; ship2 = 4; ship3 = 5
maxDay = 0

# 우선 1, 2번의 최대공약수 구함
for i in range(1, ship1 + 1):
    if ship1 % i == 0 and ship2 % i == 0:
        maxDay = i
print(f'{ship1}, {ship2}의 최대공약수: {maxDay}')

minDay = (ship1 * ship2) // maxDay
print(f'{ship1}, {ship2}의 최소공배수: {minDay}')

# 구해진 최대공약수, 최소공배수에 3번째수 추가
newMinDay = minDay
for i in range(1, newMinDay + 1):
    if newMinDay % i == 0 and ship3 % i == 0:
        maxDay = i
print(f'{ship1}, {ship2}, {ship3}의 최대공약수: {maxDay}')

minDay = (newMinDay * ship3) // maxDay
print(f'{ship1}, {ship2}, {ship3}의 최소공배수: {minDay}')

출력 결과 :

V. 진법

  • 진법: 특정 숫자 몇 개를 사용하여 수를 표시하는 방법
  1. 10진수를 2진수로 변환
  2. 10진수를 8진수로 변환
  3. 10진수를 16진수로 변환
  4. 2진수를 8진수로 변환
  5. 2진수를 10진수로 변환
  6. 2진수를 16진수로 변환
  7. 8진수를 10진수로 변환
  • 파이썬을 이용한 진법 변환
    1. 2진수(binary): bin(변환 할 숫자입력)
    2. 8진수(octal): oct(변환 할 숫자입력)
    3. 10진수(hexadecimal): hex(변환 할 숫자입력)
    • 변환 결과는 문자열
dNum = 30

print(f'2진수: {bin(dNum)}')
print(f'8진수: {oct(dNum)}')
print(f'16진수: {hex(dNum)}')
print('='*30)

print(f'2진수: {type(bin(dNum))}')
print(f'2진수: {type(oct(dNum))}')
print(f'2진수: {type(hex(dNum))}')
print('='*30)

print('2진수: {}'.format(format(dNum, '#b')))
print('2진수: {}'.format(format(dNum, '#o')))
print('2진수: {}'.format(format(dNum, '#x')))
print('='*30)

print('2진수: {}'.format(format(dNum, 'b')))
print('2진수: {}'.format(format(dNum, 'o')))
print('2진수: {}'.format(format(dNum, 'x')))

print('='*30)
print('{0:#b}, {0:#o}, {0:#x}'.format(dNum, dNum, dNum))
print('{0:#b}, {0:#o}, {0:#x}'.format(dNum))  # 값이 동일하므로, 1개만 써도 됨
print('='*30)

출력 결과 :

VI. 등차수열

  • 등차수열: 연속된 두 항의 차이가 일정한 수열

    등차수열 공식

    • 일반항 : an=a1+(n1)da_n = a_1 + (n-1)*d
    • 등차중앙 : an=(an1+an+1)/2a_n = (a_{n-1} + a_{n+1})/2
    • 등차 수열의 합 : sn=n(a1+an)/2s_n = n(a_1 + a_n)/2
  • 등차수열의 일반항과 합 구하기
    1-1. 일반항 구하기(공식 미사용)

# n번째 항의 값 출력
inputN1 = int(input('a1 입력: '))
inputD = int(input('공차 입력: '))
inputN = int(input('n 입력: '))

valueN = 0
n = 1
while n <= inputN:
    valueN = inputN1 + inputD * (n-1)
    list_a.append(valueN)
    print('{}번째 항의 값: {}'.format(n, valueN))
    n += 1

print('='*30)
print(f'{inputN}번째 항의 값: {valueN}')

출력 결과 :

1-2. 일반항 구하기(공식 사용)

inputN1 = int(input('a1 입력: '))
inputD = int(input('공차 입력: '))
inputN = int(input('n 입력: '))
print('='*30)

valueNN = inputN1 + (inputN - 1)*inputD
print(f'{inputN}번째 항의 값: {valueNN}')

출력 결과 :

  1. 등차수열의 합 구하기(공식 미사용 & 공식 사용)
inputN1 = int(input('a1 입력: '))
inputD = int(input('공차 입력: '))
inputN = int(input('n 입력: '))

valueN = 0
sumN = 0

n = 1
while n <= inputN:
    valueN = inputN1 + inputD * (n - 1)
    sumN += valueN
    print(f'{n}번째 항까지의 합: {sumN}')
    n += 1

print('='*30)
print(f'{inputN}번째 항까지의 합: {sumN}')

# 공식사용
# an = a1 + (n-1)*d
# sn = n(a1 + an) / 2
valueNN = inputN1 + (inputN - 1)*inputD
sumNN = (inputN*(inputN1 + valueNN))/2

print('='*30)
print(f'{inputN}번째 항까지의 합: {int(sumNN)}')
# 파이썬은 나누기 값이 float형식으로 나오므로, int로 바꿔줌

출력 결과 :

VII. 등비수열

  • 등비수열: 연속된 두 항의 비가 일정한 수열

    등비수열 공식

    • 일반항 : an=a1rn1a_n = a_1 * r^{n-1}
    • 등차중앙 : an2=an1an+1a_n^2 = a_{n-1} * a_{n+1}
    • 등차 수열의 합 : sn=a1(1rn)/(1r)s_n = a_1 * (1 - r^n)/(1-r)
  1. 등비수열의 일반항 구하기(공식 미사용 & 공식 사용)
inputN1 = int(input('a1 입력: '))
inputR = int(input('공비 입력: '))
inputN = int(input('n 입력: '))

valueN = 0
n = 1

while n <= inputN:
    if n == 1:
        valueN = inputN1
        print(f'{n}번째 항의 값: {valueN}')
        n += 1
        continue

    valueN *= inputR
    print(f'{n}번째 항의 값: {format(valueN, ',')}')
    n += 1

print('='*30)
print(f'{inputN}번째 항의 값: {format(valueN, ',')}')
print('='*30)

# 공식 사용
# an = a1 * r^(n-1)
valueNN = inputN1 * (inputR ** (inputN - 1))
print(f'{inputN}번째 항의 값: {format(valueNN, ',')}')

출력 결과 :

  1. 등비수열의 합 구하기(공식 미사용 & 공식 사용)
# n번째 항까지의 합을 출력
inputN1 = int(input('a1 입력: '))
inputR = int(input('공비 입력: '))
inputN = int(input('n 입력: '))

valueN = 0
sumN = 0
n = 1

while n <= inputN:

    if n == 1:
        valueN = inputN1
        sumN += valueN
        print(f'{n}번째 항까지의 합: {sumN}')
        n += 1
        continue

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

print('='*30)
print(f'{inputN}번째 항까지의 합: {format(sumN, ',')}')

# 공식 사용
# sn = a1 * (1-(r^n))/(1-r)
# sn = a1 * (1 - r^n)/(1-r)
sumNN = inputN1 * (1 - (inputR ** inputN))/(1-inputR)
print(f'{inputN}번째 항까지의 합: {format(int(sumNN), ',')}')

출력 결괴 :

VIII. 계차수열

  • 계차수열: 어떤 수열의 인접하는 두 항의 차로 이루어진 또 다른 수열

    1-1. 계차수열을 통한 일반항 구하기(공식 미사용)

    for e.g.
    {an} = {3, 7, 13, 21, 31, 43, 57}
    {bn} = {4, 6, 8, 10, 12, 14}

inputAN1 = int(input('a1 입력: '))
inputAN = int(input('an 입력: '))

inputBN1 = int(input('b1 입력: '))
inputBD = int(input('bn 공차 입력: '))

valueAN = 0
valueBN = 0

# bn의 일반항 구하기
n = 1
while n <= inputAN:
    if n == 1:
        valueAN = inputAN1
        valueBN = inputBN1
        print(f'an의 {n}번째 항의 값: {valueAN}')
        print(f'bn의 {n}번째 항의 값: {valueBN}')
        n += 1  # 무한루프에 빠지지 않기 위해 필요
        continue
    valueAN = valueAN + valueBN
    valueBN = valueBN + inputBD
    print(f'an의 {n}번째 항의 값: {valueAN}')
    print(f'bn의 {n}번째 항의 값: {valueBN}')
    n += 1

print('='*30)
print(f'an의 {inputAN}번째 항의 값: {valueAN}')
print(f'bn의 {inputAN}번째 항의 값: {valueBN}')

출력 결과 :

1-2. 계차수열을 통한 일반항 구하기(공식 사용)

bkb_k= b1b_1 +(k-1) d = 2k + 2
k=1n1bk\displaystyle\sum_{k=1}^{n-1}{b_k} = (k - 1)
(b1b_1 + 2(k - 1) + 2)/2 = k2k^2 + k -2 = inputAN2inputAN^2 + inputAN - 2
ana_n = k=1n1bk\displaystyle\sum_{k=1}^{n-1}{b_k} + a1a_1
ana_n = inputAN2inputAN^2 + inputAN - 2 + 3 = inputAN2inputAN^2 + inputAN + 1

inputAN = int(input('an 입력: '))

valueANN = inputAN**2 + inputAN + 1

print('='*30)
print(f'an의 {inputAN}번째 항의 값: {valueANN}')

출력 결과 :

profile
할 거면 제대로 하자

0개의 댓글