문제:

일반적인 프린터는 인쇄 요청이 들어온 순서대로 인쇄합니다. 그렇기 때문에 중요한 문서가 나중에 인쇄될 수 있습니다. 이런 문제를 보완하기 위해 중요도가 높은 문서를 먼저 인쇄하는 프린터를 개발했습니다. 이 새롭게 개발한 프린터는 아래와 같은 방식으로 인쇄 작업을 수행합니다.

1.인쇄 대기목록의 가장 앞에 있는 문서(J)를 대기목록에서 꺼냅니다.
2.나머지 인쇄 대기목록에서 J보다 중요도가 높은 문서가 한 개라도 존재하면 J를 대기목록의 가장 마지막에 넣습니다.
3.그렇지 않으면 J를 인쇄합니다.

예를 들어, 4개의 문서(A,B,C,D)가 순서대로 인쇄 대기목록에 있고 중요도가 2 1 3 2 라면 C D A B 순으로 인쇄하게 됩니다.

내가 인쇄를 요청한 문서가 몇 번째로 인쇄되는지 알고 싶습니다. 위의 예에서 C는 1번째로, A는 3번째로 인쇄됩니다.

현재 대기목록에 있는 문서의 중요도가 순서대로 담긴 배열 priorities와 내가 인쇄를 요청한 문서가 현재 대기목록의 어떤 위치에 있는지를 알려주는 location이 매개변수로 주어질 때, 내가 인쇄를 요청한 문서가 몇 번째로 인쇄되는지 return 하도록 solution 함수를 작성해주세요.

풀이 방법:

내가 인쇄를 요청한 문서의 중요도가 2라고 할 때 2의 중요도가 여러 개가 있다면 이 프린터를 이용했을 때 내가 요청한 문서를 찾을 수가 없다.
따라서 프린터에 넣기 전에 1.0을 곱해서 다른 값들이 int 값을 가질 때 내가 요청한 문서는 float 값을 가지도록 하였다.
이후 인쇄 된 배열인 answer_list에 이 프린터의 기능에 따라 하나씩 넣었다. 
전부 인쇄 한 뒤 answer_list에서 float형인 값을 찾아 그 인덱스를 반환하였다.(단, 이 문제에서 1번째가 0이 아닌 1이므로 1을 더해서 반환한다.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def solution(priorities, location):
    answer_list=[]
    priorities[location]*=1.0
    key=priorities[location]
    while(len(priorities)!=1):
        a=priorities.pop(0)
        if a < max (priorities):
            priorities.append(a)
        else:
            answer_list.append(a)
    answer_list.append(priorities.pop(0))
    for i in range(len(answer_list)):
        if type(answer_list[i]) !=float:
            pass
        else:
            answer = i
    return answer+1
cs



문제:

자연수 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


문제:

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 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