AI 부트캠프/챕터3(11.08~12.04)

TIL 45

musukie 2024. 11. 21. 21:18

수준별 수업 - 베이직반

파이썬 코딩테스트 복습

캐릭터의 좌표

문제 설명

제 설명머쓱이는 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]까지 이동할 수 있습니다.

이렇게 구현하기 어려운 문제를 은어로 빡구현 문제라고 부른다고 한다. 나는 하나하나 설정하고 대입해서 문제를 풀었다. 그러나 딕셔너리로 풀면 더 간단하게 풀 수 있다는 사실을 오늘 배웠다. 우선, 내가 푼 코드는 아래와 같다.

더보기
def solution(keyinput, board):
    answer = [0, 0]
    for i in keyinput:
        if i == 'left':
            answer[0] -= 1
        elif i == 'right':
            answer[0] += 1
        elif i == 'up':
            answer[1] += 1
        elif i == 'down':
            answer[1] -= 1
            
        if answer[0] > board[0] // 2:
            answer[0] = board[0] // 2
        elif answer[0] < -(board[0] // 2):
            answer[0] = -(board[0] // 2)
        elif answer[1] > board[1] // 2:
            answer[1] = board[1] // 2
        elif answer[1] < -(board[1] // 2):
            answer[1] = -(board[1] // 2)
        
    return answer

 

오늘 배운 풀이 방법을 살펴보자.

문제의 조건에 캐릭터가 보드를 넘어가지 못한다고 돼있다. 따라서 캐릭터가 보드에서 갈 수 있는 최대치를 미리 설정해두었다. 그리고 캐릭터는 항상 [0,0]에서 시작하기 때문에 x값과 y값을 0으로 설정해두었다.

def solution(keyinput, board):
    x_lim, y_lim = board[0]//2, board[1]//2   # 보드에서 갈 수 있는 최대치
    x, y = 0, 0

 

그리고 캐릭터의 움직임(left, right, up, down)을 딕셔너리 형태로 저장해준다.

    move = {
        'left' : (-1,0),
        'right' : (1,0),
        'up' : (0,1),
        'down' : (0,-1)
    }

 

그런 다음 키보드의 입력을 for문을 통해 하나씩 가져온다. 키보드의 입력으로 어디로 얼마나 움직였는 지를 dx와 dy를 통해 각각  move의 value값으로 저장해준다.

    for key in keyinput:
        dx, dy = move[key]

 

만약 키보드의 입력으로 움직인 결과가 보드를 넘어가게 되면, 움직임을 갱신하지 않도록 continue로 else문을 실행하지 않고 넘어가게 해주었다. 캐릭터가 보드를 넘어가는 움직임을 갱신하지 않기 위해서 else문에 x와 y의 값을 갱신하는 코드를 넣어준 것이다. 여기서 abs() 함수를 통해 절대값으로 계산한 이유는 -(마이너스)값과도 비교해야 하기 때문이다.

        if abs(x+dx) > x_lim or abs(y+dy) > y_lim:
            continue
        
        else:
            x, y = x+dx, y+dy
    
    return [x, y]

 

그리고 최종적인 캐릭터의 좌표값을 return해주었다.

수열과 구간 쿼리 2

문제 설명

정수 배열 arr와 2차원 정수 배열 queries이 주어집니다. queries의 원소는 각각 하나의 query를 나타내며, [s, e, k] 꼴입니다.

 query마다 순서대로 s  i  e인 모든 i에 대해 k보다 크면서 가장 작은 arr[i]를 찾습니다. 각 쿼리의 순서에 맞게 답을 저장한 배열을 반환하는 solution 함수를 완성해 주세요.

단, 특정 쿼리의 답이 존재하지 않으면 -1을 저장합니다.

 

오늘 배운 풀이 방법을 살펴보자.

sys를 import 해와서 sys.maxsize라는 것을 사용했다. sys.maxsize는 파이썬 표준 라이브러리의 sys 모듈에 정의된 상수로, 현재 Python 인터프리터에서 표현할 수 있는 가장 큰 정수 값을 나타낸다고 한다. 이는 루프를 무한히 실행하거나, 특정 최대값을 설정할 때 참조값으로 사용할 수 있다.

 

우선 최종 답을 저장할 리스트를 만들어주었다.

import sys

def solution(arr, queries):
    res = []

 

그런 다음 for문을 통해 queries에서 query를 하나씩 가져오고, query의 각각의 값을 s, e, k로 설정했다.

    for query in queries :  
        s, e, k = query

 

여기서 sys.maxsize를 사용한다. 어떤 값이 와도 sys.maxsize 값보다 클 수 없을 것이다. 문제에서는 k보다 크면서 가장 작은 arr[i]값을 찾으라고 하고 있다. 따라서 가장 작은 값을 찾기 위해 sys.maxsize를 이용한 것이다.

sys.maxsize와 가장 먼저 값을 비교하게 되는데, 이 때는 무조건 sys.maxsize 값이 클 것이기 때문에 current_min은 arr[i]로 값이 갱신된다. 그 이후부터는 갱신된 arr[i]값과 순차적으로 비교해나가면서 값을 갱신해나갈것이다.

for문을 통해 s<=i<=e인 모든 i에 대해, if문을 통해 arr[i] > k 인 경우에, current_min 값을 갱신한다.

        current_min = sys.maxsize # 뭘 넣더라도 이 수보다는 클 리가 없다. -> 첫번재 비교하는 수가 가장 작은 수가 된다. 그리고 순차적으로 비교하며 가장 작은 수를 갱신해나갈것이다. 
        for i in range(s, e+1) : # s<=i<=e인 모든 i에 대해
            if arr[i] > k :  # k보다 크면서
                current_min = min(arr[i], current_min) #현재 가장작은 값 <-> 비교하는 대상을 비교해서, 그때그때 가장 작은 값을 갱신해준다.

 

for문을 다 돌고 난 후에도 여전히 current_min 값이 sys.maxsize 값이라면, 문제에서 밑줄 친 부분으로 해당 결과를 처리해야 한다. 따라서 문제의 요구에 따라 최종 답 리스트인 res에 -1을 저장하게 했다.

current_min 값이 sys.maxsize 값이 아닐 경우에는 최종 답 리스트 res에 current_min 값을 추가한다.

        if current_min == sys.maxsize : 
            res.append(-1)
        else : 
            res.append(current_min)
            
    return res

 

최종적으로 res를 return해주었다.


강의 외부에서 추가로 알게 된 내용

CROSS JOIN

CROSS JOIN은 두 테이블을 결합할 때 사용되는 SQL 조인 종류 중 하나다. CROSS JOIN은 모든 가능한 조합을 반환하는 조인 방식으로, 두 테이블의 각 행을 서로 곱하는 방식다.

  • CROSS JOIN은 두 테이블에서 각각의 모든 행을 결합하여 모든 가능한 쌍을 만든다.
  • 이 조인은 조건이 없는 조인이다. 즉, 두 테이블의 관계에 대한 필터링이 없다.

예를 들어보자. 아래와 같 두 테이블 A와 B가 있다고 가정해보자.

CROSS JOIN을 사용한 결과는 각 A 테이블의 행이 B 테이블의 모든 행과 결합되는 형태다.

SELECT * 
FROM A
CROSS JOIN B

결과는 아래와 같다.

 

CROSS JOIN의 특징은 다음과 같다.

  • A 테이블에 2개의 행이 있고, B 테이블에 2개의 행이 있다면, 결과는 2 * 2 = 4개의 행이 생성된다.
  • 자주 사용되지 않지만, 예를 들어 모든 학생과 모든 과목의 조합을 생성하고자 할 때 사용될 수 있다.

즉, CROSS JOIN은 두 테이블의 모든 가능한 조합을 반환하는 조인이다. 조건 없이 결합하며, 큰 데이터셋에서 결과가 매우 커질 수 있다.

'AI 부트캠프 > 챕터3(11.08~12.04)' 카테고리의 다른 글

WIL 7  (0) 2024.11.22
TIL 46 팀 프로젝트  (1) 2024.11.22
TIL 44  (1) 2024.11.20
TIL 43 도전 과제  (2) 2024.11.19
TIL 42  (1) 2024.11.18