[015] 알고리즘 연습문제 / algorithm with python

이연희·2023년 8월 25일

알고리즘 수업을 마치고, 어제부터 이틀 연속 연습문제를 풀었다.
나는 연습문제 풀고, 강의 들으면서 해설강의 들으면 이틀이 꼬박 걸리는데, 다들 하루만에 이걸 다 끝낸다는 건가....?
아차 싶었던 문제랑 전혀 풀지 못했던 문제를 복습하면서 오늘 공부를 마무리하겠다.

Q1. 최빈값과 알고리즘을 사용한 나이 분포 그래프 출력하기

→ 강사님 코드

먼저 모듈 만든다. 이때 빈도수를 구하기 위해서, 먼저 최댓값을 구하는 maxMod라는 이름의 모듈을 만들어 준다.

# 최댓값을 구하는 모듈 maxMod를 만들어 준다.
class MaxAlgorithm:

    def __init__(self, ns):
        self.nums = ns
        self.maxNum = 0
        self.maxNumIdx = 0


    def setMaxIdxAndNum(self):
        self.maxNum = 0
        self.maxNumIdx = 0

        for i, n in enumerate(self.nums):
            if self.maxNum < n:
                self.maxNum = n
                self.maxNumIdx = i


    def getMaxNum(self):
        return self.maxNum

    def getMaxIdx(self):
        return self.maxNumIdx

앞서 만든 maxMod를 활용하여 나이별 빈도수를 구하고, 그래프도 간단하게 출력하는 모듈, modeMod를 만들어 준다.

# 먼저구한 최댓값 모듈 maxMod를 이용해서 빈도수 그래프를 구하는 모듈 modeMod를 만들어준다.

import maxMod

class ModeAlgorithm:

    def __init__(self, ns, mn):
        self.nums = ns
        self.maxNum = mn
        self.indexes = []

    def setIndexList(self):
        self.indexes = [0 for i in range(self.maxNum+1)]

        for n in self.nums:
            self.indexes[n] = self.indexes[n] + 1

    def getIndexList(self):
        if sum(self.indexes) == 0:
            return None
        else:
            return self.indexes


    def printAges(self):

        n=1
        while True:

            maxAlo = maxMod.MaxAlgorithm(self.indexes)
            maxAlo.setMaxIdxAndNum()
            maxNum = maxAlo.getMaxNum()
            maxNumIdx = maxAlo.getMaxIdx()

            if maxNum == 0:
                break

            print(f'[{n:0>3}]  {maxNumIdx} year-old \t Counts: {maxNum} \t', end='')       #3자리로 오른쪽 정렬, 비어있는 자리 0으로 채우기
            print('+' * maxNum)
            self.indexes[maxNumIdx] = 0

            n += 1

이제 실행파일로 모듈을 활용하여 데이터를 출력해준다.

import modeMod
import maxMod

ages = [25, 27, 27, 24, 31, 34, 33, 31, 29, 25,
        45, 37, 38, 46, 47, 22, 24, 29, 33, 35,
        27, 34, 37, 40, 42, 29, 27, 25, 26, 27,
        31, 31, 32, 38, 25, 27, 28, 40, 41, 34]
print(f'employee ages: {ages}')
print(f'employee cnt: {len(ages)}')


maxAlo = maxMod.MaxAlgorithm(ages)

maxAlo.setMaxIdxAndNum()
maxAge = maxAlo.getMaxNum()
print(f'maxAge: {maxAge}')

modAlo = modeMod.ModeAlgorithm(ages,maxAge)
modAlo.setIndexList()
print(f'IndexList: {modAlo.getIndexList()}')

modAlo.printAges()

→ 내 코드

ages = [25, 27, 27, 24, 31, 34, 33, 31, 29, 25,
        45, 37, 38, 46, 47, 22, 24, 29, 33, 35,
        27, 34, 37, 40, 42, 29, 27, 25, 26, 27,
        31, 31, 32, 38, 25, 27, 28, 40, 41, 34]
print(f'ages: {ages}')
print(f'employee cnt: {len(ages)}')

maxIdx = 0
maxAge = ages[0]

for idx, age in enumerate(ages):
    if maxAge < age:
        maxIdx = idx
        maxAge = age

print(f'maxAge: {maxAge}')


indexList = [0 for i in range(maxAge+1)]
print(f'length: {len(indexList)}')

for i in ages:
    indexList[i] += 1
    cnt = '+' * indexList[i]
    print(f'[{i}] Age: {i} \t Count : {indexList[i]} \t {cnt}')

대충 그래프 형식을 출력하기에 급급해서 모듈을 따로 만드는 여유도 없었고, 무엇보다 어떻게든 그래프를 내림차순 정렬로 이쁘게 만들고 싶었지만 실패했다.... 심지어 대괄호 안에 인덱스 대신에 자꾸만 직원들 나이가 출력돼서(ㅋㅋㅋ).... 빈도수 구하는 방식은 얼추 아는데 어떻게든 거기에 끼워 맞추려니 제대로 출력될 리가 없었다.
.
.
.
.

Q2. 근삿값 알고리즘과 BMI표를 이용해서 신체 상태를 출력하는 프로그램 만들기

핵심은 만약에 BMI지수가 18.4이 나오든 18.6이 나오든 근삿값은 18.5이 되지만, 신체 상태는 각각 '저체중'과 '정상'으로 갈리는 알고리즘을 만들어야 하는데, 이게 너무 힘들었다.....

모듈을 만들어 준다.

class ApproximationAlgorithm:

    def __init__(self,w,h):

        self.bmiSection = {18.5:['저체중','정상'], 23:['정상','과체중'], 25:['과제중','비만']}
        self.userWeight = w
        self.userHeight = h
        self.userBMI = 0
        self.userCondition = ''
        self.approximateNum = 0
        self.minNum = 25


    def calculatorBMI(self):
        self.userBMI = round(self.userWeight / (self.userHeight ** 2), 2)
        print(f'self.userBMI: {self.userBMI}')


    def printUserCondition(self):
        for n in self.bmiSection.keys():
            absNum = abs(n - self.userBMI)
            if absNum < self.minNum:
                self.minNum = absNum
                self.approximateNum = n
        print(f'self.approximateNum: {self.approximateNum}')

        if self.userBMI <= self.approximateNum:
            self.userCondition = self.bmiSection[self.approximateNum][0]
        else:
            self.userCondition = self.bmiSection[self.approximateNum][1]

        print(f'self.userCondition: {self.userCondition}')

실행파일에 모듈을 불러와서 출력해준다.

class ApproximationAlgorithm:

    def __init__(self,w,h):

        self.bmiSection = {18.5:['저체중','정상'], 23:['정상','과체중'], 25:['과제중','비만']}
        self.userWeight = w
        self.userHeight = h
        self.userBMI = 0
        self.userCondition = ''
        self.approximateNum = 0
        self.minNum = 25


    def calculatorBMI(self):
        self.userBMI = round(self.userWeight / (self.userHeight ** 2), 2)
        print(f'self.userBMI: {self.userBMI}')


    def printUserCondition(self):
        for n in self.bmiSection.keys():
            absNum = abs(n - self.userBMI)
            if absNum < self.minNum:
                self.minNum = absNum
                self.approximateNum = n
        print(f'self.approximateNum: {self.approximateNum}')

        if self.userBMI <= self.approximateNum:
            self.userCondition = self.bmiSection[self.approximateNum][0]
        else:
            self.userCondition = self.bmiSection[self.approximateNum][1]

        print(f'self.userCondition: {self.userCondition}')


.
.
.
.

Q3. 사용자가 입력한 정수 두 개를 입력하면 작은 정수와 큰 정수 사이의 모든 정수의 합을 구하는 재귀 알고리즘 만들기

for문을 이용해서 range()범위 안에 작은 수와, 큰 수로 범위를 만들려고 하는데, 이게 사용자가 입력한 두 수가 어떤 게 작은지 큰지 구분하기가 너무 어려웠다. 근데 강사님께서 그냥 0부터 큰 수까지의 총합에서 0부터 작은 수까지의 합을 빼버리셨다!!! 이런 방법이 있다니.....

모듈을 만들어준다.

class NumSum:

    def __init__(self, n1, n2):
        self.bigNum = 0
        self.smallNum = 0
        self.setN1N2(n1,n2)


    def setN1N2(self, n1,n2):
        self.bigNum = n1
        self.smallNum = n2

        if n1 < n2:
            self.bigNum = n2
            self.smallNum = n1


    def addNum(self, n):

        if n <= 1:
            return n

        return n + self.addNum(n-1)


    def sumBetweenNums(self):
        return self.addNum(self.bigNum -1) - self.addNum(self.smallNum)

실행 파일로 출력해준다.

import recursionMod

num1 = int(input('input number1: '))
num2 = int(input('input number2: '))

ns = recursionMod.NumSum(num1,num2)
result = ns.sumBetweenNums()
print(f'result: {result}')


.
.
진도가 쪼끔 밀렸다!! 반성하자

profile
안녕하세요, 데이터 공부를 하고 있습니다.

0개의 댓글