다양한 문제풀이

밤비나·2023년 3월 16일

기초수학 w/python

목록 보기
14/14

약수와 소수

  • 100부터 1000사이의 난수에 대해서 약수, 소수, 소인수를 출력해주는 프로그램
# 약수를 구하는 함수
def get_divisors(num):
    divisors = []
    for i in range(1, num + 1):
        if num % i == 0:
            divisors.append(i)
    return divisors

# 소수인지 아닌지를 판별하는 함수
import math

def is_prime(num):
    if num < 2:
        return False
    for i in range(2, int(math.sqrt(num)) + 1):
        if num % i == 0:
            return False
    return True

# 범위 내의 소수를 구하는 함수
def get_primes(start, end):
    primes = []
    for num in range(start, end + 1):
        if is_prime(num):
            primes.append(num)
    return primes

# 소인수분해를 구하는 함수
def prime_factorization(num):
    prime_factors = []
    div = 2
    while num > 1:
        if num % div == 0:
            prime_factors.append(div)
            num = num // div
        else:
            div += 1
    return prime_factors

import random

start = 100
end = 1000
num = random.randint(start, end)
print("Selected number:", num)

divisors = get_divisors(num)
print("Divisors:", divisors)

primes = get_primes(start, end)
print("Primes between", start, "and", end, ":", primes)

prime_factors = prime_factorization(num)
print("Prime factors:", prime_factors)

# 결과
'''
Selected number: 537
Divisors: [1, 3, 179, 537]
Primes between 100 and 1000 : [101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
Prime factors: [3, 179]
'''

소인수와 소인수 분해

  • 100부터 1000사이의 난수를 소인수분해를 하고 각각의 소인수에 대한 지수를 출력하는 프로그램
import random

def prime_factorization(num):
    prime_factors = []
    div = 2
    while num > 1:
        if num % div == 0:
            prime_factors.append(div)
            num = num // div
        else:
            div += 1
    # 소인수 분해 결과에서 중복을 제거하고, 각 소인수의 지수를 계산하여 리스트로 반환한다.
    result = []
    for factor in prime_factors:
        count = 0
        while factor in prime_factors:
            prime_factors.remove(factor)
            count += 1
        result.append((factor, count))

    return result

start = 100
end = 1000
num = random.randint(start, end)

print("Selected number:", num)

prime_factors = prime_factorization(num)
print("Prime factors:", prime_factors)

result = 1
for factor, count in prime_factors:
    print("{}^{}".format(factor, count))
    result *= factor ** count

print("Result:", result)

'''
Selected number: 306
Prime factors: [(2, 1), (3, 2)]
2^1
3^2
Result: 18
'''

최대공약수

  • 100부터 1000사이의 2개의 난수에 대해서 공약수와 최대공약수를 출력하고, 서로소인지 출력하는 프로그램
import random

# 공약수 구하는 함수
def get_common_divisors(num1, num2):
    # num1과 num2 중 작은 값을 찾아서, 그 값보다 작거나 같은 자연수들 중에서
    # num1과 num2가 모두 나누어 떨어지는 수를 찾습니다.
    smaller = min(num1, num2)
    common_divisors = []
    for i in range(1, smaller + 1):
        if num1 % i == 0 and num2 % i == 0:
            common_divisors.append(i)
    return common_divisors

# 최대공약수 구하는 함수
def get_greatest_common_divisor(num1, num2):
    # num1과 num2의 공약수들을 구합니다.
    common_divisors = get_common_divisors(num1, num2)
    # 공약수들 중 가장 큰 값을 찾아서 반환합니다.
    return max(common_divisors)

# 서로소 여부를 확인하는 함수
def are_coprime(num1, num2):
    # 두 수의 최대공약수를 구합니다.
    gcd = get_greatest_common_divisor(num1, num2)
    # 최대공약수가 1이면 두 수는 서로소입니다.
    return gcd == 1

# 100부터 1000 사이의 두 난수를 생성
num1 = random.randint(100, 1000)
num2 = random.randint(100, 1000)
print("Selected numbers: {} and {}".format(num1, num2))

# 두 수의 공약수를 구하고 출력
common_divisors = get_common_divisors(num1, num2)
print("Common divisors:", common_divisors)

# 두 수의 최대공약수를 구하고 출력
gcd = get_greatest_common_divisor(num1, num2)
print("Greatest common divisor:", gcd)

# 두 수가 서로소인지 확인하고 출력
if are_coprime(num1, num2):
    print("{} and {} are coprime.".format(num1, num2))
else:
    print("{} and {} are not coprime.".format(num1, num2))

'''
Selected numbers: 592 and 344
Common divisors: [1, 2, 4, 8]
Greatest common divisor: 8
592 and 344 are not coprime.
'''

최소공배수

  • 100부터 1000사이의 2개의 난수에 대해서 최대공약수와 최소공배수를 출력하는 프로그램
import random

# 두 수의 최대공약수를 구하는 함수
def gcd(a, b):
    if b == 0:
        return a
    return gcd(b, a % b)

# 두 수의 최소공배수를 구하는 함수
def lcm(a, b):
    return a * b // gcd(a, b)

# 100부터 1000 사이의 두 난수를 생성
start = 100
end = 1000
num1 = random.randint(start, end)
num2 = random.randint(start, end)
print("Selected numbers:", num1, num2)

# 최대공약수 계산
g = gcd(num1, num2)
print("GCD of", num1, "and", num2, "is", g)

# 최소공배수 계산
l = lcm(num1, num2)
print("LCM of", num1, "and", num2, "is", l)

'''
Selected numbers: 370 340
GCD of 370 and 340 is 10
LCM of 370 and 340 is 12580
'''

진법

  • 사용자가 입력한 수를 이용해서, 다음 내용에 따라 진법 변환하는 프로그램
    - 10진수 -> 2, 8 ,16진수 변환
    - X진수 -> 10진수
    - X진수 -> X진수
# 10진수 -> 2, 8, 16진수 변환 함수
def decimal_to_base(num, base):
    if num == 0:
        return '0'
    result = ''
    while num > 0:
        remainder = num % base
        if remainder < 10:
            result = str(remainder) + result
        else:
            result = chr(ord('A') + remainder - 10) + result
        num //= base
    return result


# X진수 -> 10진수 변환 함수
def base_to_decimal(num, base):
    decimal = 0
    power = 0
    for digit in reversed(num):
        if digit.isdigit():
            decimal += int(digit) * base ** power
        else:
            decimal += (ord(digit) - ord('A') + 10) * base ** power
        power += 1
    return decimal


# X진수 -> X진수 변환 함수
def base_to_base(num, base1, base2):
    decimal = base_to_decimal(num, base1)
    result = decimal_to_base(decimal, base2)
    return result


# 메인 함수
def main():
    while True:
        print("\n진법 변환 프로그램")
        print("1. 10진수 -> 2진수")
        print("2. 10진수 -> 8진수")
        print("3. 10진수 -> 16진수")
        print("4. X진수 -> 10진수")
        print("5. X진수 -> Y진수")
        print("6. 종료")
        choice = input("\n원하는 작업을 선택하세요: ")

        if choice == '1':
            decimal = int(input("10진수를 입력하세요: "))
            binary = decimal_to_base(decimal, 2)
            print("2진수:", binary)
        elif choice == '2':
            decimal = int(input("10진수를 입력하세요: "))
            octal = decimal_to_base(decimal, 8)
            print("8진수:", octal)
        elif choice == '3':
            decimal = int(input("10진수를 입력하세요: "))
            hexa = decimal_to_base(decimal, 16)
            print("16진수:", hexa)
        elif choice == '4':
            num = input("X진수를 입력하세요: ")
            base = int(input("진법을 입력하세요: "))
            decimal = base_to_decimal(num, base)
            print("10진수:", decimal)
        elif choice == '5':
            num = input("X진수를 입력하세요: ")
            base1 = int(input("진법을 입력하세요: "))
            base2 = int(input("변환할 수를 입력하세요: "))
            result = base_to_base(num, base1, base2)
            print(base1, "진수", num, "를", base2, "진수로 변환한 결과:", result)
        elif choice == '6':
            print("프로그램을 종료합니다.")
            break
        else:
            print("잘못된 입력입니다. 다시 입력해주세요.")


if __name__ == '__main__':
    main()
    
'''
진법 변환 프로그램
1. 10진수 -> 2진수
2. 10진수 -> 8진수
3. 10진수 -> 16진수
4. X진수 -> 10진수
5. X진수 -> Y진수
6. 종료

원하는 작업을 선택하세요: 5
X진수를 입력하세요: 8
진법을 입력하세요: 17
변환할 진법을 입력하세요: 2
17 진수 8 를 2 진수로 변환한 결과: 1000

'''

등차수열

  • 다음 수열의 일반항을 구하고 n번째 항의 값과 합을 구하는 프로그램
    {4,10,16,22,28,34,40,46,52,58,64...}
# 수열의 일반항: 4 + 6(n-1) (n은 항의 위치)

n = 10
a_n = 4 + 6*(n-1)
a_sum = sum([4 + 6*(i-1) for i in range(1, n+1)])

print("{}번째 항의 값: {}".format(n, a_n))
print("{}번째 항까지의 합: {}".format(n, a_sum))

'''
10번째 항의 값: 58
10번째 항까지의 합: 310
'''

등비수열

  • 다음 수열의 일반항을 구하고, n번째항의 값과 합을 구하는 프로그램
    {2,6,18,54,162,486,1458,4374,13122,...}
def sequence_value(n):
    # n번째 항의 값을 계산하는 함수
    return 2 * 3**(n-1)

def sequence_sum(n):
    # n번째 항까지의 합을 계산하는 함수
    return sum(sequence_value(i) for i in range(1, n+1))

# 10번째 항의 값과 합을 출력합니다.
n = 10
print("n번째 항의 값:", sequence_value(n))
print("n번째 항까지의 합:", sequence_sum(n))

'''
n번째 항의 값: 39366
n번째 항까지의 합: 59048
'''

시그마

  • 첫 째날 쌀 두톨을 받고 둘째 날부터는 하루 전의 2배에 해당하는 쌀을 받는다고 할 때, 30일째 되는 날 받게 되는 쌀의 개수를 수열과 시그마로 나타내고 이를 출력하는 프로그램
    {2,4,8,16,32,64,128,256,512,1024,...}

수열의 일반항: 2^(n-1)
시그마 식: ∑(2^(i-1)) (i=1~30)

n = 30

# 수열 계산
sequence = [2**(i-1) for i in range(1, n+1)]

# 시그마 계산
sigma = sum(sequence)

# 출력
print("수열:", sequence)
print("30일간 받게 되는 쌀의 총 개수:", sigma)

'''
수열: [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912]
30일간 받게 되는 쌀의 총 개수: 1073741823
'''

계차 수열

  • 다음 수열의 일반항을 구하고, n항의 값을 출력하는 프로그램 {2,5,11,20,32,47,65,86,110,137,167,...}
# 첫 번째 항과 공비를 지정
a = 2
r = 3

# 10번째 항까지 출력
for i in range(1, 11):
    # 계차 수열의 일반항을 이용하여 n번째 항의 값을 계산
    an = a + r * (i - 1) * i / 2
    print(f"{i}번째 항의 값: {an}")

# 10번째 항까지의 합을 계산
n = 10
sum = (2 * a + (n - 1) * r) * n / 2
print(f"{n}번째 항까지의 합: {sum}")

'''
1번째 항의 값: 2.0
2번째 항의 값: 5.0
3번째 항의 값: 11.0
4번째 항의 값: 20.0
5번째 항의 값: 32.0
6번째 항의 값: 47.0
7번째 항의 값: 65.0
8번째 항의 값: 86.0
9번째 항의 값: 110.0
10번째 항의 값: 137.0
10번째 항까지의 합: 155.0
'''

피보나치 수열

  • 피보나치 수열에서 n항의 값과 n항까지의 합을 출력하는 프로그램
n = int(input("몇 번째 항까지 계산할까요? "))

# 초기값 설정
a, b = 0, 1
fib_sum = 0

# n번째 항까지 반복하여 값 계산
for i in range(n):
    fib_sum += b
    a, b = b, a + b

# n번째 항의 값 출력
print("n번째 항의 값:", a)

# n항까지의 합 출력
print("n항까지의 합:", fib_sum)

'''
몇 번째 항까지 계산할까요? 10
n번째 항의 값: 55
n항까지의 합: 143
'''

팩토리얼

  • 팩토리얼 프로그램. 재귀 함수를 이용한 프로그램과 파이썬에서 제공하는 모듈을 이용한 경우
  1. 재귀 함수를 이용한 경우
def factorial_recursive(n):
    if n == 1:
        return 1
    else:
        return n * factorial_recursive(n-1)

n = int(input("팩토리얼을 구할 숫자를 입력하세요: "))
print("{}! = {}".format(n, factorial_recursive(n)))

# 6! = 720
  1. 모듈 이용한 경우
import math

n = int(input("팩토리얼을 구할 숫자를 입력하세요: "))
print("{}! = {}".format(n, math.factorial(n)))

# 6! = 720

군 수열

  • 다음 수열을 보고 수열의 합이 최초 100을 초과하는 n번째 항의 값과 n을 출력하는 프로그램
    1/1, 1/2, 2/1, 1/3, 2/2, 3/1, 1/4, 2/3, 3/2, 4/1, 1/5, 2/4, ...
# 초기값 설정
n = 1
nCnt = 1
searchNC = 0
searchNP = 0
sumN = 0
flag = True

# 수열 생성 및 합 계산
while flag:
    # n번째 항 생성
    for i in range(1, n + 1):
        # 수열 출력
        if i == n:
            print('{}/{}'.format(i, n - i + 1), end=' ')
        else:
            print('{}/{},'.format(i, n - i + 1), end=' ')

        # 수열 합 계산
        sumN += i / (n - i + 1)
        nCnt += 1

        # 합이 100을 초과하는 경우
        if sumN > 100:
            searchNC = i
            searchNP = n - i + 1
            flag = False
            break

    # 한 행 출력 후 다음 행으로 이동
    print()
    n += 1

# 결과 출력
print(f'수열의 합이 최초 100을 초과하는 항, 값, 합: {nCnt}항, {searchNC}/{searchNP}, {sumN}')

'''
1/1 
1/2, 2/1 
1/3, 2/2, 3/1 
1/4, 2/3, 3/2, 4/1 
1/5, 2/4, 3/3, 4/2, 5/1 
1/6, 2/5, 3/4, 4/3, 5/2, 6/1 
1/7, 2/6, 3/5, 4/4, 5/3, 6/2, 7/1 
1/8, 2/7, 3/6, 4/5, 5/4, 6/3, 7/2, 8/1 
1/9, 2/8, 3/7, 4/6, 5/5, 6/4, 7/3, 8/2, 9/1 
1/10, 2/9, 3/8, 4/7, 5/6, 6/5, 7/4, 8/3, 9/2, 10/1 
수열의 합이 최초 100을 초과하는 항, 값, 합: 56항, 10/1, 105.81190476190476
'''

순열

  • N과 R값을 사용자에게 입력 받아 순열들의 값을 구하는 프로그램
from math import factorial

# 사용자로부터 N과 R 값을 입력 받음
N = int(input("N 값을 입력하세요: "))
R = int(input("R 값을 입력하세요: "))

# 순열 계산
result = factorial(N) // factorial(N - R)

# 결과 출력
print(f"{N}개 중에서 {R}개를 선택하는 순열의 개수는 {result}개 입니다.")

'''
N 값을 입력하세요: 9
R 값을 입력하세요: 4
9개 중에서 4개를 선택하는 순열의 개수는 3024개 입니다.
'''

조합

import math

n = int(input("n value: "))
r = int(input("r value: "))

result = math.comb(n, r)

print("{}과 {}의 조합 {}".format(n, r, result))

'''
n value: 7
r value: 3
7과 3의 조합 35
'''

확률

  • 박스에 '꽝'이 적힌 종이가 6장 있고, '선물'이 적힌 종이가 4장이 있을 때, 파이썬을 이용해서 '꽝' 3장과 '선물' 3장을 뽑는 확률을 출력하는 프로그램
import math
# 꽝이 6장, 선물이 4장일 때, 꽝 3장과 선물 3장을 뽑을 확률
n1 = math.comb(6, 3)  # 6개의 꽝 중 3개를 뽑는 경우의 수
n2 = math.comb(4, 3)  # 4개의 선물 중 3개를 뽑는 경우의 수
n3 = math.comb(10, 6)  # 10개의 종이 중 6개를 뽑는 경우의 수

prob = (n1 * n2) / n3  # 꽝 3장과 선물 3장을 뽑을 확률

print("꽝 3장과 선물 3장을 뽑을 확률: %.2f%%" % (prob * 100))

# 꽝 3장과 선물 3장을 뽑을 확률: 38.10%
profile
씨앗 데이터 분석가.

0개의 댓글