본문 바로가기
스터디/Python

[CodingTest][2023-01-02~2022-01-10]프로그래머스 코딩테스트 Lv.0 문제들 - fin

by SeO.V 2023. 1. 10.

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

2023-01-02 ~ 2023-01-10 까지

푼 문제 : 캐릭터의 좌표, 직사각형 넓이 구하기, 컨트롤 제트, 소인수분해, 팩토리얼, 공 던지기, 합성수 찾기, 2차원으로 만들기 -> 총8문제.  

 

사실상 푼 날짜는 몰아서 풀어서..ㅠㅠ

 

캐릭터의 좌표

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

 

문제 설명

머쓱이는 RPG게임을 하고 있습니다. 게임에는 up, down, left, right 방향키가 있으며 각 키를 누르면 위, 아래, 왼쪽, 오른쪽으로 한 칸씩 이동합니다. 예를 들어 [0,0]에서 up을 누른다면 캐릭터의 좌표는 [0, 1], down을 누른다면 [0, -1], left를 누른다면 [-1, 0], right를 누른다면 [1, 0]입니다. 머쓱이가 입력한 방향키의 배열 keyinput와 맵의 크기 board이 매개변수로 주어집니다. 캐릭터는 항상 [0,0]에서 시작할 때 키 입력이 모두 끝난 뒤에 캐릭터의 좌표 [x, y]를 return하도록 solution 함수를 완성해주세요.

  • [0, 0]은 board의 정 중앙에 위치합니다. 예를 들어 board의 가로 크기가 9라면 캐릭터는 왼쪽으로 최대 [-4, 0]까지 오른쪽으로 최대 [4, 0]까지 이동할 수 있습니다.

제한사항

  • board은 [가로 크기, 세로 크기] 형태로 주어집니다.
  • board의 가로 크기와 세로 크기는 홀수입니다.
  • board의 크기를 벗어난 방향키 입력은 무시합니다.
  • 0 ≤ keyinput의 길이 ≤ 50
  • 1 ≤ board[0] ≤ 99
  • 1 ≤ board[1] ≤ 99
  • keyinput은 항상 up, down, left, right만 주어집니다.

입출력 예

keyinput  board  result
["left", "right", "up", "right", "right"] [11, 11] [2, 1]
["down", "down", "down", "down", "down"] [7, 9] [0, -4]

 

 

코드 제출 :

# 첫번째 실패
def solution(keyinput, board):
    direction = {'up':(0,1), 'down':(0,-1), 'left':(-1,0), 'right':(1,0)}
    start = [0,0]
    for order in keyinput:
        if (abs(start[0]) < board[0]//2) and (abs(start[1]) < board[1]//2):
            start[0] += direction[order][0]
            start[1] += direction[order][1]
    return [start[0],start[1]]
# 제출
def solution(keyinput, board):
    x,y = 0,0
    width, height = (board[0]//2),(board[1]//2)
    direction = {'up':(0,1), 'down':(0,-1), 'left':(-1,0), 'right':(1,0)}
    for order in keyinput:
        x += direction[order][0]
        y += direction[order][1]
        x = x+0 if -width <= x <= width else x-direction[order][0]
        y = y+0 if -height <= y <= height else y-direction[order][1]
    return [x,y]

 

해설

더보기

첫번째에서 조건적인 부분이 안되었나 하고 수정했는데 계속 뭔가 안 맞아서 찾다가 테스트케이스 8번에서 계속 틀리길래 질문하기에서 답을 찾음.

https://school.programmers.co.kr/questions/38497 여기에 보면

반례 : ["left", "left", "left", "right"], [3, 3]

기대값 : [0, 0]

혹은

반례 : ["up", "up", "up", "down"], [3, 3]

기대값 : [0, 0]

을 이야기 해줘서 넣어보니까 0이 적용이 안 되던… 그래서 계속 삽질하다가 음과 양의 범위 안을 벗어나지 않으면 값이 변하지 않고 넘어가면 이전에 더했던 걸 취소하는 방식(롤백)으로 처리해서 해결.

 

점수 : 1294(+4)

 


직사각형 넓이 구하기

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

 

문제 설명

2차원 좌표 평면에 변이 축과 평행한 직사각형이 있습니다. 직사각형 네 꼭짓점의 좌표 [[x1, y1], [x2, y2], [x3, y3], [x4, y4]]가 담겨있는 배열 dots가 매개변수로 주어질 때, 직사각형의 넓이를 return 하도록 solution 함수를 완성해보세요.

제한사항

  • dots의 길이 = 4
  • dots의 원소의 길이 = 2
  • 256 < dots[i]의 원소 < 256
  • 잘못된 입력은 주어지지 않습니다.

입출력 예

dots  result
[[1, 1], [2, 1], [2, 2], [1, 2]] 1
[[-1, -1], [1, 1], [1, -1], [-1, 1]] 4

 

 

코드 제출 :

# 첫번째 실패
def solution(dots):
    dot1, dot2, dot3, dot4 = [*dots]
    return abs(dot2[0]-dot1[0])*abs(dot3[1]-dot2[1])
# 제출
def solution(dots):
    width = max([dot[0] for dot in dots]) - min([dot[0] for dot in dots])
    height = max(([dot[1] for dot in dots])) - min([dot[1] for dot in dots])
    return width*height

 

해설

더보기

처음에 순서가 정해진 줄 알고 값에서 값을 뺀 절대값으로 했다가 안되서

돌려보면서 위치를 갖고 보다 보니까

1 2

3 4

라는 형식의 사각형일때, 결국 가장 작은 값이 3, 큰 값이 2라고 할 때 그 큰 값에서 작은 값으로 빼면 각각 가로 세로 값이 나옴.

 

점수 : 1299(+5)

 


컨트롤 제트

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

 

문제 설명

숫자와 "Z"가 공백으로 구분되어 담긴 문자열이 주어집니다. 문자열에 있는 숫자를 차례대로 더하려고 합니다. 이 때 "Z"가 나오면 바로 전에 더했던 숫자를 뺀다는 뜻입니다. 숫자와 "Z"로 이루어진 문자열 s가 주어질 때, 머쓱이가 구한 값을 return 하도록 solution 함수를 완성해보세요.

 

제한사항

  • 1 ≤ s의 길이 ≤ 200
  • 1,000 < s의 원소 중 숫자 < 1,000
  • s는 숫자, "Z", 공백으로 이루어져 있습니다.
  • s에 있는 숫자와 "Z"는 서로 공백으로 구분됩니다.
  • 연속된 공백은 주어지지 않습니다.
  • 0을 제외하고는 0으로 시작하는 숫자는 없습니다.
  • s는 "Z"로 시작하지 않습니다.
  • s의 시작과 끝에는 공백이 없습니다.
  • "Z"가 연속해서 나오는 경우는 없습니다.

입출력 예

result
"1 2 Z 3" 4
"10 20 30 40" 100
"10 Z 20 Z 1" 1
"10 Z 20 Z" 0
"-1 -2 -3 Z" -3

 

 

코드 제출 :

# 제출
def solution(s):
    answer = list(s.split())
    return sum([-int(answer[i-1]) if answer[i] == 'Z' else int(answer[i]) for i in range(len(answer))])

 

해설

더보기

answer에다가 분리한 다음에, 각각을 확인할 때, int 처리를 하면서 Z일 경우 이전 index로 끌어와서 int처리 후 -를 붙여서 음의 처리를 하면 음의 수여도 -가 다시 붙어서 +가 되므로 ㅇㅋ 그러고나서 전체적으로 sum 처리후 반환.

 

점수 : 1300(+1)

 


소인수분해

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

 

문제 설명

소인수분해란 어떤 수를 소수들의 곱으로 표현하는 것입니다. 예를 들어 12를 소인수 분해하면 2 * 2 * 3 으로 나타낼 수 있습니다. 따라서 12의 소인수는 2와 3입니다. 자연수 n이 매개변수로 주어질 때 n의 소인수를 오름차순으로 담은 배열을 return하도록 solution 함수를 완성해주세요.

 

제한사항

  • 2 ≤ n ≤ 10,000

입출력 예

result
12 [2, 3]
17 [17]
420 [2, 3, 5, 7]

 

 

코드 제출 :

# 제출
def prime_list(x):
    tmp = [True for i in range(x+1)]
    for i in range(2, int(x**0.5)+1):
        if tmp[i] == True:
            j = 2
            while i*j <= x:
                tmp[i*j] = False
                j += 1
    return [i for i in range(2, x+1) if tmp[i]]

def solution(n):
    prime = prime_list(n)
    answer = [i for i in prime if n%i==0]
    return answer
# 다른 사람 풀이
def solution(n):
    answer = []
    d = 2
    while d <= n:
        if n % d == 0:
            n /= d
            if d not in answer:
                answer.append(d)
        else:
            d += 1
    return answer

해설

더보기

소인수 분해 하기 전에 소수부터 구해야 하지 않나라는 생각에 소수 리스트를 구하고 거기서 나눠지면 리스트 추가하는 식으로 처리.

# 다른 사람 풀이
def solution(n):
    answer = []
    d = 2
    while d <= n:
        if n % d == 0:
            n /= d
            if d not in answer:
                answer.append(d)
        else:
            d += 1
    return answer

그 이외에는 이게 이해가 되는 방식.

2부터 시작해서 딱 나눠 떨어지면 n/d로 처리 후, 소수인 d가 answer 리스트에 없으면 추가해서 만들고 그렇게 d를 += 1해서 n이 될 때까지 while loop

 

점수 : 1303(+3)

 


팩토리얼

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

 

문제 설명

i팩토리얼 (i!)은 1부터 i까지 정수의 곱을 의미합니다. 예를들어 5! = 5 * 4 * 3 * 2 * 1 = 120 입니다. 정수 n이 주어질 때 다음 조건을 만족하는 가장 큰 정수 i를 return 하도록 solution 함수를 완성해주세요.

  • i! ≤ n

제한사항

  • 0 < n ≤ 3,628,800

입출력 예

result
3628800 10
7 3

 

 

코드 제출 :

# 첫번째 실패 - 2, 5 fail
def solution(n):
    count = 2
    while n > 2:
        n //= count
        count += 1
    return count-1
# 제출
def solution(n):
    count = 2
    while n != 0:
        n //= count
        count += 1
    return count-2

 

해설

더보기

처음에 푼 건

# 첫번째 실패 - 2, 5 fail
def solution(n):
    count = 2
    while n > 2:
        n //= count
        count += 1
    return count-1

이거였는데 19 같이 그 근처이면서 애매하게 남으면 count가 예상값과 다르길래 print로 하나하나 찍어보면서 수정.

while문으로서 1은 곱해도 1이니까 2부터 나눠가면서 count의 값을 더하고 0이 될 때까지 완벽하게 나눈 다음에 원 count를 알 수 있게 2를 차감. 10을 넘는 것도 맞게 나오는 거 확인.

 

점수 : 1305(+2)

 


공 던지기

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

 

문제 설명

머쓱이는 친구들과 동그랗게 서서 공 던지기 게임을 하고 있습니다. 공은 1번부터 던지며 오른쪽으로 한 명을 건너뛰고 그다음 사람에게만 던질 수 있습니다. 친구들의 번호가 들어있는 정수 배열 numbers와 정수 K가 주어질 때, k번째로 공을 던지는 사람의 번호는 무엇인지 return 하도록 solution 함수를 완성해보세요.

제한사항

  • 2 < numbers의 길이 < 100
  • 0 < k < 1,000
  • numbers의 첫 번째와 마지막 번호는 실제로 바로 옆에 있습니다.
  • numbers는 1부터 시작하며 번호는 순서대로 올라갑니다.

입출력 예

numbers  result
[1, 2, 3, 4] 2 3
[1, 2, 3, 4, 5, 6] 5 3
[1, 2, 3] 3 2

 

 

코드 제출 :

# 제출
def solution(numbers, k):
    numbers = numbers[::2]+numbers[::2] if len(numbers)%2==0 else numbers[::2]+numbers[1::2]
    return [numbers[i%len(numbers)] for i in range(k)][-1]

 

해설

더보기

문제를 봤을 때 numbers의 길이가 짝수면 1,3,5 홀수만 돌아가고 그게 아니면 교차되면서 가는 형식의 순환이라서 numbers먼저 순환을 2번으로 붙인 다음에 list comprehension으로 k값 많큼 순환 하면서 해당 numbers의 index들을 이용해서 값을 기록 수 가장 마지막 -1으로 slicing처리.

다른 사람의 풀이는

# 다른 사람 풀이
def solution(numbers, k):
    return numbers[2 * (k - 1) % len(numbers)]

index를 순서로서 0,2,4,으로 처리하신 듯.

 

점수 : 1306(+1)

 


합성수 찾기

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

 

문제 설명

약수의 개수가 세 개 이상인 수를 합성수라고 합니다. 자연수 n이 매개변수로 주어질 때 n이하의 합성수의 개수를 return하도록 solution 함수를 완성해주세요.

 

제한사항

  • 1 ≤ n ≤ 100

입출력 예

result
10 5
15 8

 

 

코드 제출 :

# 제출
def prime_list(x):
    tmp = [True for i in range(x+1)]
    for i in range(2, int(x**0.5)+1):
        if tmp[i] == True:
            j = 2
            while i*j <= x:
                tmp[i*j] = False
                j += 1
    return [i for i in range(2, x+1) if tmp[i]]
def solution(n):
    answer = set(range(2,n+1))
    primes = set(prime_list(n))
    return len(answer-primes)

 

해설

더보기

합성수라는 건 결국 1 이상이며 소수가 아닌 것들이라는 거니까 1을 제외하고 소수를 먼저 구하고 거기서 set끼리의 연산으로 구하고 나서 한 건데 이건 목록을 구하는 게 아니라서 어떻게 보면 불필요하므로

다른 사람들이 푼

def solution(n):
    output = 0
    for i in range(4, n + 1):
        for j in range(2, int(i ** 0.5) + 1):
            if i % j == 0:
                output += 1
                break
    return output

이 방식이 좀 더 빠르고 가벼워 보임.

 

점수 : 1307(+1)

 


2차원으로 만들기

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

 

문제 설명

정수 배열 num_list와 정수 n이 매개변수로 주어집니다. num_list를 다음 설명과 같이 2차원 배열로 바꿔 return하도록 solution 함수를 완성해주세요.

num_list가 [1, 2, 3, 4, 5, 6, 7, 8] 로 길이가 8이고 n이 2이므로 num_list를 2 * 4 배열로 다음과 같이 변경합니다. 2차원으로 바꿀 때에는 num_list의 원소들을 앞에서부터 n개씩 나눠 2차원 배열로 변경합니다.

num_list  result
[1, 2, 3, 4, 5, 6, 7, 8] 2 [[1, 2], [3, 4], [5, 6], [7, 8]]

제한사항

  • num_list의 길이는 n의 배 수개입니다.
  • 0 ≤ num_list의 길이 ≤ 150
  • 2 ≤ n < num_list의 길이

입출력 예

num_list  result
[1, 2, 3, 4, 5, 6, 7, 8] 2 [[1, 2], [3, 4], [5, 6], [7, 8]]
[100, 95, 2, 4, 5, 6, 18, 33, 948] 3 [[100, 95, 2], [4, 5, 6], [18, 33, 948]]

 

 

코드 제출 :

# 제출
def solution(num_list, n):
    return [num_list[nums:nums+n] for nums in range(0,len(num_list),n)]

 

해설

더보기

n개씩 묶는 건 range의 자체적 기능으로 할 수 있고 list이므로 index의 번호로 slicing을 이용하면 됨.

 

점수 : 1308(+1)

 


 

Lv0 입문 100문제 끝!!!