211213-211219 1주차

  • 나의 상태:
    너무 텅텅 비어있어서 뭐부터 넣어야 할지 감이 오지 않습니다
  • 이번 주에 한거:
    html&css 부분 복습
    파이썬 문법, 문법 문제풀이: 특히 리스트, 문자열을 대략적으로만 알고 있었는데 조금 더 깊게 알 수 있었다...!
    알고리즘 기초 문제풀이

1주차 회고에는 단순하게 내가 한 것들 나열보다 알고리즘 문제풀며 느꼈던 의문? 앞으로의 공부방향 등에 대해서 써보려고 합니다

  • 배운거...그리고?

내가 알고 있는 기초 문법으로 코드를 짜려니까 자꾸 말(=코드)가 길어짐
대강 코드를 완성해도 효율적으로 정리하는 법은 어렵다.
(어려운 영어단어 하나를 몰라서 쉬운 말로 풀어쓰다보니 계속 길어지는 것처럼..)

알고리즘 문제를 풀어보고 코드부터 짜기보다는 전체적인 하나의 흐름을 말/그림으로 풀어보기
(나중에 파이썬을 좀 더 자유롭게 쓸 수 있게되면 이걸 코드로 번역(?)할 수 있도록)
예를 들어..
1. 약수를 판별 하려면 나머지가 0이 되면 됨 (n%2==0 이거 사용)
2. 이렇게 걸러낸 애들은 리스트에 추가
3. 그러면 리스트에 추가한 애들 인덱스 숫자를 가지고 원하는 순서의 숫자 빼올 수 있음(k번째를 원하면 list[k-1]처럼)

(여기서부터는 내가 푼 알고리즘 문제)

일단 수포자는 정수, 약수, 소수의 의미조차 네이버에 검색을 해봐야 합니다^^

  1. 어떤 자연수 p, q가 있을 때 p를 q로 나누었을 때 나머지가 0이면 q는 p의 약수
    -> 두개의 자연수 N과 K가 주어졌을 때 N의 약수 중 K번째 숫자를 출력
    -> N, K가 빈칸을 두고 첫째 줄에 주어지고 N은 1이상 10000 이하, K는 1이상 N이하
    -> N의 약수 개수가 K개보다 적어서 K번째 약수가 존재하지 않을 경우 -1 출력

문제만 봐도 머릿속에 떠오르는 건 ???
약수는 어떻게 판별하는지 검색을 해봅니다..ㅎ

내가 작성한 코드

n = int(input('num:' ))
k = int(input('num2:' ))   

divisor = []

for i in range(1, n+1):
    if n%i ==0:
        divisor.append(i)

if len(divisor) < k:
    print(-1)
else:
    # print(len(divisor))
    print(divisor)
    print(k,'번째의 약수: ',divisor[k-1])

(??? 나의 의문점과 그 해결)

a) N과 K를 빈칸을 두고 입력하라는 게 뭐지..?
-> 이걸 이해를 못 하기도 했구 지금 내가 아는 문법으로는 해보려다 보니 N과 K를 따로 입력 받았는데, 한 줄의 코드로 입력 받으라는 뜻
내가 쓴 1~2줄을 아래와 같이 한 줄로 바꿀 수 있다.

N, K=map(int, input('num:').split())

b) 주어지는 N과 K값의 범위는 어쩌라는 거지..?
-> 같은 팀원분의 답변으로는 저건 코드에 입력하는 조건이라기 보다는 저 범위 내에 숫자에서
문제없이 코드가 돌아가도 답이 출력되게 하면 된다구 하셨다.(내가 말을 잘 못 알아 들어서 최대한 쉽게 말씀해 주심..)

  1. 자연수 N입력하면 N까지의 소수 개수 출력. 제한시간 1초.

(내가 처음으로 쓴 코드)

#자연수 n이 소수인지 아닌지를 판정하려면, 2<=p<=n루트값 범위에 있는 모든 소수 p로 n을 나누어 보아, 나누어 떨어지지 않으면 소수이고, 나누어 떨어지면 합성수이다.

import time
import math

n = int(input('enter>>'))

start = time.time()

#소수판별
def isPrime(num):
    for i in range(2,num):
        if num % i == 0:
            return False
    return True

#소수개수구하기
def primeNum(num):
    lst=[]
    count = 0
    for i in range(2, int(math.sqrt(num)+1)):
        if isPrime(i):
            lst.append(i)
    for l in range(2, num+1):
        if isPrime(l):
            count += 1
    # print(count)

    # print(f'소수리스트:{lst}')
    return count

print(f'n의루트값까지소수:{primeNum(n)}개')
end = time.time()
print(f'{end-start:.2f}s')
   

(출력결과)

enter>>100000
n의루트값까지소수:9592개
27.25s

시간이 27초 라구요? 버그 아닌가ㅋㅋ...아님 컴퓨터가 느린거 아닌가요...?....ㅜㅜ

(수정한 코드)

import time
import math


n = int(input('enter>>'))

start = time.time()
#소수판별
def isPrime(num):
    for i in range(2,int(math.sqrt(num)+1)):
        if num % i == 0:
            return False
    return True

def primeNum(num):
    lst=[]
    count = 0
    for i in range(2, num+1):
        if isPrime(i): 
            lst.append(i)
            count += 1
    
    return count

print(f'n의루트값까지소수:{primeNum(n)}개')
end = time.time()
print(f'{end-start:.2f}s')

저 for문 돌리는 곳에서 시간을 엄청 잡아 먹는 것 같았다. 그래서 n의 루트값 for문 돌리는걸 위에 소수판별하는 곳으로 옮겼다. 그러면 숫자 하나하나 2~n 까지 돌려서 소수를 판별하는 곳에서 시간을 많이 쓰는 것 같아서 루트값까지 돌리는 부분은 소수판별하는 곳으로 옮겨봤당

(출력결과)

enter>>100000
9592
n의루트값까지소수:9592개
0.18s

값은 나오긴 했는데 아직까지 저 코드가 돌아가는 순서, 과정들은 아직 확실하게 알지를 못한다. 감으로 이럴거 같으니까 여기다가 옮겨서 해볼까? 이러면서 해결(?)된 부분들이 많다ㅠ.ㅠ
다른 팀원 소스코드 보니까 함수 하나와 이중for문으로 엄청 간결하게 쓰셨던데
아직 난 그정도 경지는 무리야...흑흑
코드를 쓰려고 무작정 붙잡고 늘어지는 것보다 지금 내 수준에서는 알고리즘 과정에 대해 생각해보고 말이나 순서도 같은 걸로 간결하게 정리해 보는 게 좋을 것 같다.

좋은 웹페이지 즐겨찾기