밑바닥부터 시작하는 딥러닝5에 대해서 리뷰해보겠습니다. 이 책은 사이토 고키가 저술하고 개앞맵시님께서 번역한 딥러닝 입문서로, 딥러닝을 처음 접하는 분들에게 매우 유용한 자료입니다.

 책의 첫 장에서는 정규분포에 대한 이론을 다루고 있습니다. 정규분포는 통계학에서 매우 중요한 개념으로, 데이터 분석 및 머신러닝의 기초가 됩니다. 이 장에서는 정규분포의 수식과 확률분포에 대해 자세히 설명하고 있으며, 독자가 이해하기 쉽게 다양한 예시와 함께 설명하고 있습니다.

다음으로, 최대 가능도 추정에 대한 내용을 다룹니다. 최대 가능도 추정은 통계적 추정 방법 중 하나로, 주어진 데이터에 대해 가장 가능성이 높은 파라미터 값을 찾는 방법입니다. 이 책에서는 이론적인 설명뿐만 아니라, 실제 코드 예제를 통해 독자가 쉽게 따라할 수 있도록 구성되어 있습니다.

또한, 다변량 정규분포와 가우스 혼합모델에 대한 설명도 포함되어 있습니다. 다변량 정규분포는 여러 변수의 정규분포를 다루는 개념으로, 머신러닝에서 자주 사용됩니다. 가우스 혼합모델은 여러 개의 정규분포를 혼합하여 데이터를 모델링하는 방법으로, 클러스터링 문제를 해결하는 데 유용합니다. 이 두 개념은 머신러닝의 기초를 다지는 데 큰 도움이 됩니다.

이 책의 가장 큰 장점 중 하나는 실습 코드가 포함되어 있다는 점입니다. 파이토치, 사이파이, 넘파이와 같은 라이브러리를 활용한 코드가 제공되어 있어, 독자가 직접 코드를 실행해보며 학습할 수 있습니다. 이러한 실습은 이론을 이해하는 데 큰 도움이 되며, 실제로 딥러닝을 적용하는 데 필요한 기술을 익히는 데 유용합니다.

독자에게 추천하는 이유는 이 책이 단순히 이론적인 설명에 그치지 않고, 실습을 통해 직접 경험할 수 있도록 구성되어 있기 때문입니다. 딥러닝을 처음 접하는 분들이라면 이 책을 통해 기초부터 차근차근 배워나갈 수 있을 것입니다.

마무리하자면, 밑바닥부터 시작하는 딥러닝5는 딥러닝의 기초를 다지고 싶은 분들에게 강력히 추천하는 책입니다. 이 책을 통해 딥러닝의 세계에 한 발짝 더 다가갈 수 있을 것입니다 
그래서 딥러닝에 대해서 공부하시는 분들께 이 책을 진심으로 추천드립니다.

YES24 리뷰어클럽 서평단 자격으로 작성한 리뷰입니다.

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

파이썬으로 배우는 통계학교과서  (1) 2024.12.18
그로스 해킹 5장 ~6장  (0) 2024.11.24
그로스 해킹 3~4장  (0) 2024.11.18
그로스 해킹 1장 ~ 3장  (2) 2024.11.10

TODAY TIL

 

안녕하세요! 이번 블로그 포스팅에서는 학교 식당 줄 서기 문제를 해결하는 파이썬 코드와 문제 해결 과정을 공유해보려고 합니다. 이 문제는 많은 학생들이 식당에서 줄을 서고, 식사가 준비되는 과정을 처리하면서 최대 대기 인원을 기록하는 문제입니다. 특히, 입력의 개수가 많기 때문에 효율적인 구현이 필요합니다. 함께 문제를 이해하고 해결해봅시다!

문제 설명

학생들이 학교 식당에 도착하고, 식사가 준비되는 총 n개의 정보가 주어집니다. 이 정보는 두 가지 유형으로 이루어져 있습니다:

  1. 학생 도착 (유형 1 a): 학생 번호 a가 식당에 도착하여 줄을 섭니다.
  2. 식사 준비 (유형 2): 줄의 맨 앞 학생이 식사를 시작합니다.

식당에 도착한 학생은 줄의 맨 뒤에 서게 되며, 식사가 준비되면 줄의 맨 앞에 있는 학생이 식사를 하러 들어갑니다. 우리는 이 과정에서 줄에 서 있는 학생 수가 최대가 되었을 때, 그 순간 줄의 맨 뒤에 있는 학생 번호를 출력해야 합니다.

문제 해결 접근법

이 문제를 해결하기 위해 다음과 같은 접근 방식을 사용했습니다:

  • 큐(Queue) 자료구조를 활용해 학생들이 줄을 서고, 식사를 하러 들어가는 과정을 구현합니다. deque 모듈을 사용하면 큐의 양쪽에서 삽입과 삭제가 빠르게 이루어지므로 적합합니다.
  • 최대 대기 인원과 그 순간의 줄 맨 뒤 학생 번호를 추적하여 결과를 계산합니다.

코드 구현

아래는 문제를 해결하기 위한 파이썬 코드입니다:

from collections import deque
import sys

n = int(input())
queue = deque()
max_wait = 0
last_student = 100001

for _ in range(n):
    action = sys.stdin.readline().strip()
    if action[0] == '1':  # 학생 도착 (유형 1)
        _, student_number = action.split()
        student_number = int(student_number)
        queue.append(student_number)

        if len(queue) > max_wait:
            max_wait = len(queue)
            last_student = queue[-1]
        elif len(queue) == max_wait:
            if queue[-1] < last_student:
                last_student = queue[-1]

    elif action[0] == '2' and queue:  # 식사 준비 (유형 2)
        queue.popleft()

if max_wait == 0:
    last_student = -1

 

코드 설명

  1. 입력 처리 및 초기화
    • n은 총 명령어의 개수를 의미합니다.
    • queue는 학생들이 줄을 서는 대기열을 나타내며, deque()로 초기화됩니다.
    • max_wait는 대기 중인 최대 학생 수를 저장하며, last_student는 그때 줄의 맨 뒤에 있는 학생 번호를 기록합니다.
  2. 학생 도착 처리 (유형 1)
    • 학생 번호가 주어지면 해당 번호를 큐의 맨 뒤에 추가합니다.
    • 대기열 길이가 max_wait보다 크다면 이를 갱신하고, last_student를 현재 줄의 맨 뒤 학생 번호로 업데이트합니다.
    • 만약 대기열 길이가 max_wait와 같다면, 줄의 맨 뒤 학생 번호가 더 작은 경우로 갱신합니다.
  3. 식사 준비 처리 (유형 2)
    • 식사가 준비되면 큐의 맨 앞에 있는 학생을 제거합니다.
  4. 결과 계산
    • 만약 최대 대기 인원이 0이라면, 대기 중인 학생이 없다는 의미로 last_student-1로 설정합니다.

문제 해결의 어려움과 해결 방법

이 문제는 주어진 입력의 개수가 최대 100,000개일 수 있기 때문에 효율적인 입력 처리와 큐의 사용이 필수적입니다. sys.stdin.readline()을 사용하여 입력을 빠르게 처리하고, deque를 활용하여 큐 연산을 효율적으로 구현함으로써 런타임 에러를 피할 수 있었습니다.

마무리

이번 포스팅에서는 학생들이 식당에서 줄을 서는 문제를 해결하는 파이썬 코드를 다뤄보았습니다. 큐 자료구조를 사용해 효율적으로 줄 서기와 식사 과정을 처리하고, 최대 대기 인원과 그때의 학생 번호를 찾는 과정에서 발생할 수 있는 여러 가지 상황들을 고려했습니다. 이 코드가 여러분의 이해에 도움이 되었기를 바랍니다!

 

TODAY TIL

안녕하세요! 오늘은 게임 내에서 연계 기술의 발동 조건을 다루는 흥미로운 문제를 풀어볼 거예요. 임스가 플레이 중인 게임에서는 몇 가지 규칙에 따라 기술이 발동됩니다:

  • 연계 기술은 사전 기술과 본 기술의 조합입니다.
  • 사전 기술 없이 본 기술을 사용하면 기술이 비정상적으로 발동됩니다.
  • 사전 기술은 L, S, 본 기술은 R, K입니다.
  • 숫자 1부터 9까지의 기술은 언제나 단독으로 발동할 수 있습니다.

예를 들어, L을 사용한 후에 R을 사용하면 정상 발동되지만, R만 있으면 발동되지 않아요.

문제 해결 아이디어

이 문제를 해결하려면, 사전 기술이 사용되었는지 확인하면서 본 기술이 발동될 수 있는지를 검토하면 됩니다.

주요 아이디어

  • 사전 기술(L, S)이 나오면 리스트에 저장해두고, 본 기술(R, K)이 나올 때 이 리스트를 확인해 발동 여부를 결정합니다.
  • 숫자 기술(1~9)은 특별한 조건 없이 바로 발동할 수 있습니다.

코드 설명

# 기술의 개수 입력받기 (사용하지 않지만 문제의 형식에 맞추어 필요)
N = int(input())  

# 기술 순서를 문자열로 입력받고 리스트로 변환
skill = list(str(input()))

# 정상적으로 발동된 기술의 개수를 세는 변수
num = 0

# 사용된 사전 기술을 추적하는 리스트
used_list = []

# 기술을 하나씩 확인하며 발동 여부 판단
for i in skill:
    # 사전 기술 'L' 또는 'S'가 나오면 used_list에 추가
    if i == 'L' or i == 'S':
        used_list.append(i)
    
    # 본 기술 'K'가 나왔을 때
    elif i == 'K':
        # 사전 기술 'S'가 있다면 발동 가능
        if 'S' in used_list:
            used_list.remove('S')  # 사용한 'S'는 리스트에서 제거
            num += 1  # 발동된 기술 수 증가
        else:
            break  # 사전 기술 없으면 반복 종료 (스크립트 꼬임)
    
    # 본 기술 'R'이 나왔을 때
    elif i == 'R':
        # 사전 기술 'L'이 있다면 발동 가능
        if 'L' in used_list:
            used_list.remove('L')  # 사용한 'L'은 리스트에서 제거
            num += 1  # 발동된 기술 수 증가
        else:
            break  # 사전 기술 없으면 반복 종료 (스크립트 꼬임)
    
    # 숫자 기술 '1'~'9'는 조건 없이 발동 가능
    else:
        num += 1

# 최종 발동된 기술의 개수 출력
print(num)

설명

  • L이 나오면 사전 기술로 저장됩니다.
  • 1은 사전 기술이 필요 없는 숫자 기술이므로 바로 발동됩니다.
  • S가 나오면 사전 기술로 저장됩니다.
  • 2도 숫자 기술이라 바로 발동됩니다.
  • R이 나오면 L이 사전 기술로 사용되었으므로 발동됩니다.
  • K도 S가 사용된 상태이므로 발동됩니다.

발동된 기술은 총 4개입니다.

 

결론

이 문제는 리스트를 사용해 사전 기술의 사용 상태를 관리하면서 본 기술 발동 여부를 체크하는 방식으로 해결할 수 있었습니다. 코드의 각 부분을 이해하고, 예제를 실행해보며 학습하면 확실히 이해할 수 있을 거예요!

 

TODAY TIL

안녕하세요! 오늘은 n개의 숫자가 적힌 카드를 이용해 특정 규칙에 따라 카드를 처리하는 Python 코드에 대해 설명해드리겠습니다. 이 코드는 카드 게임의 시뮬레이션으로, 주어진 카드가 한 장 남을 때까지의 과정을 출력합니다.

 

문제 설명

사용자는 n개의 카드(숫자 1부터 n까지)를 갖고 있으며, 다음의 규칙을 반복해서 카드가 한 장 남을 때까지 진행합니다:

  1. 제일 위에 있는 카드를 버립니다.
  2. 그다음 제일 위에 있는 카드를 제일 아래로 옮깁니다.

코드 설명

n = int(input())
card = [i for i in range(1, n + 1)]
discard = []

while len(card) != 1:
    discard.append(card.pop(0)) # 제일 위에 있는 카드를 버린다.
    card.append(card.pop(0))    # 제일 위에 있는 카드를 제일 아래로 옮긴다.

for c in discard:
    print(c, end=' ')
print(card[0])

 

코드 단계별 분석

  1. 입력받기: n은 카드의 개수를 나타내며, 사용자가 입력합니다.
  2. 카드 리스트 생성: card는 1부터 n까지의 숫자가 순서대로 저장된 리스트입니다. 예를 들어, n=7일 경우 card = [1, 2, 3, 4, 5, 6, 7]입니다.
  3. 버려진 카드 리스트 초기화: discard는 게임 중 버려진 카드를 저장하기 위한 빈 리스트입니다.
  4. 메인 로직:
    • while len(card) != 1: 조건을 만족할 때까지 반복합니다.
    • discard.append(card.pop(0)): 카드의 맨 위에 있는 카드를 discard에 추가합니다.
    • card.append(card.pop(0)): 카드의 맨 위에 있는 카드를 제거하고, 이를 카드 리스트의 맨 아래로 보냅니다.
  5. 출력:
    • discard 리스트의 내용을 순서대로 출력합니다.
    • 마지막으로 남은 한 장의 카드를 출력합니다.

동작 예시

입력: n = 7

초기 상태:

  • card = [1, 2, 3, 4, 5, 6, 7]
  • discard = []

게임 과정:

  1. discard = [1], card = [3, 4, 5, 6, 7, 2]
  2. discard = [1, 3], card = [5, 6, 7, 2, 4]
  3. discard = [1, 3, 5], card = [7, 2, 4, 6]
  4. discard = [1, 3, 5, 7], card = [4, 6, 2]
  5. discard = [1, 3, 5, 7, 4], card = [2, 6]
  6. discard = [1, 3, 5, 7, 4, 2], card = [6]

출력:

1 3 5 7 4 2
6

 

결과 해석: 버려진 카드의 순서를 출력한 후, 마지막으로 남은 카드를 출력합니다.

이 코드의 핵심은 리스트의 pop(0) 메서드와 append() 메서드를 사용하여 카드의 순서를 처리하는 것입니다. 이를 통해 카드 게임의 규칙을 간단하게 구현할 수 있습니다.

결론

이 코드 예제는 Python의 리스트 메서드를 활용하여 간단한 카드 게임을 시뮬레이션하는 방법을 잘 보여줍니다. 다양한 카드 처리 문제에 응용할 수 있는 좋은 연습이 될 것입니다.

다음에도 재미있는 코드 설명으로 찾아오겠습니다. 읽어주셔서 감사합니다!

 

 

TODAY TIL

안녕하세요! 오늘은 배열에서 연속으로 나타나는 숫자를 제거하는 문제를 해결하는 방법을 소개하겠습니다. 이 문제는 배열 arr에 연속으로 나타나는 숫자가 있을 때, 중복된 숫자를 하나만 남기고 제거하여 반환하는 문제입니다. 문제 풀이를 단계별로 설명하겠습니다.

 

문제 설명

  • 배열 arr가 주어집니다.
  • 배열의 각 원소는 0부터 9까지의 숫자로 이루어져 있습니다.
  • 연속적으로 나타나는 숫자를 하나만 남기고 제거한 배열을 반환합니다.
  • 예를 들어:
    • arr = [1, 1, 3, 3, 0, 1, 1]이면 [1, 3, 0, 1]을 반환해야 합니다.
    • arr = [4, 4, 4, 3, 3]이면 [4, 3]을 반환해야 합니다.

제한사항

  • 배열 arr의 크기: 최대 1,000,000
  • 배열 arr의 원소: 0 이상 9 이하의 정수

 

문제 해결 접근법

1. 문제 이해 및 계획

  • 주어진 배열을 순회하면서 연속된 숫자가 중복인지 확인하고, 중복이 아니면 결과 배열에 추가합니다.
  • 각 숫자를 이전 숫자와 비교하여 중복 여부를 판단합니다.

2. 구현 단계

  • 빈 배열 result를 초기화하여 중복되지 않은 숫자를 저장합니다.
  • previous 변수로 이전 숫자를 저장합니다.
  • arr의 각 원소를 순회하며, previous와 비교해 다를 경우에만 result에 추가합니다.

3. 코드 구현

다음은 문제를 해결하는 Python 코드입니다:

 

def solution(arr):
    result = []  # 결과를 저장할 배열
    previous = None  # 이전 원소를 저장할 변수

    for num in arr:
        # 이전 원소와 다를 때만 결과 배열에 추가
        if num != previous:
            result.append(num)
            previous = num  # 현재 숫자를 이전 숫자로 갱신

    return result

# 테스트 케이스
print(solution([1, 1, 3, 3, 0, 1, 1]))  # 출력: [1, 3, 0, 1]
print(solution([4, 4, 4, 3, 3]))        # 출력: [4, 3]

 

4. 코드 설명

  • result 배열은 중복이 제거된 숫자들을 저장합니다.
  • previous 변수는 이전 숫자를 저장해 연속 중복을 판단합니다.
  • arr의 각 숫자를 순회하며 previous와 비교해 다르면 result에 추가하고, previous를 현재 숫자로 갱신합니다.

5. 시간 및 공간 복잡도

  • 시간 복잡도: O(n)O(n) — 배열을 한 번 순회하므로 매우 효율적입니다.
  • 공간 복잡도: O(n)O(n) — 중복이 제거된 결과 배열을 저장하기 때문입니다.

마무리

이 코드로 연속된 중복 숫자를 손쉽게 제거할 수 있습니다. 배열의 길이가 최대 1,000,000인 경우에도 효율적으로 동작합니다. 문제를 풀면서 알고리즘의 효율성과 Python의 기본 문법을 함께 이해할 수 있는 좋은 예제였습니다.

+ Recent posts