문제:

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

문제:

 수평 직선에 높이가 서로 다른 탑  N대를 세웠습니다. 모든 탑의 꼭대기에는 신호를 송/수신하는 장치를 설치했습니다. 발사한 신호는 신호를 보낸 탑보다 높은 탑에서만 수신합니다. 또한, 한 번 수신된 신호는 다른 탑으로 송신되지 않습니다.

예를 들어 높이가 6,9,5,7,4인 다섯 탑이 왼쪽으로 동시에 레이저 신호를 발사합니다. 그러면, 탑은 다음과 같이 신호를 주고 받습니다. 높이가 4인 다섯 번째 탑에서 발사한 신호는 높이가 7인 네 번째 탑이 수신하고, 높이가 7인 네 번째 탑의 신호는 높이가 9인 두 번째 탑이, 높이가 5인 세 번째 탑의 신호도 높이가 9인 두 번째 탑이 수신합니다. 높이가 9인 두 번째 탑의 높이가 6인 첫 번째 탑인 보낸 레이저 신호는 어떤 탑에서도 수신할 수 없습니다.

맨 왼쪽에서 순서대로 탑의 높이를 담은 배열 heights가 매개변수로 주어질 때 각 탑이 쏜 신호를 어느 탑에서 받았는지 기록한 배열을 return 하도록 solution 함수를 작성해주세요.

풀이 방법:

 스택이란 모든 원소들의 삽입과 삭제가 리스트의 한쪽 끝에서만 수행되는 자료 구조로 LIFO(Last In First Out) 이라는 특징을 가지고 있다. 스택은 리스트의 끝을 Top이라고 하는데 삽입과 삭제의 연산이 top에서만 이루어져 있으므로 top 포인터는 1씩 증가 혹은 감소시킴으로써 수행한다.
 큐는 스택과 반대 구조로 리스트의 한 쪽 끝에서는 자료가 삽입되고 다른 한 쪽에서 자료가 삭제되는 자료 구조를 뜻한다. 즉 FIFO(First In First Out) 구조를 가지고 있다.
 파이썬의 리스트는 기본적으로 스택 구조를 유지한다. 따라서 append를 사용하면 리스트의 끝에 추가를 하고 pop을 하면 리스트의 끝 값이 빠져나가는 것이 그 이유이다. 우선 신호의 진행 방향이 오른쪽에서 왼쪽으로 이동을 하므로 조금 더 편하게 보기 위해서 reverse 함수를 사용해서 방향을 바꾸어 확인하였다. 송신하는 탑의 인덱스를 i 의 값으로 수신하는 탑의 인덱스를 j 로 하여 송신 탑보다 높은 수신 탑을 찾도록 하였다. 만약 찾았다면 reverse 함수를 사용해서 인덱스를 뒤집었으므로 길이에서 수신 탑의 인덱스를 빼서 원래 수신 탑의 인덱스를 집어 넣도록 하였다. 또한 count 값을 설정해서 끝까지 갈 동안 수신 탑을 못 찾을 경우에 0을 넣도록 하였다. 항상 모든 경우에 가장 왼쪽의 탑은 수신을 받을 탑이 없기에 반복문이 끝난 뒤 0을 넣고 난 뒤 다시 원래의 값을 얻기 위해 reverse 함수를 사용해서 원래대로 돌렸다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def solution(height):
    answer = []
    height.reverse() #오른쪽에서 왼쪽으로 송신하므로
    for i in range(len(height)):
        count=0 #송신하는 탑과 수신하는 탑의 차이
        for j in range(i+1,len(height)):
            count+=1
            if height[i] < height[j]:
                answer.append(len(height)-j)
                break
            else:
                if count==len(list(range(i+1,len(height)))): #수신하는 탑이 없이 끝까지 도달 했을 경우
                    answer.append(0)
                    break
    answer.append(0#맨 왼쪽에 있던 탑은 항상 수신하는 탑이 없다.
    answer.reverse()
    return answer
cs
  


문제:

1937년 Collatz란 사람에 의해 제기된 이 추측은, 주어진 수가 1이 될 때까지 다음 작업을 반복하면, 모든 수를 1로 만들 수 있다는 추측입니다. 작업능 다음과 같습니다.

1-1. 입력된 수가 짝수라면 2로 나눕니다.
1-2. 입력된 수가 홀수라면 3을 곱하고 1을 더합니다.
2. 결과로 나온 수에 같은 작업을 1이 될 때까지 반복합니다.

위 작업을 몇 번이나 반복해야하는지 반환하는 함수, solution을 완성해 주세요. 단 작업을 500번을 반복해도 1이 되지 않는다면 -1을 반환해 주세요.

풀이 방법:


 500번은 시도를 해봐야 하므로 이를 for 반복문이나 while 반복문을 사용해야 하는데 for 반복문을 사용했다. 우선 숫자가 1인지 확인을 하고 난 뒤에 아니라면 작업을 수행하도록 하였다. 만약 반복문 내에서 1이 되지 않았다면 -1을 반환토록 하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
def solution(num):
    answer = 0
    for i in range(500):
        if num == 1:
            return answer
        else:
            if num%2==0:
                num=num//2
                answer+=1
            else:
                num=num*3+1
                answer+=1
    return -1
cs

문제 링크:

https://programmers.co.kr/learn/courses/30/lessons/12943



문제:

 양의 정수 x가 하샤드 수이려면 x의 자릿수의 합으로 x가 나누어져야 합니다. 예를 들어 18의 자릿수 합은 1+8=9이고, 18은 9로 나누어 떨어지므로  18은 하샤드 수입니다. 자연수 n을 입력받아 n이 하샤드 수인지 아닌지 검사하는 함수, solution을 완성해주세요.

풀이 방법:

 입력값을 정수형으로 받기 때문에 반복문을 사용하기 위해서 반복가능한 객체(iterable)인 문자열로 바꿔서 반복문을 사용하였다.
이후 다시 정수형으로 바꿔서 각 자릿수의 합을 구했으며 나머지 연산자(%)를 사용해서 하샤드 수인지 검사하였다.

1
2
3
4
5
6
7
8
9
def solution(x):
    add=0
    for i in str(x):
        add+=int(i)
    if x%add==0:
        answer=True
    else:
        answer=False
    return answer
cs

문제 링크:

https://programmers.co.kr/learn/courses/30/lessons/12947



문제:

 프로그래머스 모바일은 개인정보 보호를 위해 고지서를 보낼 때 고객들의 전화번호의 일부를 가립니다. 전화번호가 문자열 phone_number로 주어졌을 때, 전화번호의 뒷 4자리를 제외한 나머지 숫자를 전부 *으로 가린 문자열을 리턴하는 함수, solution을 완성해주세요.

풀이 방법:

 문자열의 슬라이싱을 이용하는 문제이다. 뒷 4자리를 제외한 나머지를 가려야 하므로 뒤에서 부터 접근하는 슬라이싱을 알아야 한다. 파이썬의 인덱싱은 음수값으로 접근 할 때 맨 뒤에서 부터 접근하므로 이를 이용하면 된다.

1
2
3
def solution(phone_number):
    answer="*"*(len(phone_number)-4)+phone_number[-4:]
    return answer
cs

문제 링크:

https://programmers.co.kr/learn/courses/30/lessons/12948

문제:

 행렬의 덧셈은 행과 열의 크기가 같은 두 행렬의 같은 행, 같은 열의 값을 서로 더한 결과가 됩니다. 2개의 행렬 arr1과 arr2를 입력받아, 행렬 덧셈의 결과를 반환하는 함수, solution을 완성해주세요.

풀이 방법:

행렬은 2차원 배열로 구성되어있는데 전체 배열의 길이가 행의 크기이고, 배열 원소의 길이가 열의 크기가 되는 구조이다.
따라서 이를 이용해 2중 반복을 이용하면 행렬의 덧셈을 구할 수 있다.

1
2
3
4
5
def solution(arr1, arr2): 
    for j in range(len(arr1)):
        for k in range(len(arr1[j])):
            arr1[j][k]= arr1[j][k]+arr2[j][k]
    return arr1
cs

문제 링크:

https://programmers.co.kr/learn/courses/30/lessons/12950

문제:

 함수 solution은 정수 x와 자연수 n을 입력 받아, x부터 시작해 x씩 증가하는 숫자를 n개 지니는 리스트를 리턴해야 합니다. 다음 제한 조건을 보고, 조건을 만족하는 함수, solution을 완성해주세요.

풀이 방법:

 x부터 시작해 n번 반복하는 작업이므로 반복문을 사용하여 answer 리스트에 추가를 하면 된다.

1
2
3
4
5
def solution(x, n):
    answer = []
    for i in range(n):
        answer.append(x*(i+1))
    return answer
cs

문제 링크:

https://programmers.co.kr/learn/courses/30/lessons/12954

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

[Programmers]Lv 1. 하샤드 수  (0) 2019.01.20
[Programmers]Lv 1.핸드폰 번호 가리기  (0) 2019.01.19
[Programmers]Lv 1. 행렬의 덧셈  (0) 2019.01.18
[Programmers]Lv 1. 직사각형 별찍기  (0) 2019.01.14
[Programmers]Lv.1 예산  (0) 2019.01.12

+ Recent posts