본문 바로가기
스터디/Python

[CodingTest][2022-12-21~22]프로그래머스 코딩테스트 Lv.0 문제들

by SeO.V 2022. 12. 22.

프로그래머스 코딩테스트 Lv.0 문제들

2022-12-21~22

Lv 0 을 빠르게 해치우고 싶어서 추가적으로 계속 풀기.

푼 문제 : 옹알이 (1), 다음에 올 숫자, 연속된 수의 합, 종이 자르기, 문자열 밀기, 잘라서 배열로 저장하기

 

옹알이 (1)

link : https://school.programmers.co.kr/learn/courses/30/lessons/120956

 

문제 설명

머쓱이는 태어난 지 6개월 된 조카를 돌보고 있습니다. 조카는 아직 "aya", "ye", "woo", "ma" 네 가지 발음을 최대 한 번씩 사용해 조합한(이어 붙인) 발음밖에 하지 못합니다. 문자열 배열 babbling이 매개변수로 주어질 때, 머쓱이의 조카가 발음할 수 있는 단어의 개수를 return하도록 solution 함수를 완성해주세요.

 

제한사항

  • 1 ≤ babbling의 길이 ≤ 100
  • 1 ≤ babbling[i]의 길이 ≤ 15
  • babbling의 각 문자열에서 "aya", "ye", "woo", "ma"는 각각 최대 한 번씩만 등장합니다.
    • 즉, 각 문자열의 가능한 모든 부분 문자열 중에서 "aya", "ye", "woo", "ma"가 한 번씩만 등장합니다.
  • 문자열은 알파벳 소문자로만 이루어져 있습니다.

입출력 예

babbling  result
["aya", "yee", "u", "maa", "wyeoo"] 1
["ayaye", "uuuma", "ye", "yemawoo", "ayaa"] 3

 

 

코드 제출 :

# 제출 - 예전에 제출한 코드
from itertools import permutations
def solution(babbling):
    answer = 0
    pron = ["aya", "ye", "woo", "ma"]
    word = []
    for i in range(1, len(pron) + 1) :
        print(f'i : {i}')
        for j in permutations(pron, i) :
            print(f'j : {j}')
            word.append("".join(j))
            print(f'word : {word}')
    for i in babbling :
        print(f'i in after : {i}')
        if i in word :
            print(f'word : {word} / i : {i}')
            answer += 1
    return answer

 

해설

더보기

from itertools import permutations 을 이용해서 permutations(iterable,r=None) : iterable에서 원소 개수가 r개인 순열 뽑도록 함.

첫번째 for 문으로 경우의 수들로 순열 뽑고 문자열로 join으로 만들어 놓고 다시 word안에 넣어서 모든 경우의 수를 만들어 놓음.

for 문으로 babbling이 만든 word안에 있으면 answer += 1을 하도록 함.

ref : https://seu11ee.tistory.com/5

점수 : 1137 (+4)


다음에 올 숫자

link : https://school.programmers.co.kr/learn/courses/30/lessons/120924

 

 

문제 설명

등차수열 혹은 등비수열 common이 매개변수로 주어질 때, 마지막 원소 다음으로 올 숫자를 return 하도록 solution 함수를 완성해보세요.

제한사항

  • 2 < common의 길이 < 1,000
  • 1,000 < common의 원소 < 2,000
  • 등차수열 혹은 등비수열이 아닌 경우는 없습니다.
  • 공비가 0인 경우는 없습니다.

입출력 예

common  result
[1, 2, 3, 4] 5
[2, 4, 8] 16

 

 

코드 제출 :

# 제출
def solution(common):
    n = len(common)
    return common[0]+((n)*(common[-1]-common[-2])) if common[-1]-common[-2] == common[-2]-common[-3] else common[0]*((common[-1]//common[-2])**n)

 

 

해설

더보기

등차수열(arithmetic progression, AP) : 수열의 첫항을 $a_1$, 공차를 $d$ 라고 할 때, 일반항을 다음과 같이 나타낼 수 있다.

$a_n = a + (n−1)d$ 이를

예를 들면, [3,5,7,9,?]일 때 3으로 시작하는 등차수열의 5번째는 $n= 5일 때,a_5 = 3+(5-1)*2$ 이므로,

$a_5 = 3+(4*2) = 3+8 = 11$ 이다.

등비수열(geometric sequence) : 등비수열 : 첫항이 $a$이며, 공비가 $r$인 등비수열의 $n$번째 항은 다음과 같다.

$a_{n}=ar^{{n-1}}$ 이를

예를 들면, [3,6,12,24,48,?]이라고 할 때 3으로 시작하는 등비수열의 6번째는 $n=6$일 때, $a_6 = 3*2^{(6-1)}$ 이고,

$a_6 = 3*32 = 96$ 이다.

위의 참조를 통해 수식을 확인하고 그걸 문제에 그대로 적용. 다만 조건식 if로서 차이가 동일하다면 등차로, 아니면 등비로 인식하도록 한 다음에 처리. 

점수 : 1142 (+5)


연속된 수의 합

link : https://school.programmers.co.kr/learn/courses/30/lessons/120923

 

문제 설명

연속된 세 개의 정수를 더해 12가 되는 경우는 3, 4, 5입니다. 두 정수 num과 total이 주어집니다. 연속된 수 num개를 더한 값이 total이 될 때, 정수 배열을 오름차순으로 담아 return하도록 solution함수를 완성해보세요.

 

제한사항

  • 1 ≤ num ≤ 100
  • 0 ≤ total ≤ 1000
  • num개의 연속된 수를 더하여 total이 될 수 없는 테스트 케이스는 없습니다.

입출력 예

num  total  result
3 12 [3, 4, 5]
5 15 [1, 2, 3, 4, 5]
4 14 [2, 3, 4, 5]
5 5 [-1, 0, 1, 2, 3]

 

코드 제출 :

# 제출
def solution(num, total):
    last = (num//2)+(total//num)
    return sorted(map(int,range(last,(last-num),-1)))
# 풀이
def solution(num, total):
    med = total // num # 중앙값을 찾기 위해서.
    half = num // 2 # 중앙값으로부터 가장 큰 값까지의 차이
    last = half+med # 가장 큰 수
    return sorted(map(int,range(last,(last-num),-1)))
    # sorted() 오름차순 정렬+list 반환
    # map(int, range(가장 큰 값부터, 가장 작은 값까지, 역수로))

 

 

해설

더보기
풀이와 같다.

나온 것들을 보다보니 total에서 num으로 나온 값이 중앙값인 걸 알게 되었고 거기서부터 배열까지의 차이가 대부분, // 으로 나누었기 때문에 뒤 부분에 +1 되는 형식이고 또 가장 큰 값까지의 차이(등차수열로서 1씩 차이가 났기에 가능)까지 확인이 되는 패턴이어서, 여기에 중앙값med+가장 큰 값까지 가는 차이half를 더하면 결과값의 가장 마지막 수를 찾을 수 있으니 거기서부터 거꾸로 range와 map으로 배열처리 한 다음에 sorted로 오름차순 처리 함.

점수 : 1145(+3)


종이 자르기

link : https://school.programmers.co.kr/learn/courses/30/lessons/120922

 

문제 설명

머쓱이는 큰 종이를 1 x 1 크기로 자르려고 합니다. 예를 들어 2 x 2 크기의 종이를 1 x 1 크기로 자르려면 최소 가위질 세 번이 필요합니다.

정수 M, N이 매개변수로 주어질 때, M x N 크기의 종이를 최소로 가위질 해야하는 횟수를 return 하도록 solution 함수를 완성해보세요.

 

제한사항

  • 0 < M, N < 100
  • 종이를 겹쳐서 자를 수 없습니다.

 

입출력 예

result
2 2 3
2 5 9
1 1 0

 

 

코드 제출 :

# 제출
def solution(M, N):
    return (M * N) - 1

 

해설

더보기
예시 몇 개 해보다가 패턴이 있었음 M * N 한 수에서 1을 빼면 result가 나와서 그대로.

 

점수 : 1146(+1)


 

문자열 밀기

link : https://school.programmers.co.kr/learn/courses/30/lessons/120921

 

문제 설명

문자열 "hello"에서 각 문자를 오른쪽으로 한 칸씩 밀고 마지막 문자는 맨 앞으로 이동시키면 "ohell"이 됩니다. 이것을 문자열을 민다고 정의한다면 문자열 A와 B가 매개변수로 주어질 때, A를 밀어서 B가 될 수 있다면 몇 번 밀어야 하는지 횟수를 return하고 밀어서 B가 될 수 없으면 -1을 return 하도록 solution 함수를 완성해보세요.

제한사항

  • 0 < A의 길이 = B의 길이 < 100
  • A, B는 알파벳 소문자로 이루어져 있습니다.

입출력 예

result
"hello" "ohell" 1
"apple" "elppa" -1

 

 

코드 제출 :

# 제출
def solution(A, B):
    string = [a for a in A]
    result = [b for b in B]
    count = 0
    while string != result:
        if count >= len(A):
            return -1
        tmp = string[-1]
        string = string[:-1]
        string = [tmp]+string
        count += 1
    return count

 

 

해설

더보기

그냥 그대로 구현을 먼저 해보려고 했는데 한 방에 되긴 됨.

while문으로 될 때까지 하고 문자열이 아니라 list로서 처리하면서 가장 마지막을 앞으로 하고 concat 하면서 count += 1했는데

로이님도 그렇고 다른 사람 풀이 중에서

solution = lambda A,B: (B*2).find(A)
# 이게 대박이었음.
# 예를 들어서 A = 'hello', B = 'lohel' 이라고 할 때,
# (B*2)으로 하게 되면 결국 lohellohel인 결과에서 find(A)를 적용하면 A가 있는 hello가 있는 문자열의 시작점 index를 return 하는데 그게 결국 맨 마지막 글자를 앞으로 당기면서 밀리는 만큼의 횟수이기 때문.

점수 : 1155(+9)


잘라서 배열로 저장하기

link : https://school.programmers.co.kr/learn/courses/30/lessons/120913

 

문제 설명

문자열 my_str과 n이 매개변수로 주어질 때, my_str을 길이 n씩 잘라서 저장한 배열을 return하도록 solution 함수를 완성해주세요.

 

제한사항

  • 1 ≤ my_str의 길이 ≤ 100
  • 1 ≤ n ≤ my_str의 길이
  • my_str은 알파벳 소문자, 대문자, 숫자로 이루어져 있습니다.

 

입출력 예

my_str  result
"abc1Addfggg4556b" 6 ["abc1Ad", "dfggg4", "556b"]
"abcdef123" 3 ["abc", "def", "123"]

 

코드 제출 :

# 제출
def solution(my_str, n):
    str_len = len(my_str)
    count = (str_len // n) if (str_len % n) == 0 else (str_len // n)+1
    start = 0
    end = n
    length = str_len+1
    result = []
    for _ in range(count):
        result.append(my_str[start:end])
        start = end
        end = start+n
    return result
# 팩토리얼 
# for loop 사용
def factorial(n):
    answer = 1
    for num in range(1,n+1):
        answer *= num
    return answer
def solution(balls, share):
    return factorial(balls) / (factorial(balls-share) * factorial(share))

 

 

해설

더보기

이것도 우선은 단순하게 가려고 for loop으로 나눠야 할 갯수(count) 만들고 append로 쪼개되 slicing할 번호를 만들었는데 분명 줄일 수 있을 거 같아서 찾아보다가

# 다른 사람 풀이
def solution(my_str, n):
    return [my_str[i: i + n] for i in range(0, len(my_str), n)]

이거 보고 감탄. output 찍어보니까 → i : 0 / my_str[0: 0 + 6] : abc1Ad range로 0부터 시작해서 글자의 갯수까지 가되 잘라낼 n개까지를 하고 i로 더해버리면 되는 것이었음. 맨 마지막에 range의 범위를 넘어가도 어차피 error 아니고 문자열 끝까지니까 상관 없음.

점수 : 1157(+2)


여기까지 6문제.