문제:

자연수 n을 입력받아 n의 약수를 모두 더한 값을 리턴하는 함수,solution을 완성해주세요.

풀이 방법:

반복문을 1부터 n까지 반복시킨뒤 이를 n과 나누어보아 나머지가 0인 것들만을 answer에 더한 값이 약수의 합니다.

1
2
3
4
5
6
def solution(n):
    answer = 0
    for i in range(1,n+1):
        if n%i==0:
            answer+=i
    return answer
cs


문제:

트럭 여러 대가 강을 가로지르는 일 차선 다리를 정해진 순으로 건너려 합니다. 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 알아내야 합니다. 트럭이 1초에 1만큼 움직이며, 다리 길이는 bridge_length이고 다리는 무게 weight까지 견딥니다.
solution 함수의 매개변수로 다리 길이 bridge_length, 다리가 견딜 수 있는 무게 weight, 트럭별 무게 truck_weights가 주어집니다. 이때 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 return 하도록 solution 함수를 완성하세요.

풀이 방법:

트럭이 다리를 지나가는 과정을 그리기 위해서 다리 위에 있는 트럭들을 나타내는 overing_truck, 다리를 건너간 트럭을 나타내는 overed_truck, overing_truck에서 overed_truck으로 넘기기 위한 timer 배열을 만들었다. 그리고 총 시간을 나타내는 answer를 만들었다.
트럭이 다리를 다 지나갈 때까지 반복해야하므로 overed_truck의 배열이 truck_weights와 같아 질 때까지 반복하는 while문을 사용하였다. 그리고 다음과 같은 과정을 반복하도록 하였다.

1. 앞으로 타야할 트럭의 무게와 지금 다리 위에 있는 트럭의 무게의 합이 weight보다 작다면 다리 위에 올리고 timer에 0값을 넣어준다.
2. 1초가 지난 뒤 timer의 값을 lambda 함수를 사용해서 1초 증가시킨다.
3. 만약 timer의 첫 값(0번째 인덱스)가 다리의 길이와 같아졌다면 그 값을 빼내 다리를 지난 배열에 넣어준다.

이 과정을 while문이 깨질 때까지 반복하여 answer를 리턴하도록 하였다. 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def solution(bridge_length,weight,truck_weights):
    answer=0
    a=len(truck_weights)
    timer=[]
    overed_truck=[]
    overing_truck=[]
    while(len(overed_truck)!=a):
        answer+=1
        timer=list(map(lambda x: x+1,timer))
        if len(timer)>0:
            if timer[0]==bridge_length:
                timer.pop(0)
                b=overing_truck.pop(0)
                overed_truck.append(b)
        if len(truck_weights)>0:
            if sum(overing_truck)+truck_weights[0]<=weight:
                b=truck_weights.pop(0)
                overing_truck.append(b)
                timer.append(0)
    return answer
cs


문제:

 문자열 s는 한 개 이상의 단어로 구성되어 있습니다. 각 단어는 하나 이상의 공백문자로 구분되어 있습니다. 각 단어의 짝수번째 알파벳은 대문자로, 홀수번째 알파벳은 소문자로 바꾼 문자열을 리턴하는 함수, solution을 완성하세요.

풀이 방법:

 제한 사항의 말이 가장 중요하다. 문자열 전체의 인덱스가 아닌 단어별로 인덱스를 따져 줘야 한다.
따라서 공백을 만날 경우 index를 초기화하는 작업을 하였고, 홀수면 lower를 사용해서 소문자로 만들었고, 짝수면 upper를 사용해서 대문자로 만들었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def solution(s):
    index= 1
    answer = ''
    for i in s:
        if i==" ":
            index=1
            answer+=' '
            continue
        elif index%2==1:
            index+=1
            answer+=i.upper()
        else:
            index+=1
            answer+=i.lower()
    return answer
cs


프로그래밍 언어를 처음 배우려는 사람에게 추천하는 언어가 Python이다. 그 이유는 Python은 문법이 쉬워서 빠르게 배울수 있기 때문이다.

Python의 문법 자체가 간결하며 이해하기 쉽다. 따라서 독학으로도 충분히 Python을 공부할 수 있다.

 필자도 Python을 독학으로 공부를 하였고 다른 사람들에게 조금이라도 도움이 되고자 Python을 독학으로 공부를 했을 때 작성했던 Python 정리 노트를 [Python 따라하기]로 정리해서 올리기로 하였다. 따라서 Python을 시작하기에 앞서서 Python을 설치하는 방법을 소개한다.


1. 공식 홈페이지에서 다운 받기  

 파이썬 공식 홈페이지인 https://www.python.org/downloads/windows/ 에 들어가서 가장 최신 버젼을 다운받아서 사용하면 된다. 작성일 기준 최신 버젼은 3.7.2 버전이며 대부분 Download Windows x86-64 executable installer를 선택해서 다운받으면 된다.






설치 파일을 실행하면 다음과 같은 화면에서 아래 항목을 다 체크한 뒤 [Install Now]를 누르면 바로 설치가 진행된다.



다음과 같이 시작프로그램에 추가되어 있으면 잘 설치 된 것 이다. 이 중 IDLE를 클릭해서 Python를 작성하면 된다.



IDLE를 클릭하면 다음과 같은 Shell 창을 얻게 되는데 이 Shell 창에서는 대화형으로 코드를 진행해 나갈수 있다.



File-New File을 누르면 다음과 같은 또 다른 에디터 모드 Shell 창을 얻을 수 있는데, 이 창에선 간단한 프로그램을 작성하려 할 때 사용하면 되고, 코드를 작성 한 뒤 F5 를 눌러서 코드를 진행시킬 수 있다.



하지만 더 복잡한 프로그램을 작성하기 위해서는 IDLE보다는 전문적인 에디터를 사용하는 것이 유용하다.


2. 파이참(PyCharm)

 파이참은 많은 사람들이 주로 사용하는 에디터로 자동 완성 기능이나, 문법 체크등 다양한 기능을 제공한다. 따라서 IDLE를 사용하기 보다는 파이참을 사용하는 것을 추천한다.
파이참은 http://www.jetbrains.com/pycharm/download/#section=windows 으로 들어가서 Community 버젼을 받아도 큰 문제가 없다.




3. Anaconda(Jupyter Notebook)

  Jupyter Notebook은 웹기반으로 실행되는 에디터로, 데이터 분석 패키지가 잘 적용 되어 있다. Jupyter Notebook은  Anaconda를 통해서 다운 받을 수 있다. https://www.anaconda.com/download/에 들어가서 자신에게 맞는 버젼을 찾아서 다운을 받으면 다음과 같이 시작프로그램에 추가되어있을 것이다.



그중 Jupyter Notebook을 클릭하면 Prompt창이 뜨고 잠시 기다리면 다음과 같은 창이 등장한다.



우측 상단에 New 를 클릭해 Python3를 클릭하면 코드를 작성할 수 있는 Notebook이 실행이 된다. 코드를 작성한 뒤에 Shift+Enter를 누르면 코드가 진행이 된다.








 앞으로 Jupyter Notebook을 이용해서 앞으로 내용을 진행할 예정이니, Jupyter Notebook의 대한 기능은 추후 기회가 될 때 조금씩 설명할 예정입니다. 



문제:

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다.

또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 기능보다 먼저 개발될 수 있고, 이 때 뒤에 있는 기능은 앞에 있는 기능이 배포될 때 함께 배포됩니다.

먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses와 각 작업의 개발 속도가 적힌 정수 배열 speeds가 주어질 각 배포마다 몇 개의 기능이 배포되는지를 return 하도록 solution 함수를 완성하세요.

풀이 방법:

우선 각 기능마다 진도나 속도가 다르기 때문에 기능이 완성되는 날짜가 다르다. 따라서 이를 divmod를 사용해서 각 기능별로 완성이 되는 날짜 배열 complete를 만들었다.
 이후 이중반복문을 이용해서 답을 구하도록 하였다. 앞선 기능이 완성되는 날짜에 따라 배포 되는 작업이 달라진다. 예시처럼 첫 기능이 7일째에 완성이 되므로 다음 기능중 이보다 적게 걸리는 작업들은 7일과 함께 발표된다. 7일 보다 적게 걸리는 작업을 0으로 바꾸며 count를 하나씩 늘렸다. 왜냐하면 만약 적게 걸리는 작업을 제거해버린다면 반복문의 인덱스가 꼬여서 오류가 발생하기 때문이다. 이를 7일보다 많이 걸리는 작업(9일)을 만날 때까지 반복한다. 만나면 두번째 반복문을 break를 해버리고 count를 answer리스트에 추가한다. 이 반복문 작업을 마치고 나서 맨 끝 인덱스가 만약 0이 아니라면 그 작업은 따로 발표를 해야하므로 1을 추가해주도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def solution(progresses, speeds):
    complete = []
    for i in range(len(progresses)):
        a,b=divmod(100-progresses[i],speeds[i])
        if b !=0:
            complete.append(a+1)
        else:
            complete.append(a)
    answer=[]
    for i in range(len(complete)-1):
        count=1
        if complete[i] !=0:
            for j in range(i+1,len(complete)):
                if complete[i] >=  complete[j]:
                    if complete[j]==0:
                        pass
                    else:
                        count+=1
                        complete[j]=0
                else:
                    break
            answer.append(count)
    if complete[-1!=0:
        answer.append(1)
    return answer
cs


문제:

 함수 solution은 정수 n을 매개변수로 입력받습니다. n의 각 자릿수를 큰것부터 작은순으로 정렬한 새로운 정수를 리턴해주세요. 예를 들어 n이 118372면 873211을 리턴하면 됩니다.

풀이 방법:

 입력 받는 것이 정수형이기 때문에 리스트로 변환하기 위해서 string으로 변환시켜야 한다. string으로 변환한 후 리스트 상태에서 뒤집은 후 다시 join을 사용해 묶고 int형으로 변환하여 리턴하면 된다.

1
2
3
4
5
6
def solution(n):
    answer = 0
    n=list(str(n))
    n=sorted(n,reverse=True)
    answer=int("".join(n))
    return answer
cs
 


문제:

124 나라가 있습니다. 124 나라에서는 10진법이 아닌 다음과 같은 자신들만의 규칙으로 수를 표현합니다.

1. 124 나라에는 자연수만 존재합니다.
2. 124 나라에는 모든 수를 표현할 때 1,2,4만 사용합니다.

예를 들어서 124 나라에서 사용하는 숫자는 다음과 같이 변환됩니다.

 10진법

124 나라 

10진법 

124 나라 

14 

21 

22

11 

24 

12 

10 

41 


자연수 n이 매개변수로 주어질 때, n을 124 나라에서 사용하는 숫자로 바꾼 값을 return 하도록 solution 함수를 완성해 주세요.


풀이 방법:

 1~10까지의 예시를 잘 보면 3단위로 맨 오른 쪽 끝의 자리가 1,2,4가 반복 됨을 알 수 있다. 즉 124 나라의 숫자는 3의 나머지와 관련 있다는 것을 알 수 있다. 맨 오른쪽 끝 자리 이외에도 계속 1,2,4가 반복이므로 while문을 사용해서 n이 0이 될 때까지 반복하도록 한다. 이 때 divmod라는 함수를 사용했는데 divmod(a,b)로 사용을 하며 a를 b로 나눈 것의 몫과 나머지를 동시에 반환한다. 나머지가 0일 때, 몫을 1을 줄였는데 그 이유는 10진법의 1,2,3을 보면 십의 자리가 0으로 시작한다고 생각 해야 하기 때문이다. 


1
2
3
4
5
6
7
8
9
10
11
12
def solution(n):
    answer=''
    while n>0:
        n,r=divmod(n,3)
        if r==0:
            answer='4'+answer
            n-=1
        elif r==1:
            answer='1'+answer
        else:
            answer='2'+answer
    return answer
cs


문제:

 임의의 정수 n에 대해, n이 어떤 정수 x의 제곱인지 아닌지 판단하려 합니다. n이 정수 x의 제곱이라면 x+1의 제곱을 리턴하고, n이 정수 x의 제곱이 아니라면 -1을 리턴하는 함수를 완성하세요.

풀이방법:

 만약 n이 정수 x의 제곱이 아니면 n에다가 루트를 씌운 뒤에 1로 나눈다면 나머지가 발생 할 것이다. 조건문에서 0은 거짓 그 외의 수는 참으로 판별하기 때문에 이를 사용해서 문제를 해결하였다.

1
2
3
4
5
6
7
def solution(n):
    answer = n**(1/2)
    if answer%1==0:
        answer=(int(answer)+1)**2
    else:
        answer=-1
    return answer
cs


문제:

선행 스킬이란 어떤 스킬을 배우기 전에 먼저 배워야 하는 스킬을 뜻합니다.

예를 들어 선행 스킬 순서가 스파크 ->라이트닝 볼트 -> 썬더 일때, 썬더를 배우려면 먼저 라이트닝 볼트를 배워야 하고, 라이트닝 볼트를 배우려면 먼저 스파크를 배워야 합니다.

위 순서에 없는 다른 스킬(힐링 등)은 순서에 상관없이 배울 수 있습니다. 따라서 스파크 ->힐링->라이트닝 볼트->썬더 와 같은 스킬트리는 가능하지만, 썬더->스파크 나 라이트닝 볼트 ->스파크 ->힐링 -> 썬더 와 같은 스킬트리는 불가능합니다.

선행 스킬 순서 skill과 유저들이 만든 스킬트리를 담은 배열 skill_trees가 매개변수로 주어질 때, 가능한 스킬트리 개수를 return 하는 solution 함수를 작성해주세요.

풀이 방법:

skill의 인덱스를 비교했을 때 뒤의 스킬이 선행스킬보다 앞서서 있다면 잘못된 스킬트리인것이다. skill에 있는 것들이 항상 스킬트리에 있다는 보장이 없으므로 없는 것을 찾았을 때 -1을 반환하는 find를 사용했다. 따라서 나올 수 있는 경우의 수는 총 5가지이다. 편의상 이전의 스킬을 1번 스킬 이후의 스킬을 2번이라 표현한다. 

1. 1번스킬의 인덱스 < 2번스킬의 인덱스 일 때
 1번스킬이 존재하지 않고 2번스킬이 존재하거나 아니면 정상적으로 이루어져 있을 경우가 존재한다.
전자의 경우에는 잘못된 경우이므로 False로 설정하고 후자는 정상적인 경우이므로 True로 유지한채 진행한다.

2. 1번스킬의 인덱스 ==2번스킬의 인덱스 일 때
이 경우는 둘 다 -1로 같은 것 뿐이다. 예시에서 C만 존재하고 B ,D가 존재 하지 않는다면 이 또한 True이므로 그대로 진행한다.

3. 1번 스킬의 인덱스 > 2번 스킬의 인덱스  일 때
 1번스킬은 존재하지만 2번 스킬이 존재하지 않거나, 잘못 스킬트리가 구성되어 있을 경우이므로 전자는 True로 진행, 후자는 False로 설정후 종료시켰다.

이 과정이 모두 끝나고 난 뒤에도 True이면 정상적인 스킬트리이므로 answer 카운트를 증가시켰다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def solution(skill,skill_trees):
    answer_count=0
    for i in skill_trees:
        correct=True
        for j in range(1,len(skill)):
            if i.find(skill[j-1])<i.find(skill[j]):
                if i.find(skill[j-1])==-1:
                    correct=False
                    break
            elif i.find(skill[j-1])==i.find(skill[j]):
                pass
            else:
                if i.find(skill[j])==-1:
                    continue
                correct=False
                break
        if correct:
            answer_count+=1
    return answer_count
cs


문제:

두 수를 입력받아 두 수의 최대공약수와 최소공배수를 반환하는 함수, solution을 완성해 보세요. 배열의 맨 앞에 최대공약수, 그다음 최소공배수를 넣어 반환하면 됩니다. 예를 들어 두 수 3,12의 최대공약수는 3, 최소공배수는 12이므로 solution(3,12)는 [3,12]를 반환해야 합니다.

풀이 방법:

 최대공약수를 구하는 방법중 가장 좋은 방법은 유클리드 호제법을 사용하는 것이다. 작은 수의 경우에는 상관 없으나 문제와 같이 수가 커질 경우에는 유클리드 호제법이 효율적이기 때문이다. 
 유클리드 호제법이란 '정수 a,b,q,r(b!=0)에 대하여 a=bq+r이면 G(a,b)=G(b,r)가 성립한다.'라는 것이다. 따라서 이를 이용해 b가 0이 될 때가 while문을 반복하도록 해서 최대공약수를 구하도록 하였다.
최소공배수는 두 수의 곱에다가 최대공약수를 나누면 쉽게 구할 수 있다.

1
2
3
4
5
6
7
8
def solution(n, m):
    gcd=n
    multi=n*m
    while m !=0:
        gcd,m=m,gcd%m
    lcm=multi/gcd
    answer = [gcd,int(lcm)]
    return answer
cs


'Algorithm > Python' 카테고리의 다른 글

[Programmers]Lv 1. 정수 제곱근 판별  (0) 2019.01.26
[Programmers]Lv 2. 스킬트리  (0) 2019.01.25
[Programmers]Lv2. 탑  (0) 2019.01.23
[Programmers]Lv 1. 콜라츠 추측  (0) 2019.01.21
[Programmers]Lv 1. 하샤드 수  (0) 2019.01.20

+ Recent posts