문제:

 초 단위로 기록된 주식가격이 담긴 배열 prices가 매개변수로 주어질 때, 가격이 유지된 기간은 몇 초인지를 return 하도록 solution 함수를 완성하세요.

풀이방법:

스택/큐를 사용해서 풀어야 하는 문제인 것 같지만 딱히 스택/큐를 활용하지 않아도 쉽게 풀 수 있다. 이중반복문을 이용해서 떨어지기 전까지 계속 count를 증가시키고 떨어지는 순간 break를 걸어서 그 때까지의 count를 answer 배열에 넣어주면 된다.


1
2
3
4
5
6
7
8
9
10
11
12
def solution(prices):
    answer=[]
    for i in range(len(prices)):
        count=0
        for j in range(i+1,len(prices)):
            count+=1
            if prices[i] <= prices[j]:
                pass
            else:
                break
        answer.append(count)
    return answer
cs


문제:

1부터 입력받은 숫자 n 사이에 있는 소수의 개수를 반환하는 함수, solution을 만들어 보세요.

소수는 1과 자기 자신으로만 나누어지는 수를 의미합니다.
(1은 소수가 아닙니다.)

풀이 방법:

소수는 1과 자기 자신으로만 나누어지는 수이기 때문에 반복문을 사용해서 임의의 수 x가 소수인지 판별하는 방법은 2부터 x-1까지 나누어 보았을 때, 나머지가 생기지 않으면 된다. 따라서 다음과 같이 코드를 작성할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
def solution(n):
    answer=[]
    cnt=1
    while(cnt!=n):
        cnt+=1
        prime=True
        for i in range(2,cnt):
            if cnt%i==0:
                prime=False
                break
        if prime:
            answer.append(cnt)
    return len(answer)
cs

하지만 이 방법은 효율적이지 못한 방법이라 큰 수의 경우에는 통과를 하지 못한다.



 그 이유는 2부터 x-1까지 검사하기 때문에 엄청 큰 소수 인 경우 x-1까지 반복해야하기 때문이다.

하지만 수학적으로 생각해보면 만약 어떤 수의 약수가 존재한다면 x-1까지 검사할 필요 없이 sqrt(x)까지만 검사를 해보아도 충분하다는 것을 알 수 있다.

따라서 위 코드를 다음과 같이 수정을 하였다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
def solution(n):
    import math
    answer=[2]
    cnt=1
    while(cnt!=n):
        cnt+=1
        prime=True
        for i in range(2,math.ceil(math.sqrt(cnt))+1):
            if cnt%i==0:
                prime=False
                break
        if prime:
            answer.append(cnt)
    return len(answer)
cs


math에 있는 루트 함수인 sqrt와 올림 함수인 ceil을 사용해서 범위를 잡아 주었다. 그러면 다음과 같이 큰 수의 경우에도 통과를 하는 것을 알 수 있다.



 하지만 이 방법이 소수를 판별하는 문제에서 최적의 효율을 나타내지는 않는다. 소수를 판별하는 문제에서 가장 효율이 좋은 코드는 '에라토스테네스의 체' 원리를 사용하는 것이다. 소수가 1과 자기 자신으로 나누어 지는 수라고 가정하면 소수가 아닌 수는 임의의 소수 하나로 나눌 수 있다는 말이 된다. 따라서 2부터 x-1까지 나누어보는 것이 아닌 소수 배열을 만들어서 임의의 소수로 나누어 지지 않는다면 소수가 된다는 것이다. 다음은 에라토스테네스의 체 원리를 이용해 작성한 코드다.


1
2
3
4
5
6
7
8
9
10
11
12
13
def solution(n):
    answer=[]
    for i in range(2,n+1):
        prime=True
        for j in answer:
            if i%j == 0:
                prime=False
                break
            elif j > i**(1/2):
                break
        if prime:
            answer.append(i)
    return len(answer)
cs

다음

다음과 같이 더 빨리 통과함을 알 수 있다. 효율성 테스트에서는 더 빨리 통과한다는 것을 체감할 수 있다.

 


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

[Programmers]Lv 1.문자열 내 마음대로 정렬하기  (0) 2019.02.07
[Programmers]Lv 2.주식 가격  (0) 2019.02.06
[Programmers]Lv 2.쇠막대기  (0) 2019.02.04
[Programmers]Lv 1. 시저 암호  (0) 2019.02.03
[Programmers]Lv 2.프린터  (0) 2019.02.02

문제:

여러 개의 쇠막대기를 레이저로 절단하려고 합니다. 효율적인 작업을 위해서 쇠막대기를 아래에서 위로 겹쳐 놓고, 레이저를 위에서 수직으로 발사하여 쇠막대기들을 자릅니다. 쇠막대기와 레이저의 배치는 다음 조건을 만족합니다.

-쇠막대기는 자신보다 긴 쇠막대기 위에만 놓일 수 있습니다.

-쇠막대기를 다른 쇠막대기 위에 놓는 경우 완전히 포함되도록 놓되, 끝점은 겹치지 않도록 놓습니다.

-각 쇠막대기를 자르는 레이저는 적어도 하나 존재합니다.

-레이저는 어떤 쇠막대기의 양 끝점과도 겹치지 않습니다.


이러한 레이저와 쇠막대기의 배치는 다음과 같이 괄호를 이용하여 왼쪽부터 순서대로 표현할 수 있습니다.


(a) 레이저는 여는 괄호와 닫는 괄호의 인접한 쌍 '()'으로 표현합니다. 또한 모든 '()'는 반드시 레이저를 표현합니다.

(b) 쇠막대기의 왼쪽 끝은 여는 괄호 '('로, 오른쪽 끝은 닫힌 괄호 ')'로 표현됩니다.


쇠막대기와 레이저의 배치를 표현한 문자열 arrangement가 매개변수로 주어질 때, 잘린 쇠막대기 조각의 총 개수를 return 하도록 solution 함수를 작성해주세요.


풀이 방법:

 이 문제에서 막대기가 갈라지는 경우는 레이저로 자르는 것 이외에도 쌓인 막대기가 달라져서 생길 수 있다. 
'('는 막대기가 쌓인다는 의미이고 ')'는 막대기가 사라진다는 의미로 생각을 해야한다. 따라서 '(' 일 때 stack 값을 1 증가시키고 ')' 일 때는 감소 시키도록 한다.
또한 ')' 이전에 '('가 있었으면 레이저의 의미이고, ')'가 있었다면 막대기의 층이 달라진다는 의미이다. 따라서 이를 위해 cut 라는 bool 값을 추가했다.
 


첫 레이저에서는 쌓인 막대기가 없어서 생긴 조각이 없다. 하지만 두번째 레이저에서는 '(' 가 4개 ')'개 인 것이므로 3개의 조각이 생긴다. (현재 stack=3)



세번째 레이저에서는 3개의 stack이 유지 중에 '('를 1번 ')'를 1번이 있었으므로 이번에도 3개의 조각이 생긴다. (현재 stack=3)



')'가 두 번 연속 반복된 상황이다. 따라서 stack을 1 줄이면서 1개의 조각을 더 추가시킨다. (현재 stack=2)



네번째 레이져까지 도달할 때까지 stack 2에서 '('를 2번 ')'를 한 번 만나서 3개의 조각이 생기게 된다. (현재 stack=3)



')'가 두 번 연속 반복된 상황이다. 따라서 stack을 1 줄이면서 1개의 조각을 더 추가시킨다. (현재 stack=2)



다섯번째 레이저를 만나기까지 '(' 한 번 ')' 한 번씩 만났다 따라서 2개의 조각이 생기게 된다. (현재 stack=2)



')'가 세 번 연속 반복된 상황이다. 따라서 stack을 1씩 두 번  줄이면서 1개의 조각씩을 더 추가시킨다. (현재 stack=0)



여섯번째 레이저를 만나기까지 '(' 두 번 ')' 한 번을 만나면서 1개의 조각이 생긴다. (현재 stack =1)



')'가 두 번 연속 반복된 상황이다. 따라서 stack을 1 줄이면서 1개의 조각을 더 추가시킨다. (현재 stack=0)


이렇게 쇠막대기를 잘라나가면 답을 얻을 수 있게 될 것이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def solution(arrangement):
    stack=0
    answer=0
    for i in arrangement:
        if i=="(":
            stack+=1
            cut=True
        else:
            stack-=1
            if cut:
                answer+=stack
                cut=False
            else:
                answer+=1
    return answer
cs




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

[Programmers]Lv 2.주식 가격  (0) 2019.02.06
[Programmers]Lv 1.소수 찾기  (0) 2019.02.05
[Programmers]Lv 1. 시저 암호  (0) 2019.02.03
[Programmers]Lv 2.프린터  (0) 2019.02.02
[Programmers]Lv 1.약수의 합  (0) 2019.02.01

문제:

어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화방식을 시저 암호라고 합니다. 예를 들어 "AB"는 1만큼 밀면 "BC"가 되고, 3만큼 밀면 "DE"가 됩니다. "z"는 1만큼 밀면 "a"가 됩니다. 문자열 s와 거리 n을 입력받아 s를 n만큼 민 암호문을 만드는 함수, solution을 완성해 보세요.

풀이 방법:

Python의 내장함수는 ord()와 chr()를 사용하는 문제이다. s를 반복문으로 돌려서 각 자리가 소문자, 대문자, 공백인지 확인한다.
이후 chr(((ord(i)-ord('a'))+n)%26+ord('a')) 이와 같이 시저 암호를 만든다.

1
2
3
4
5
6
7
8
9
10
def solution(s, n):
    answer = ''
    for i in s:
        if i.islower():
            answer+=chr(((ord(i)-ord('a'))+n)%26+ord('a'))
        elif i.isupper():
            answer+=chr(((ord(i)-ord('A'))+n)%26+ord('A'))
        else:
            answer+=' '
    return answer
cs


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

[Programmers]Lv 1.소수 찾기  (0) 2019.02.05
[Programmers]Lv 2.쇠막대기  (0) 2019.02.04
[Programmers]Lv 2.프린터  (0) 2019.02.02
[Programmers]Lv 1.약수의 합  (0) 2019.02.01
[Programmers]Lv 2. 다리를 지나는 트럭  (0) 2019.01.31

문제:

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

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
 


+ Recent posts