오늘은 파이썬을 이용하여 배울 수 있는 통계학에 대해서 알아보겠습니다. 요즘 데이터 분석과 머신러닝이 대세인 만큼, 통계학의 중요성도 점점 더 커지고 있어요. 그래서 이번에 소개할 책은 바로 "파이썬으로 배우는 통계학 교과서"입니다. 이 책은 통계학의 기본 개념부터 시작해서, 파이썬을 활용한 데이터 분석 방법까지 폭넓게 다루고 있어요.

책 소개

"파이썬으로 배우는 통계학 교과서"는 통계학을 처음 접하는 사람부터 어느 정도 알고 있는 사람까지 모두에게 유용한 책이에요. 이 책은 통계학의 기초부터 시작해, 데이터 분석, 머신러닝에 필요한 확률과 회귀에 대한 개념까지 설명하고 있어요. 특히, 파이썬 라이브러리를 사용하여 통계 처리를 쉽게 할 수 있다는 점이 매력적이에요.

통계학의 기본 개념

통계학은 데이터를 수집하고 분석하여 의미 있는 정보를 도출하는 학문이에요. 기본적으로 기술통계, 추론통계, 회귀분석 등 다양한 분야로 나뉘어져 있어요. 이 책에서는 이러한 기본 개념을 쉽게 설명해 주기 때문에, 통계학에 대한 두려움을 덜 수 있어요.

파이썬 프로그래밍과 통계학

파이썬은 데이터 분석에 매우 유용한 프로그래밍 언어로, 다양한 라이브러리(예: NumPy, Pandas, Matplotlib 등)를 통해 통계적 분석을 쉽게 수행할 수 있어요. 이 책에서는 파이썬을 활용하여 통계학의 이론을 실제로 적용하는 방법을 배울 수 있어요.

기술통계의 중요성

기술통계는 데이터를 요약하고 정리하는 데 필요한 기초적인 통계 기법이에요. 이 책의 3장에서는 "기술통계"에 대해 다루고 있는데, 데이터 분류와 관측, 변수의 개념을 설명하고 있어요. 데이터 분석의 첫 단계로서 기술통계는 매우 중요하답니다.

확률과 확률분포

확률은 통계학의 핵심 개념 중 하나로, 사건이 발생할 가능성을 수치로 표현하는 방법이에요. 이 책에서는 확률과 확률분포에 대한 기본적인 이해를 돕기 위해 다양한 예시와 함께 설명하고 있어요. 확률분포는 데이터의 분포를 이해하는 데 필수적이죠.

모집단과 표본추출

모집단은 연구의 대상이 되는 전체 집단을 의미하고, 표본은 그 모집단에서 선택된 일부를 말해요. 이 책에서는 표본추출의 중요성과 방법에 대해 자세히 설명하고 있어요. 올바른 표본추출은 통계적 분석의 신뢰성을 높이는 데 큰 역할을 해요.

통계적 가설검정

가설검정은 통계학에서 매우 중요한 개념으로, 주어진 데이터에 기반하여 가설의 진위를 판단하는 방법이에요. 이 책에서는 가설검정의 기본 원리와 절차를 쉽게 설명하고 있어요. 이를 통해 독자들은 실제 데이터 분석에 적용할 수 있는 기초 지식을 쌓을 수 있어요.

통계모델과 정규선형모델

통계모델은 데이터를 설명하기 위해 수학적 모델을 사용하는 방법이에요. 정규선형모델은 통계학에서 가장 기본적인 모델 중 하나로, 이 책에서는 이를 통해 데이터의 관계를 분석하는 방법을 배울 수 있어요.

통계학과 머신러닝의 관계

마지막으로, 통계학과 머신러닝은 밀접한 관계가 있어요. 머신러닝의 많은 알고리즘이 통계학의 이론에 기반하고 있기 때문에, 통계학을 잘 이해하면 머신러닝을 배우는 데 큰 도움이 돼요. 이 책에서는 통계학의 기초를 통해 머신러닝의 개념을 쉽게 이해할 수 있도록 도와줘요.

이 책은 통계학을 배우고자 하는 모든 분들에게 추천할 만한 훌륭한 자료입니다. 파이썬을 활용하여 통계학을 배우는 데 큰 도움이 될 거예요. 통계학의 기초부터 시작해, 데이터 분석과 머신러닝까지 폭넓은 지식을 쌓을 수 있는 기회를 놓치지 마세요!

 

'책 서평' 카테고리의 다른 글

그로스 해킹 5장 ~6장  (0) 2024.11.24
그로스 해킹 3~4장  (0) 2024.11.18
밑바닥부터 시작하는 딥러닝 5를 읽고  (0) 2024.11.15
그로스 해킹 1장 ~ 3장  (2) 2024.11.10

문제 설명

이번 포스팅에서는 STATION 테이블에서 가장 짧은 도시 이름가장 긴 도시 이름을 찾는 SQL 문제를 다룹니다. 단, 조건은 다음과 같습니다:

  1. 가장 짧은 도시 이름과 그 길이를 구합니다.
    • 만약 이름이 같은 경우, 알파벳 순으로 가장 앞선 도시를 선택합니다.
  2. 가장 긴 도시 이름과 그 길이를 구합니다.
    • 마찬가지로, 이름이 같은 경우, 알파벳 순으로 가장 앞선 도시를 선택합니다.
  3. 최종 결과는 두 도시의 이름과 이름의 길이를 포함해야 합니다.

문제 해결 접근 방식

  1. 도시 이름 길이 계산: SQL의 LENGTH(CITY)를 사용하여 도시 이름의 길이를 계산합니다.
  2. 가장 짧은 도시 찾기:
    • 도시 이름 길이를 기준으로 오름차순(ASC) 정렬.
    • 같은 길이를 가진 도시가 여러 개라면 알파벳 순으로 정렬.
    • LIMIT 1을 사용해 가장 짧은 이름을 가진 도시 중 첫 번째 도시를 선택.
  3. 가장 긴 도시 찾기:
    • 도시 이름 길이를 기준으로 내림차순(DESC) 정렬.
    • 같은 길이를 가진 도시가 여러 개라면 알파벳 순으로 정렬.
    • LIMIT 1을 사용해 가장 긴 이름을 가진 도시 중 첫 번째 도시를 선택.
  4. 결과 병합:
    • UNION ALL을 사용해 두 개의 쿼리 결과를 하나로 병합합니다.

SQL 쿼리 코드

(SELECT CITY, LENGTH(CITY) AS NAME_LENGTH
 FROM STATION
 ORDER BY LENGTH(CITY) ASC, CITY ASC
 LIMIT 1)
UNION ALL
(SELECT CITY, LENGTH(CITY) AS NAME_LENGTH
 FROM STATION
 ORDER BY LENGTH(CITY) DESC, CITY ASC
 LIMIT 1);

 

예제 데이터

다음과 같은 STATION 테이블이 있다고 가정합니다:

CITYLENGTH(CITY)

Paris 5
Dubai 5
New York 8
Tokyo 5
Johannesburg 12

실행 결과

위 데이터를 기반으로 쿼리를 실행하면 다음과 같은 결과가 나옵니다:

CITYNAME_LENGTH

Dubai 5
Johannesburg 12
  • 가장 짧은 도시: 이름 길이가 5자인 도시 중 알파벳 순으로 가장 앞선 Dubai.
  • 가장 긴 도시: 이름 길이가 12자인 도시 Johannesburg.

추가 팁

  • LENGTH() 함수는 문자열의 길이를 계산할 때 유용합니다.
  • ORDER BY와 LIMIT은 데이터를 정렬하고 특정 조건에 맞는 결과를 빠르게 찾는 데 효과적입니다.
  • UNION ALL은 두 쿼리 결과를 합쳐주는 역할을 합니다. 중복 제거가 필요하다면 UNION을 사용하면 됩니다.

마무리

이번 문제를 통해 SQL에서 문자열 길이 계산과 정렬, 그리고 조건에 맞는 데이터를 선택하는 방법을 배웠습니다. 실무에서도 데이터의 최대값, 최소값, 특정 조건에 맞는 값을 찾는 데 유용하게 사용할 수 있습니다.

궁금한 점이나 개선할 방법이 있다면 댓글로 남겨주세요! 😊

'SQL' 카테고리의 다른 글

Weather Observation Station 17  (0) 2024.10.31
Weather Observation Station 16  (0) 2024.10.29
Weather Observation Station 15  (0) 2024.10.23
Weather Observation Station 14  (0) 2024.10.22
Weather Observation Station 13  (0) 2024.10.20

 

 

TODAY TIL

📌 문제 설명

두 정수 X, Y의 임의의 자리에서 공통으로 나타나는 숫자들을 사용해 만들 수 있는 가장 큰 정수를 두 수의 "짝꿍"이라고 합니다.
짝꿍을 구하는 규칙은 다음과 같습니다:

  1. X와 Y에 공통으로 나타나는 숫자만 사용합니다.
  2. 공통 숫자 중 가능한 최대 빈도수만큼 사용합니다.
  3. 공통 숫자가 없다면 -1을 반환합니다.
  4. 짝꿍이 0으로만 구성되어 있다면 0을 반환합니다.

예시

  • X = 3403, Y = 13203
    → 짝꿍: 330
  • X = 5525, Y = 1255
    → 짝꿍: 552
  • X = 12345, Y = 67890
    → 짝꿍: -1

💡 문제 해결 방법

이 문제를 해결하기 위한 단계별 접근법은 다음과 같습니다:

Step 1: 숫자의 빈도수 계산

  • X와 Y의 각 숫자가 몇 번 나타나는지를 계산합니다.
  • collections.Counter를 사용하면 간단하게 자릿수의 빈도를 구할 수 있습니다.

Step 2: 공통 숫자와 빈도수 찾기

  • X와 Y의 공통 숫자를 찾고, 각 숫자의 최소 빈도를 기준으로 사용할 수 있는 최대 빈도를 계산합니다.

Step 3: 결과 문자열 생성

  • 공통 숫자를 내림차순으로 정렬하여 가장 큰 숫자를 만듭니다.
  • 예외 처리:
    • 공통 숫자가 없다면 -1 반환.
    • 결과가 0으로만 구성되어 있다면 0 반환.

🖥 코드 구현

from collections import Counter

def solution(X, Y):
    # Step 1: 숫자의 빈도수를 계산
    count_X = Counter(X)
    count_Y = Counter(Y)
    
    # Step 2: 공통 숫자와 최소 빈도 계산
    common_numbers = []
    for num in count_X.keys():
        if num in count_Y:
            # 공통으로 등장하는 숫자 중 가능한 최대 갯수를 추가
            common_numbers.extend([num] * min(count_X[num], count_Y[num]))
    
    # Step 3: 결과 문자열 생성
    if not common_numbers:  # 공통 숫자가 없으면
        return "-1"
    
    # 숫자를 내림차순으로 정렬
    common_numbers.sort(reverse=True)
    result = ''.join(common_numbers)
    
    # 숫자가 모두 0으로만 구성된 경우
    if result[0] == "0":
        return "0"
    
    return result

 

🛠 동작 원리 설명

1. Counter를 활용한 숫자 빈도수 계산

count_X = Counter("3403")  # {'3': 2, '4': 1, '0': 1}
count_Y = Counter("13203") # {'1': 1, '3': 2, '2': 1, '0': 1}

Counter는 각 숫자의 빈도를 딕셔너리 형태로 반환합니다.

2. 공통 숫자와 최소 빈도 찾기

count_X와 count_Y의 키를 비교하여 공통 숫자를 찾고, 가능한 최대 빈도를 리스트에 추가합니다.

common_numbers = ['3', '3', '0']  # 최소 빈도를 기준으로 계산

 

3. 결과 생성

common_numbers를 내림차순으로 정렬하여 가장 큰 숫자를 생성합니다.

common_numbers.sort(reverse=True)  # ['3', '3', '0']
result = ''.join(common_numbers)   # "330"

 

⚙️ 테스트 케이스

# 테스트 케이스
print(solution("3403", "13203"))  # 330
print(solution("5525", "1255"))   # 552
print(solution("12345", "67890")) # -1
print(solution("100", "203045"))  # 0
print(solution("0", "0"))         # 0

 

결과

XY결과

3403 13203 330
5525 1255 552
12345 67890 -1
100 203045 0
0 0 0

💡 문제 풀이 요약

  1. 숫자의 빈도를 계산하여 X와 Y의 공통 숫자를 찾습니다.
  2. 공통 숫자를 기준으로 가능한 최대 빈도를 계산하여 숫자를 조합합니다.
  3. 숫자를 내림차순 정렬하여 가장 큰 짝꿍을 반환합니다.
  4. 특별 케이스 (공통 숫자가 없거나, 결과가 0)를 처리합니다.

⏳ 시간 복잡도

  • 빈도 계산: O(N + M) (X와 Y의 길이)
  • 공통 숫자 탐색 및 정렬: O(10 + K log K) (K는 공통 숫자의 수, 최대 10)

최종 시간 복잡도는 **O(N + M)**입니다.


✏️ 블로그 마무리

이 문제는 문자열 조작과 빈도 계산을 효율적으로 다루는 연습에 적합합니다.
collections.Counter와 같은 내장 모듈을 활용하면 복잡한 문제도 간단히 해결할 수 있습니다.

여러분도 자신만의 풀이법으로 문제를 해결하고 Python을 더욱 깊게 이해해 보세요! 🚀
궁금한 점이나 추가적인 개선 아이디어가 있다면 댓글로 공유해 주세요! 😊

TODAY TIL

문제 소개

햄버거 가게에서 일을 하는 상수는 햄버거를 포장하는 작업을 합니다. 재료들이 정해진 순서로 쌓이면 상수는 이를 포장합니다.
햄버거를 완성할 수 있는 순서는 아래와 같습니다:

  • [빵(1) – 야채(2) – 고기(3) – 빵(1)]

주어진 재료 배열에서 햄버거를 몇 개 포장할 수 있는지 구하는 프로그램을 작성해봅시다.


문제 예시

입력:

ingredient = [2, 1, 1, 2, 3, 1, 2, 3, 1]

출력:

2

설명:

  1. 첫 번째 햄버거는 [1, 2, 3, 1]로 완성됩니다.
  2. 두 번째 햄버거는 [1, 2, 3, 1]로 완성됩니다.
    결과적으로 2개의 햄버거를 포장할 수 있습니다.

문제 해결 접근법

  1. 스택(Stack) 활용:
    • 스택을 사용하여 재료를 추가하면서 햄버거 완성 여부를 확인합니다.
    • 햄버거가 완성되면 스택에서 해당 재료들을 제거합니다.
  2. 햄버거 완성 조건:
    • 스택의 마지막 4개의 재료가 [1, 2, 3, 1]인지 확인합니다.
  3. 시간 최적화:
    • 슬라이싱 대신 stack.pop()을 사용하여 불필요한 연산을 줄입니다.

최적화된 코드

아래 코드는 시간 초과를 방지하기 위해 최적화된 방식으로 작성되었습니다.

def solution(ingredient):
    stack = []  # 재료를 담을 스택
    count = 0   # 포장한 햄버거 개수

    for item in ingredient:
        stack.append(item)  # 스택에 재료 추가

        # 스택의 길이가 4 이상일 때 마지막 4개 요소를 직접 비교
        if len(stack) >= 4:
            if stack[-1] == 1 and stack[-2] == 3 and stack[-3] == 2 and stack[-4] == 1:
                # 햄버거 완성 -> 스택에서 제거
                stack.pop()  # 빵 제거
                stack.pop()  # 고기 제거
                stack.pop()  # 야채 제거
                stack.pop()  # 빵 제거
                count += 1  # 햄버거 개수 증가

    return count

 

코드 실행 과정

입력:

ingredient = [2, 1, 1, 2, 3, 1, 2, 3, 1]
print(solution(ingredient))  # 출력: 2

 

실행 과정:

  1. 스택에 [2] 추가 → 햄버거 완성 불가능.
  2. 스택에 [2, 1] 추가 → 햄버거 완성 불가능.
  3. 스택에 [2, 1, 1] 추가 → 햄버거 완성 불가능.
  4. 스택에 [2, 1, 1, 2, 3, 1] 추가 → 햄버거 완성! 스택에서 제거 → [2, 1].
  5. 나머지 재료를 처리하여 두 번째 햄버거 완성.

결과적으로 햄버거 2개 포장.


시간 및 공간 복잡도

  1. 시간 복잡도:
    • 각 재료에 대해 stack.append()와 비교, 제거 연산이 이루어지므로 O(n).
  2. 공간 복잡도:
    • 스택의 최대 크기는 ingredient와 동일하므로 O(n).

주요 개선 사항

  • 슬라이싱 제거:
    기존의 stack[-4:] 대신, stack[-1], stack[-2], stack[-3], stack[-4]로 개별 접근하여 연산 속도 최적화.
  • 불필요한 복사 연산 최소화:
    stack.pop()을 사용해 스택의 크기를 조정하며, 필요 없는 메모리 복사를 방지.

결론

이 문제는 스택 자료구조를 활용하여 재료의 순서를 관리하고, 햄버거 포장이 완료될 때마다 이를 제거하는 방식으로 효율적으로 해결할 수 있습니다. 최적화된 코드로 시간 초과 문제를 해결했으며, 스택 활용의 기본 개념을 연습하기에도 좋은 문제입니다.

 

 

 

TODAY TIL

환규와 태욱이는 문자열을 가지고 재미있는 "탕수육 게임"을 하고 있습니다. 게임의 규칙은 다음과 같습니다:

  1. 누가 먼저 시작할지 순서를 정합니다.
  2. 먼저 시작하는 사람이 단어의 첫 글자를 말합니다.
  3. 이후 두 사람은 번갈아 가며 다음 글자를 순서대로 말합니다.
  4. 단어의 마지막 글자에 도달하면, 다시 단어의 첫 글자로 돌아가서 반복합니다.
  5. 잘못된 글자를 말하면 게임에서 지게 됩니다.

예를 들어, 단어가 탕수육이라면:

  • 첫 번째 사람: "탕", "육", "수", "탕", "육", "수" ...
  • 두 번째 사람: "수", "탕", "육", "수", "탕", "육" ...

코드 소개

탕수육 게임의 규칙을 바탕으로, 두 사람이 번갈아 문자열을 나누어 가져가는 방식을 Python 코드로 구현했습니다. 이번 포스팅에서는 이 코드를 분석하며 어떻게 동작하는지 알아보겠습니다.

 

코드

def solution(case):
    answer = 0

    for v in case:
        player1 = []
        player2 = []
        for i, c in enumerate(v if (len(v) % 2) == 0 else v * 2):
            if i % 2 == 0:
                player1.append(c)
            else:
                player2.append(c)
        print("".join(player1))
        print("".join(player2))
    return answer


n = int(input())
games = [input() for _ in range(n)]
solution(games)

 

코드 분석

1. 함수 정의

def solution(case):
    answer = 0

 

 

  • 함수 solution은 문자열의 리스트 case를 입력으로 받습니다.
  • answer는 반환 값으로 초기화되지만, 현재는 출력 외에 사용되지 않습니다.

2. 게임 데이터 처리

for v in case:
    player1 = []
    player2 = []

 

 

  • 각 문자열 v를 순회하며, 두 사람의 문자 선택을 저장할 리스트 player1과 player2를 초기화합니다.

3. 문자열 순회 및 나누기

for i, c in enumerate(v if (len(v) % 2) == 0 else v * 2):
    if i % 2 == 0:
        player1.append(c)
    else:
        player2.append(c)

 

 

  • 문자열의 길이에 따라 처리 방식이 달라집니다:
    1. 짝수 길이: 문자열 v 그대로 사용.
    2. 홀수 길이: 문자열 v를 두 번 반복한 문자열 v * 2 사용.
      • 이렇게 하면 홀수 길이에서도 두 사람이 계속 번갈아 가며 문자를 가져갈 수 있습니다.
  • enumerate를 사용해 문자열의 각 문자와 해당 인덱스 i를 가져옵니다:
    • i % 2 == 0: 첫 번째 사람이 선택(player1에 추가).
    • i % 2 == 1: 두 번째 사람이 선택(player2에 추가).

4.결과 출력

print("".join(player1))
print("".join(player2))

 

 

 

  • 두 사람의 선택 결과를 각각 출력합니다.
  • player1과 player2 리스트의 문자를 합쳐 문자열로 변환한 뒤 출력합니다.

5.입력 및 함수 호출

n = int(input())
games = [input() for _ in range(n)]
solution(games)

 

 

  • 입력 데이터:
    • 첫 번째 줄: 게임의 수 n.
    • 이후 n개의 문자열이 게임의 데이터로 입력됩니다.
  • solution 함수에 입력 데이터를 전달하여 결과를 처리합니다.

동작 예시

입력

2
탕수육
ABC

 

처리 과정

  1. 첫 번째 게임: "탕수육"
    • player1: "탕육수" → 첫 번째 사람이 가져간 문자.
    • player2: "수탕육" → 두 번째 사람이 가져간 문자.
    • 출력:
       
탕육수
수탕육

 

2 .두 번째 게임: "ABC"

  • 문자열 길이가 홀수이므로 "ABCABC"로 확장.
  • player1: "ACB" → 첫 번째 사람이 가져간 문자.
  • player2: "BCA" → 두 번째 사람이 가져간 문자.
  • 출력:
     
ACB
BCA

 

최종 출력

탕육수
수탕육
ACB
BCA

 

코드의 한계와 개선 가능성

  1. 반복 확장 방식의 비효율성
    • 홀수 길이 문자열에서 v * 2로 확장하면 메모리를 낭비할 수 있습니다.
    • 이를 대신해 인덱스를 순환적으로 접근하면 더 효율적입니다.
  2. 리턴 값 사용
    • 현재 코드는 결과를 출력만 하고 반환하지 않습니다. 결과를 리스트로 반환하면 더 유연하게 활용할 수 있습니다.

개선된 코드

def solution(case):
    results = []
    for v in case:
        player1 = []
        player2 = []
        n = len(v)
        for i in range(n):
            if i % 2 == 0:
                player1.append(v[i % n])
            else:
                player2.append(v[i % n])
        results.append(("".join(player1), "".join(player2)))
    return results

# 입력 처리
n = int(input())
games = [input() for _ in range(n)]
result = solution(games)

# 결과 출력
for r in result:
    print(r[0])
    print(r[1])

 

결론

이 코드는 두 사람이 번갈아 문자열을 나누는 방식으로 게임을 진행하도록 구현되었습니다. 이를 통해 문자열의 반복적인 패턴을 쉽게 처리할 수 있습니다. 개선된 코드는 더 효율적으로 처리하며, 결과를 반환해 다양한 방식으로 활용할 수 있습니다.

탕수육 게임처럼 단순하지만 재미있는 문제를 통해 문자열 처리와 반복 구조에 대한 이해를 높여보세요! 😊

 

TODAY TIL

📌 문제 설명

H-Index는 과학자의 생산성과 연구 영향력을 나타내는 지표입니다. 한 과학자의 H-Index h는 다음과 같이 정의됩니다:

  • h번 이상 인용된 논문이 h편 이상
  • 나머지 논문이 h번 이하 인용

즉, hh의 최댓값을 구하는 것이 목표입니다.

제한사항

  1. 논문 수 n: 1 이상 1,000 이하
  2. 논문별 인용 횟수: 0 이상 10,000 이하

💡 문제 이해

논문의 인용 횟수 배열을 분석하여, 위 조건을 만족하는 hh의 최댓값을 구합니다.


🛠️ 풀이 방법

문제를 해결하기 위해 다음과 같은 단계를 거칩니다:

  1. 내림차순 정렬
    • 논문의 인용 횟수를 내림차순으로 정렬합니다.
    • 이렇게 하면 인용 횟수가 높은 논문부터 조건을 확인할 수 있습니다.
  2. H-Index 조건 확인
    • 정렬된 배열에서 i+1번째 논문이 i+1번 이상 인용되었는지 확인합니다.
    • 이 조건을 만족하는 i+1h입니다.
  3. 조건 만족 여부
    • 조건을 만족하지 않는 순간 반복을 멈추고, 이전까지 구한 hh의 최댓값을 반환합니다.

 

📄 Python 코드

def solution(citations):
    # 1. 내림차순 정렬
    citations.sort(reverse=True)
    
    # 2. H-Index 계산
    h_index = 0
    for i, citation in enumerate(citations):
        if citation >= i + 1:  # h 조건 확인
            h_index = i + 1
        else:
            break
    
    # 3. 결과 반환
    return h_index

 

🔍 단계별 풀이

  1. 내림차순 정렬
citations.sort(reverse=True)

 

 

  • 논문의 인용 횟수를 내림차순으로 정렬합니다.
  • 예시 입력: [3, 0, 6, 1, 5]
  • 정렬 결과: [6, 5, 3, 1, 0]

2. H-Index 조건 확인

for i, citation in enumerate(citations):
    if citation >= i + 1:
        h_index = i + 1
    else:
        break

 

 

 

  • 논문 i+1번째의 인용 횟수가 i+1 이상인지 확인합니다.
  • 조건이 만족되지 않으면 반복을 멈춥니다.

3. 최댓값 반환

return h_index

 

 

  • 최종적으로 구한 h 값 중 최댓값을 반환합니다.

 

📊 예제 테스트

예제 1

citations = [3, 0, 6, 1, 5]
print(solution(citations))  # 결과: 3

 

 

  • 정렬: [6, 5, 3, 1, 0]
  • hh 계산:
    • 1번째 논문: 6>=1 → h=1
    • 2번째 논문: 5>=2 → h=2
    • 3번째 논문: 3>=3 → h=3
    • 4번째 논문: 1<4 → 조건 불만족, 종료
  • 최종 결과: h=3

예제 2

citations = [10, 8, 5, 4, 3]
print(solution(citations))  # 결과: 4

 

 

  • 정렬: [10, 8, 5, 4, 3]
  • hh 계산:
    • 1번째 논문: 10>=1 → h=1
    • 2번째 논문: 8>=2 → h=2
    • 3번째 논문: 5>=3 → h=3
    • 4번째 논문: 4>=4 → h=4
    • 5번째 논문: 3<5 → 조건 불만족, 종료
  • 최종 결과: h=4

⏳ 복잡도 분석

  • 시간 복잡도
    • 정렬: O(nlog⁡n)
    • 배열 순회: O(n)
    • 총합: O(nlog⁡n)
  • 공간 복잡도
    • 추가 메모리를 사용하지 않으므로 O(1)

✨ 마무리

H-Index 문제는 간단한 조건 확인과 정렬을 통해 해결할 수 있습니다. 중요한 점은 조건을 만족하는 순간까지 hh를 계산하고 최댓값을 반환하는 것입니다.

이 코드를 통해 데이터 분석 및 알고리즘 설계 능력을 키울 수 있으며, 특히 논문이나 데이터를 분석하는 데 유용한 지표 계산에 활용할 수 있습니다.

코드와 풀이에 대한 질문이 있으면 댓글로 남겨주세요!

TODAY TIL

안녕하세요! 😊 오늘은 숫자를 영어로 읽어서 사전순으로 정렬하는 재미있는 문제를 함께 풀어보겠습니다. 이 문제는 파이썬으로 간단하게 구현할 수 있으니, 따라오세요!


문제 설명 📖

  1. 숫자를 숫자 단위로 영어로 읽는다.
    • 예: 79 → seven nine, 80 → eight zero
  2. 영어로 읽은 숫자를 기준으로 사전순 정렬한다.
    • 예: 80 (eight zero) → 79 (seven nine)
  3. 정렬한 숫자를 한 줄에 10개씩 출력한다.

입출력 예시 📝

입력

79 80

 

출력

80 79

 

또 다른 예시

입력

8 15

 

출력

8 11 12 13 15 14 10 9

 

문제 풀이 과정 💡

1단계: 숫자를 영어로 변환하기

숫자를 하나씩 쪼개서 영어로 읽어야 해요.
예를 들어:

  • 79 → seven nine
  • 80 → eight zero

이를 위해 각 자리 숫자를 영어로 변환하는 함수를 만듭니다.

2단계: 정렬 기준 만들기

숫자를 영어로 변환한 후, 영어 문자열 기준으로 정렬합니다.

3단계: 한 줄에 10개씩 출력하기

정렬된 숫자들을 10개씩 묶어서 출력하면 됩니다.

 

파이썬 코드 🐍

def number_to_words(num):
    # 숫자를 영어로 변환하는 함수
    digits = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
    return " ".join(digits[int(digit)] for digit in str(num))

def solve_number_problem(M, N):
    # M부터 N까지 숫자를 영어로 변환하여 정렬
    numbers = list(range(M, N + 1))
    sorted_numbers = sorted(numbers, key=number_to_words)
    
    # 결과를 한 줄에 10개씩 출력
    for i in range(0, len(sorted_numbers), 10):
        print(" ".join(map(str, sorted_numbers[i:i + 10])))

# 입력 받기
M, N = map(int, input().split())
solve_number_problem(M, N)

 

코드 설명 🛠️

함수 number_to_words

  • 숫자 하나를 받아서 숫자 단위로 영어 문자열로 변환합니다.
  • 예: 79 → seven nine, 80 → eight zero
  •  
digits = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
return " ".join(digits[int(digit)] for digit in str(num))

 

함수 solve_number_problem

  1. M부터 N까지 숫자를 리스트로 생성합니다.
    • 예: M=79, N=80 → [79, 80]
  2. 숫자를 number_to_words 기준으로 정렬합니다.
    • 예: 79 → seven nine, 80 → eight zero
    • 정렬 결과: [80, 79]
  3. 한 줄에 10개씩 출력합니다.
    • 예: print(" ".join(...))

예제 실행 결과 🎯

입력

8 15

 

출력

8 11 12 13 15 14 10 9

 

문제를 해결하면서 배운 점 📚

  1. 숫자를 영어로 변환하기 위해 문자열 처리를 배웠어요.
  2. sorted 함수로 정렬 기준을 자유롭게 설정하는 방법을 익혔어요.
  3. 한 줄에 10개씩 출력하는 반복문 작성법도 알게 되었어요.

마무리 ✍️

이번 문제는 숫자를 영어로 읽는 독특한 방법과 정렬 기준 설정이 핵심이었습니다. 여러분도 파이썬으로 재미있게 구현해보세요! 😊

TODAY TIL

온라인 게임에서 세준이와 세비가 키운 군대가 대결을 펼친다면 어떻게 될까요? 이번 포스팅에서는 각 군대의 병사들이 전투를 벌여 최후의 승자를 가리는 시뮬레이션 문제를 풀어보려고 합니다. 문제를 간단히 설명하고, 이를 해결하기 위한 파이썬 코드를 함께 살펴볼게요!

문제 설명

세준이와 세비는 각각 군대를 키웠고, 이제 서로의 병사들로 전쟁을 하려고 합니다. 전쟁은 여러 번의 전투로 이루어지며, 매 전투에서 살아남은 병사들 중 가장 약한 병사가 죽게 됩니다. 이 과정을 한 명의 병사만 남을 때까지 반복하며, 최후에 살아남은 병사가 속한 팀이 승리하게 됩니다.

문제의 규칙은 다음과 같습니다:

  • 입력: 첫 번째 줄에 테스트 케이스의 개수 T가 주어집니다. 각 테스트 케이스에서는 두 줄에 걸쳐서 세준이와 세비의 병사 수와 각 병사의 힘이 주어집니다.
  • 출력: 각 테스트 케이스마다 승리한 팀을 출력합니다. 세준이가 이기면 'S', 세비가 이기면 'B', 둘 다 죽으면 'C'를 출력합니다.

병사의 힘은 정수로 주어지며, 이 값이 클수록 강한 병사를 의미합니다. 전투 중에는 두 팀의 병사 중 약한 병사들이 먼저 죽게 되고, 승자를 가릴 때까지 전투가 반복됩니다.

 

입력 예시

1
3 3
5 10 7
6 9 8

 

  • 첫째 줄: 테스트 케이스의 수 (1)
  • 둘째 줄: 세준이의 병사 수 (3명)과 세비의 병사 수 (3명)
  • 셋째 줄: 세준이의 병사들의 힘 (5, 10, 7)
  • 넷째 줄: 세비의 병사들의 힘 (6, 9, 8)

출력 예시

S

 

  • 세준이가 승리한 경우 'S' 출력

파이썬 코드로 문제 풀이하기

이제 이 문제를 해결하기 위한 파이썬 코드를 작성해볼게요. 아래 코드는 주어진 병사들의 힘을 비교하면서 각 팀의 병사들이 하나씩 전멸해가는 과정을 시뮬레이션해줍니다.

n = int(input())
for i in range(n):
    input()  # 테스트 케이스 번호나 팀 이름은 사용하지 않음
    a, b = map(int, input().split())
    s_list = list(map(int, input().split()))
    b_list = list(map(int, input().split()))
    
    # 병사들의 힘을 내림차순으로 정렬하여 가장 강한 병사가 앞에 오도록 함
    s_list.sort(reverse=True)
    b_list.sort(reverse=True)

    # 두 팀 중 한 팀의 병사가 전멸할 때까지 라운드를 진행함
    while s_list and b_list:
        # 세준이의 가장 강한 병사가 세비의 가장 강한 병사보다 강할 경우
        if s_list[0] >= b_list[0]:
            b_list.pop(0)  # 세비의 병사를 제거함
        else:
            s_list.pop(0)  # 세준이의 병사를 제거함

    # 결과 출력: 세준이가 이긴 경우 'S', 세비가 이긴 경우 'B', 둘 다 없는 경우 'C'
    if s_list:
        print('S')
    elif b_list:
        print('B')
    else:
        print('C')

 

코드 설명

  1. 입력받기: 테스트 케이스의 개수를 입력받고, 각 케이스마다 병사들의 힘을 리스트로 입력받습니다.
  2. 내림차순 정렬: 각 팀의 병사들을 내림차순으로 정렬해서 가장 강한 병사가 리스트 앞쪽에 오도록 합니다.
  3. 전투 진행: while 반복문을 사용해 두 팀의 병사들이 남아있을 동안 전투를 계속합니다. 각 라운드마다 가장 강한 병사들끼리 비교하여 상대방을 제거합니다.
  4. 승자 판별: 최종적으로 남은 병사가 있는 팀을 출력합니다. 세준이가 이기면 'S', 세비가 이기면 'B', 모두 없으면 'C'를 출력합니다.

예시를 통해 이해하기

입력 예시에서 세준이의 병사들은 [10, 7, 5]로 정렬되고, 세비의 병사들은 [9, 8, 6]으로 정렬됩니다. 가장 강한 병사들끼리 싸워서 이긴 팀의 병사가 남게 되고, 결국 세준이 팀의 병사들만 남기 때문에 'S'가 출력됩니다.

마무리

이렇게 세준이와 세비의 군대가 전투를 벌이는 시뮬레이션 문제를 해결해 보았습니다. 전투 시뮬레이션 문제를 통해 리스트의 정렬과 반복문을 활용해 문제를 해결하는 방법을 배울 수 있었어요. 각 전투마다 가장 강한 병사들끼리 비교하고, 하나씩 병사가 줄어들면서 최후의 승자를 가리는 방식으로 전투를 진행해요.

이번 포스팅이 도움이 되었길 바라며, 궁금한 점이나 이해가 안 되는 부분이 있다면 언제든지 댓글로 남겨주세요! 😊

TODAY TIL

안녕하세요! 오늘은 재미있는 숫자 조작 문제를 함께 풀어보겠습니다. 이 문제는 주어진 숫자에서 같은 홀수끼리, 또는 같은 짝수끼리만 자리를 교환하여 가장 큰 숫자를 만들어야 하는 도전 과제입니다. 누구나 쉽게 이해할 수 있도록 하나하나 단계별로 풀어보겠습니다.


문제 설명

입력: 양의 정수 num
목표: num의 각 자릿수를 같은 홀수 또는 짝수끼리만 교환하여 만들 수 있는 가장 큰 값을 반환합니다.

단, 홀수와 짝수는 서로 교환할 수 없습니다.

예시

  1. 입력: 1234
    출력: 3412
    설명:
    • 홀수(1, 3)를 교환하여 큰 값이 앞에 오도록 정렬합니다.
    • 짝수(2, 4)를 교환하여 큰 값이 앞에 오도록 정렬합니다.
  2. 입력: 65875
    출력: 87655
    설명:
    • 짝수(6, 8)를 교환하여 큰 값이 앞에 오도록 정렬합니다.
    • 홀수(5, 5, 7)를 교환하여 큰 값이 앞에 오도록 정렬합니다.

문제 해결 방법

  1. 숫자의 홀수와 짝수를 분리합니다.
  2. 각 그룹(홀수, 짝수)을 내림차순으로 정렬합니다.
  3. 원래 숫자의 각 자릿수를 확인하며, 해당 자릿수가 홀수이면 정렬된 홀수 리스트에서 값을 꺼내고, 짝수이면 짝수 리스트에서 값을 꺼냅니다.
  4. 최종적으로 만들어진 숫자를 반환합니다.

코드 구현

아래는 이 문제를 해결하는 Python 코드입니다. 간단한 주석을 추가하여 쉽게 이해할 수 있도록 했습니다.

def largestNumberAfterSwaps(num):
    # 1. 숫자를 문자열로 변환하고 홀수와 짝수 분리
    num_str = str(num)
    odds = [int(d) for d in num_str if int(d) % 2 != 0]  # 홀수 리스트
    evens = [int(d) for d in num_str if int(d) % 2 == 0]  # 짝수 리스트
    
    # 2. 각각 내림차순으로 정렬
    odds.sort(reverse=True)  # 큰 숫자가 앞에 오도록
    evens.sort(reverse=True)
    
    # 3. 원래 숫자의 자리 순서에 맞게 재배치
    result = []
    for digit in num_str:
        if int(digit) % 2 == 0:  # 짝수 자리라면
            result.append(evens.pop(0))  # 짝수 리스트에서 가장 큰 값 추가
        else:  # 홀수 자리라면
            result.append(odds.pop(0))  # 홀수 리스트에서 가장 큰 값 추가
    
    # 4. 리스트를 합쳐서 정수형으로 변환
    return int(''.join(map(str, result)))

# 테스트 예제
print(largestNumberAfterSwaps(1234))  # Output: 3412
print(largestNumberAfterSwaps(65875))  # Output: 87655

 

코드 설명 (누구나 쉽게 이해하기)

  1. 숫자를 문자로 변환하고 홀수와 짝수 분리
    숫자 num을 문자열로 변환합니다. 각 자릿수를 순회하며 홀수와 짝수를 분리합니다.
    예를 들어, num = 65875라면:
    • 홀수 리스트: [5, 5, 7]
    • 짝수 리스트: [6, 8]
  2. 정렬
    홀수와 짝수를 각각 내림차순으로 정렬합니다. 이렇게 하면 가장 큰 숫자가 앞으로 옵니다.
    예를 들어:
    • 정렬된 홀수 리스트: [7, 5, 5]
    • 정렬된 짝수 리스트: [8, 6]
  3. 재배치
    원래 숫자의 각 자릿수를 순회하며, 홀수 자리에는 정렬된 홀수 리스트의 첫 번째 값을 넣고, 짝수 자리에는 정렬된 짝수 리스트의 첫 번째 값을 넣습니다.
    • 원래 숫자: 65875
    • 재배치: [8, 7, 6, 5, 5]
  4. 최종 숫자로 변환
    재배치된 리스트를 문자열로 합친 뒤 정수형으로 변환하여 반환합니다.

예제 설명

입력: 1234

  1. 홀수: [1, 3], 짝수: [2, 4]
  2. 정렬 후: 홀수 [3, 1], 짝수 [4, 2]
  3. 자리 배치: [3, 4, 1, 2]
  4. 결과: 3412

입력: 65875

  1. 홀수: [5, 5, 7], 짝수: [6, 8]
  2. 정렬 후: 홀수 [7, 5, 5], 짝수 [8, 6]
  3. 자리 배치: [8, 7, 6, 5, 5]
  4. 결과: 87655

정리

이 문제는 자릿수의 홀짝성(Parity)을 기준으로 숫자를 정렬하고 재배치하는 간단하지만 재미있는 문제였습니다.
Python의 리스트 처리와 정렬 기능을 활용하면 직관적으로 풀 수 있습니다. 이 코드는 실전 코딩 테스트에서도 활용도가 높으니 꼭 연습해 보세요!

오늘도 코딩 재미있게 하세요! 😊

 

TODAY TIL

파이썬으로 점수 순위 매기기 - 쉬운 풀이 가이드

안녕하세요, 이번 블로그 포스트에서는 파이썬을 이용해 점수 배열을 받아 선수들의 순위를 매기는 문제를 해결해보려고 합니다. 점수에 따라 메달을 부여하고 순위를 매기는 알고리즘 문제를 쉽게 이해할 수 있도록 차근차근 설명드릴게요. 이 포스트를 통해 여러분이 코드 작성 과정을 이해하고, 직접 문제를 풀어볼 수 있도록 돕겠습니다!

문제 설명

우리는 각 선수의 점수가 담긴 배열을 받습니다. 이 배열에는 각 선수의 점수가 고유하게 담겨 있으며, 높은 점수가 높은 순위를 의미합니다. 각 선수는 다음과 같은 순위에 따라 메달 또는 순위 번호를 부여받습니다.

  • 1등: "Gold Medal"
  • 2등: "Silver Medal"
  • 3등: "Bronze Medal"
  • 4등 이후: 해당 순위 숫자

예를 들어, 입력 배열이 [10, 3, 8, 9, 4]이라면 결과는 ['Gold Medal', '5', 'Bronze Medal', 'Silver Medal', '4']가 되어야 합니다.

해결 방법

이 문제를 해결하기 위해 다음과 같은 단계를 거칠 것입니다.

  1. 점수 배열과 인덱스 묶기: 각 점수와 인덱스를 묶어 리스트로 만듭니다. 이렇게 하면 점수를 정렬한 후에도 각 점수가 원래 어디에 있었는지 알 수 있습니다.
  2. 점수 정렬하기: 점수들을 높은 순서대로 정렬합니다. 정렬된 순서에서 1등, 2등, 3등을 각각 메달로 처리하고 나머지 순위를 숫자로 기록합니다.
  3. 결과 배열 생성: 원래 배열에 맞는 순위를 기록한 결과 배열을 반환합니다.

코드 구현

이제 파이썬 코드로 이 문제를 해결하는 방법을 알아보겠습니다. 코드가 이해하기 쉽게 클래스 형태로 작성되어 있습니다.

class Solution:
    def findRelativeRanks(self, score):
        # 점수 배열과 각 인덱스를 묶어 (점수, 인덱스) 형태로 리스트 생성 후 내림차순 정렬
        sorted_score = sorted(enumerate(score), key=lambda x: x[1], reverse=True)

        # 결과 배열 초기화
        ranks = [""] * len(score)

        # 순위에 따라 메달 혹은 순위 번호를 할당
        for i, (idx, value) in enumerate(sorted_score):
            if i == 0:
                ranks[idx] = "Gold Medal"
            elif i == 1:
                ranks[idx] = "Silver Medal"
            elif i == 2:
                ranks[idx] = "Bronze Medal"
            else:
                ranks[idx] = str(i + 1)

        return ranks

# 예제 입력 테스트
solution = Solution()
score1 = [5, 4, 3, 2, 1]
print(solution.findRelativeRanks(score1))  # 출력: ["Gold Medal", "Silver Medal", "Bronze Medal", "4", "5"]

score2 = [10, 3, 8, 9, 4]
print(solution.findRelativeRanks(score2))  # 출력: ["Gold Medal", "5", "Bronze Medal", "Silver Medal", "4"]

 

코드 설명

  • 점수 정렬하기: enumerate(score)를 사용해 점수와 인덱스를 함께 묶은 후, 점수를 기준으로 내림차순 정렬했습니다. 이렇게 하면 각 점수가 원래 어느 위치에 있었는지 알 수 있게 됩니다.
  • 결과 배열 생성: 정렬된 점수에 따라 순위를 매기고, 그에 맞는 메달 혹은 순위 숫자를 원래 인덱스 위치에 기록합니다.
  • 메달 할당: 1, 2, 3등에 해당하는 선수에게 각각 "Gold Medal", "Silver Medal", "Bronze Medal"을 부여하고, 나머지는 순위 숫자를 할당합니다.

예제 테스트

  • 입력: [5, 4, 3, 2, 1]
    • 출력: ["Gold Medal", "Silver Medal", "Bronze Medal", "4", "5"]
  • 입력: [10, 3, 8, 9, 4]
    • 출력: ["Gold Medal", "5", "Bronze Medal", "Silver Medal", "4"]

마무리

이렇게 해서 점수 배열을 받아 선수들의 순위를 메달 및 숫자로 표현하는 방법을 알아보았습니다. 간단한 정렬과 반복문을 이용해 문제를 해결할 수 있었죠. 이 문제는 파이썬의 정렬 기능과 인덱스 활용을 배울 수 있는 좋은 예제입니다.

여러분도 비슷한 문제를 풀 때 이런 방식으로 접근해 보세요! 질문이나 궁금한 점이 있으면 언제든지 댓글로 남겨주세요.

+ Recent posts