KATA#75

codataffee·2024년 6월 28일
0

CODEKATA

목록 보기
75/114
post-thumbnail

WHAT IS KATA?

KATA는 기술과 기술 향상에 초점을 맞춘 코드 챌린지입니다.
일부는 프로그래밍 기본 사항을 교육하는 반면 다른 일부는 복잡한 문제 해결에 중점을 둡니다.

이 용어는 The Pragmatic Programmer 라는 책의 공동 저자인 Dave Thomas 가
무술에서 일본의 카타 개념을 인정하면서 처음 만들어졌습니다.
Dave의 개념 버전은 코드 카타를 프로그래머가
연습과 반복을 통해 기술을 연마하는 데 도움이 되는 프로그래밍 연습으로 정의합니다.


- SQL


✔️ 문제 #1: Weather Observation Station 20

LAT_N 칼럼의 중앙값을 찾는 문제

✔️ 제출 쿼리

✔️ 쿼리 분석

SELECT ROUND(AVG(LAT_N), 4) 
FROM (
     SELECT LAT_N
     FROM (
           SELECT LAT_N,
                  ROW_NUMBER() OVER(ORDER BY LAT_N) ROWN,
                  COUNT(*) OVER() TOTALCNT
           FROM STATION
           ) SORTING
      WHERE ROWN = FLOOR((TOTALCNT + 1) / 2) OR 
            ROWN = CEILING((TOTALCNT + 1) / 2)
      ) MEDIAN

쿼리 작동 세부 내용 정리

  1. INNER 쿼리 (SORTING)

    # 순번 부여하고 정렬하기
    ROW_NUMBER() OVER(ORDER BY LAT_N) ROWN :
    LAT_N 칼럼 내 값을 기준으로 각 행에 오름차순 순번 부여
    COUNT(*) OVER() TOTALCNT :
    전체 행 수
  2. MIDDLE 쿼리

    # 부여된 순번들의 중간에 위치한 값 찾기
    WHERE ROWN = FLOOR((TOTALCNT + 1) / 2) OR 
          ROWN = CEILING((TOTALCNT + 1) / 2) :
          
    # 전체 행 수가 홀수일 경우 1개, 짝수일 경우 2개의 값이 출력
    FLOOR((TOTALCNT + 1) / 2), CEILING((TOTALCNT + 1) / 2) :
    
    # 전체 행 수가 5(홀수)일 경우
    FLOOR((5 + 1) / 2) = 3, CEILING((5 + 1) / 2) = 3
    두 쿼리 모두 3이 된다.
    
    # 전체 행 수가 4(짝수)일 경우
    FLOOR((4 + 1) / 2) = 2, CEILING((4 + 1) / 2) = 3
    FLOOR 는 2, CEILING 은 3 > 결과로 23이 된다.
    
    OR 조건을 사용해 전체 행 수가 홀수, 짝수에 상관없이 
    중간에 위치한 하나 또는 두 개의 행을 선택
  3. OUTER 쿼리

    # 선택된 행들의 LAT_N 값을 AVG(LAT_N)를 사용해 평균 구하기
    
    AVG(LAT_N) :
    짝수 행의 경우 두 값의 평균을 구하고, 
    홀수 행의 경우 한 개의 값을 출력
    
    ROUND(AVG(LAT_N), 4) :
    구해진 중앙값을 소수점 넷째 자리까지 반올림

- PYTHON


✔️ 문제 #1: 가장 큰 수

✔️ 제출 코드

✔️ 코드 분석

def solution(numbers):
    # 숫자들을 문자열로 변환
    numbers = list(map(str, numbers))
    
    # 문자열을 세 번 반복하여 비교 기준으로 사용, 내림차순 정렬
    # key = lambda x : x*3 > x를 세 번 반복한 값이 기준이라는 의미
    numbers.sort(key=lambda x: x*3, reverse=True)
    
    # 정렬된 숫자들을 이어붙여 결과 문자열 생성
    result = ''.join(numbers)
    
    # '0000'과 같은 경우 '0'으로 변환 (테스트 케이스 조건..)
    if result[0] == '0':
        return '0'
    return result

코드 작동 세부 내용 정리

numbers = list(map(str, numbers)) :

숫자 리스트 numbers 의 각 요소를 문자열로 변환
예) [3, 30, 34, 5, 9] → ["3", "30", "34", "5", "9"]

numbers.sort(key=lambda x: x*3, reverse=True) :

sort 메서드를 사용하여 문자열 리스트 정렬

key = lambda x: x*3
각 문자열 x를 세 번 반복한 값을 정렬 기준으로 사용
예) "3" → "333"
    "30" → "303030"
    "34" → "343434"
    "5" → "555"
    "9" → "999"
    
문자열을 세 번 반복하는 이유는 자릿수를 맞춰 비교하기 위해,
"34"는 "3"보다 길지만 "34"와 "3"을 비교할 때 
"34"가 더 큰 값을 만들도록 하기 위함

reverse=True
내림차순으로 정렬

정렬 후 결과
["9", "5", "34", "3", "30"]

result = ''.join(numbers) :

정렬된 문자열 리스트를 하나의 문자열로 결합
예) ["9", "5", "34", "3", "30"] → "9534330"

✔️ CHECK POINT

  • SQL

서브쿼리 단계별 작성하기 :

  1. INNER 쿼리 (SORTING)

    # 순번 부여하고 정렬하기
    ROW_NUMBER() OVER(ORDER BY LAT_N) ROWN :
    LAT_N 칼럼 내 값을 기준으로 각 행에 오름차순 순번 부여
    COUNT(*) OVER() TOTALCNT :
    전체 행 수
  2. MIDDLE 쿼리 (WHERE)

    # 부여된 순번들의 중간에 위치한 값 찾기
    WHERE ROWN = FLOOR((TOTALCNT + 1) / 2) OR 
          ROWN = CEILING((TOTALCNT + 1) / 2) :
          
    # 전체 행 수가 홀수일 경우 1개, 짝수일 경우 2개의 값이 출력
    FLOOR((TOTALCNT + 1) / 2), CEILING((TOTALCNT + 1) / 2) :
    
    # 전체 행 수가 5(홀수)일 경우
    FLOOR((5 + 1) / 2) = 3, CEILING((5 + 1) / 2) = 3
    두 쿼리 모두 3이 된다.
    
    # 전체 행 수가 4(짝수)일 경우
    FLOOR((4 + 1) / 2) = 2, CEILING((4 + 1) / 2) = 3
    FLOOR 는 2, CEILING 은 3 > 결과로 23이 된다.
    
    OR 조건을 사용해 전체 행 수가 홀수, 짝수에 상관없이 
    중간에 위치한 하나 또는 두 개의 행을 선택
  3. OUTER 쿼리 (SELECT)

    # 선택된 행들의 LAT_N 값을 AVG(LAT_N)를 사용해 평균 구하기
    
    AVG(LAT_N) :
    짝수 행의 경우 두 값의 평균을 구하고, 
    홀수 행의 경우 한 개의 값을 출력
    
    ROUND(AVG(LAT_N), 4) :
    구해진 중앙값을 소수점 넷째 자리까지 반올림
  • PYTHON

map()sort(), 그리고 lambda :
숫자를 문자열로 변경하기 → 정렬하기 (key 값 정의하기)

numbers = list(map(str, numbers)) :

숫자 리스트 numbers 의 각 요소를 문자열로 변환
예) [3, 30, 34, 5, 9] → ["3", "30", "34", "5", "9"]

numbers.sort(key=lambda x: x*3, reverse=True) :

sort 메서드를 사용하여 문자열 리스트 정렬

key = lambda x: x*3
각 문자열 x를 세 번 반복한 값을 정렬 기준으로 사용
예) "3" → "333"
    "30" → "303030"
    "34" → "343434"
    "5" → "555"
    "9" → "999"
    
문자열을 세 번 반복하는 이유는 자릿수를 맞춰 비교하기 위해,
"34"는 "3"보다 길지만 "34"와 "3"을 비교할 때 
"34"가 더 큰 값을 만들도록 하기 위함

reverse=True
내림차순으로 정렬

정렬 후 결과
["9", "5", "34", "3", "30"]

result = ''.join(numbers) :

정렬된 문자열 리스트를 하나의 문자열로 결합
예) ["9", "5", "34", "3", "30"] → "9534330"

profile
커피 좋아하는 데이터 꿈나무

0개의 댓글

관련 채용 정보