TODAY TIL

 안녕하세요!  오늘은 이 큐를 이용해서 여러 가지 명령어를 처리하는 프로그램을 파이썬으로 구현해볼 거예요!

 

큐(Queue)란?

큐(Queue)는 FIFO(First In, First Out) 구조를 가진 자료 구조에요. 줄을 서서 차례로 서비스를 받는 것처럼, 먼저 들어온 데이터가 먼저 나가는 구조를 가지고 있어요. 반대로 **스택(Stack)**은 LIFO(Last In, First Out) 구조를 가지는데, 나중에 들어온 것이 먼저 나가는 구조를 가지고 있어요.

 

오늘 우리가 구현할 프로그램은 정수를 저장하는 큐에 여러 가지 명령어를 처리하는 프로그램이에요. 여기서 사용될 명령어는 다음과 같아요:

  1. push X: 정수 X를 큐에 넣습니다. 즉, 줄의 끝에 새로운 사람이 들어오는 것과 같아요.
  2. pop: 큐의 가장 앞에 있는 값을 꺼내서 출력해요. 줄의 맨 앞에 있는 사람이 나가는 것과 같은 일이에요. 만약 줄에 아무도 없으면 -1을 출력해요.
  3. size: 현재 큐에 몇 명이 있는지를 출력해요.
  4. empty: 큐가 비어 있으면 1을, 비어 있지 않으면 0을 출력해요.
  5. front: 큐의 가장 앞에 있는 값을 출력해요. 아무도 없으면 -1을 출력해요.
  6. back: 큐의 가장 뒤에 있는 값을 출력해요. 아무도 없으면 -1을 출력해요.

파이썬 코드로 큐 구현하기

아래 코드는 deque를 사용해서 큐를 쉽게 구현한 거예요. deque는 양쪽 끝에서 데이터를 넣고 빼는 데 최적화된 자료구조로, 파이썬의 collections 모듈에서 제공해요.

 

from collections import deque
import sys

input = sys.stdin.read

def queue_operations(commands):
    queue = deque()
    result = []
    for command in commands:
        if "push" in command:
            value = command.split()[1]
            queue.append(value)
        elif command == "pop":
            result.append(queue.popleft() if queue else -1)
        elif command == "size":
            result.append(len(queue))
        elif command == "empty":
            result.append(0 if queue else 1)
        elif command == "front":
            result.append(queue[0] if queue else -1)
        elif command == "back":
            result.append(queue[-1] if queue else -1)
    return result

def main():
    data = input().splitlines()
    commands = data[1:]
    results = queue_operations(commands)
    sys.stdout.write("\n".join(map(str, results)) + "\n")

if __name__ == "__main__":
    main()

 

코드 설명

  1. deque를 사용해 큐 만들기: queue = deque()로 큐를 만들었어요. 이제 queue.append()로 값을 추가하고, queue.popleft()로 값을 꺼낼 수 있어요.
  2. 명령어 처리하기:
    • push X: 큐의 끝에 값을 추가해요.
    • pop: 큐의 앞에 있는 값을 꺼내고, 큐가 비어있다면 -1을 저장해요.
    • size: 현재 큐의 크기를 저장해요.
    • empty: 큐가 비어 있으면 1, 비어 있지 않으면 0을 저장해요.
    • front: 큐의 가장 앞에 있는 값을 저장하고, 큐가 비어있다면 -1을 저장해요.
    • back: 큐의 가장 뒤에 있는 값을 저장하고, 큐가 비어있다면 -1을 저장해요.
  3. 결과 출력하기: 각 명령어의 결과를 리스트에 모아서 마지막에 한 번에 출력해요.

큐의 활용

큐는 여러 가지 상황에서 활용될 수 있어요. 예를 들어, 프린터의 출력 작업을 처리할 때, 먼저 요청된 작업부터 처리하는 데 큐가 사용돼요. 또 너비 우선 탐색(BFS) 같은 알고리즘에서도 큐가 중요한 역할을 해요.

이제 여러분도 큐의 개념과 구현 방법을 잘 이해할 수 있겠죠? 줄을 서는 것처럼 먼저 들어간 것이 먼저 나오는 이 간단한 개념을 파이썬으로 구현해보세요!

마무리

이 글에서는 큐라는 자료구조를 이해하고, 파이썬으로 직접 구현해 보았어요. 큐의 간단한 개념을 다양한 상황에 적용할 수 있으니, 여러 문제를 풀어보면서 직접 사용해 보세요. 이해하기 어려운 부분이나 더 궁금한 점이 있다면 언제든지 댓글로 남겨주세요!

TODAY TIL

 안녕하세요! 오늘은 주어진 여러 개의 테스트 케이스에서 단어들을 반대 순서로 출력하는 Python 코드를 다루어 보겠습니다. 이 문제는 간단한 문자열 처리 문제로, 입출력 포맷에 유의하며 해결하는 방법을 배워보겠습니다.

 

문제 설명

주어진 입력은 N개의 케이스로 구성되어 있습니다. 각 케이스에는 스페이스로 구분된 여러 단어가 있으며, 이를 반대 순서로 출력하는 것이 목표입니다. 각 케이스의 결과는 특정 출력 형식에 맞춰야 합니다.

  • 입력 조건:
    • 첫 줄에는 케이스의 개수 NN이 주어집니다.
    • 각 케이스는 한 줄에 하나씩 입력되며, 단어들은 공백으로 구분됩니다. 라인의 처음과 끝에는 공백이 없습니다.
    • NN과 각 문장의 길이 LL은 1 ≤ LL ≤ 25를 만족합니다.
  • 출력 조건:
    • 각 케이스에 대해 "Case #x: " 형식으로 번호를 출력한 후, 반대 순서로 단어를 출력합니다.

예제 코드

이제 이 문제를 해결하는 Python 코드를 살펴보겠습니다.

# 첫 번째 줄에서 전체 케이스의 개수 N을 입력받는다.
N = int(input())

# 각 케이스를 반복하며 처리한다.
for i in range(1, N + 1):
    # 각 케이스에 대한 단어 입력을 받는다.
    sentence = input().strip()  # strip()을 사용해 앞뒤 공백 제거
    
    # 입력받은 문장을 단어 단위로 분할
    words = sentence.split()
    
    # 단어 리스트를 뒤집는다.
    reversed_words = words[::-1]
    
    # 'Case #x: ' 형식으로 결과를 출력
    print(f"Case #{i}: {' '.join(reversed_words)}")

 

실행 예제

다음은 입력과 출력 예제입니다.

입력:

5
Hello World
Programming is fun
Python is powerful
Reverse these words
Learning is continuous

 

출력:

Case #1: World Hello
Case #2: fun is Programming
Case #3: powerful is Python
Case #4: words these Reverse
Case #5: continuous is Learning

 

코드 설명

  1. input() 함수로 NN을 입력받아 테스트 케이스의 수를 가져옵니다.
  2. strip() 메서드로 각 줄의 앞뒤 공백을 제거하고, split()으로 단어를 리스트로 만듭니다.
  3. 리스트 슬라이싱 [::-1]을 사용하여 단어의 순서를 뒤집습니다.
  4. ' '.join()으로 뒤집힌 단어 리스트를 다시 문자열로 합쳐서 출력 포맷에 맞춰 출력합니다.

마무리

이 코드는 주어진 문제를 해결하는 데 필요한 기본적인 문자열 처리 기법을 포함하고 있습니다. 입출력 포맷과 리스트 조작법을 연습할 수 있는 좋은 예제입니다.

이 코드를 여러분의 Python 학습에 도움이 되기를 바랍니다!

 

TODAY TIL

안녕하세요! 오늘은 코딩 테스트에서 자주 나오는 스택(Stack) 구현 문제를 함께 풀어보겠습니다. 이 문제는 입력으로 주어지는 명령어들을 스택을 통해 처리하는 프로그램을 작성하는 것입니다. 명령어의 종류와 해결 방법을 차근차근 적어보려고 합니다.

 

문제 설명

우리는 다음과 같은 명령어를 처리할 수 있는 스택을 구현해야 합니다:

  • push X: 정수 X를 스택에 넣습니다.
  • pop: 스택에서 가장 위에 있는 정수를 빼고 출력합니다. 스택이 비어 있으면 -1을 출력합니다.
  • size: 스택에 들어있는 정수의 개수를 출력합니다.
  • empty: 스택이 비어 있으면 1, 아니면 0을 출력합니다.
  • top: 스택의 가장 위에 있는 정수를 출력합니다. 스택이 비어 있으면 -1을 출력합니다.

코드 구현

먼저, Python의 sys.stdin.readline()을 사용해 입력을 빠르게 처리하고 각 명령어를 효율적으로 처리하는 코드를 작성하겠습니다.

 

import sys
input = sys.stdin.readline

# 스택 초기화
stack = []

# 명령 수 입력
N = int(input().strip())

# 명령 처리
for _ in range(N):
    command = input().strip()
    
    if command[:4] == "push":
        # push X 처리
        stack.append(int(command.split()[1]))
    elif command == "pop":
        print(stack.pop() if stack else -1)
    elif command == "size":
        print(len(stack))
    elif command == "empty":
        print(1 if not stack else 0)
    elif command == "top":
        print(stack[-1] if stack else -1)

 

코드 설명

  • import sys: Python의 기본 입력 함수 input()은 느릴 수 있기 때문에 sys.stdin.readline()을 사용하여 입력 속도를 최적화했습니다.
  • 스택 구현: Python의 리스트를 사용해 스택을 구현합니다. append()로 push 연산을, pop()으로 pop 연산을 쉽게 처리할 수 있습니다.
  • 명령어 처리: 명령어는 if-elif 조건문으로 처리하며, 명령어가 push로 시작하는지 command[:4] == "push"로 확인해 split()으로 숫자를 추출합니다.
  • 출력 처리:
    • pop: 스택이 비어 있으면 -1을 출력하고, 아니면 마지막 요소를 제거하고 출력합니다.
    • size: len(stack)을 출력합니다.
    • empty: 스택이 비어 있으면 1, 아니면 0을 출력합니다.
    • top: 스택의 마지막 요소를 출력하되, 비어 있으면 -1을 출력합니다.

마무리

이제 이 코드를 통해 코딩 테스트에서 자주 나오는 스택 문제를 해결할 수 있습니다. 입력을 빠르게 처리하고 명령어를 간단하게 구현하여 시간 초과를 방지할 수 있습니다.

이 글이 도움이 되었다면 블로그 구독과 댓글도 부탁드려요! 앞으로도 더 많은 코딩 팁과 문제 풀이를 공유할 예정입니다. 😊

 

TODAY TIL

안녕하세요! 오늘은 마라톤에 참여한 선수 중 단 한 명의 완주하지 못한 선수를 찾는 문제를 해결하는 방법을 다뤄보겠습니다. 이 문제는 코딩 테스트에서 자주 나오는 유형으로, 배열과 정렬을 다루는 좋은 연습이 됩니다.

 

문제 설명

수많은 마라톤 선수들이 마라톤에 참여했는데, 단 한 명의 선수를 제외하고는 모두 완주했습니다. 마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어졌을 때, 완주하지 못한 선수의 이름을 반환하는 함수를 작성하세요.

제한사항

  • 마라톤에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.
  • completion 배열의 길이는 participant의 길이보다 1 작습니다.
  • 참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
  • 참가자 중에는 동명이인이 있을 수 있습니다.

문제 해결 방법

이 문제를 효율적으로 풀기 위해 정렬을 사용한 방법을 설명하겠습니다.

해결 방법 순서

  1. participant와 completion 배열을 정렬합니다.
  2. 정렬된 상태에서 두 배열을 처음부터 비교하면서 일치하지 않는 요소를 찾습니다.
  3. 만약 모든 요소가 일치하면 participant 배열의 마지막 요소가 완주하지 못한 선수입니다.

 

코드 구현

def solution(participant, completion):
    participant.sort()  # 참가자 배열 정렬
    completion.sort()   # 완주자 배열 정렬
    
    # 정렬된 배열에서 비교
    for i in range(len(completion)):
        if participant[i] != completion[i]:
            return participant[i]
    
    # 마지막 참가자가 완주하지 못한 경우
    return participant[-1]

 

예제 테스트

예제 #1:

print(solution(["leo", "kiki", "eden"], ["eden", "kiki"]))  # 결과: "leo"

 

예제 #2

print(solution(["marina", "josipa", "nikola", "vinko", "filipa"], ["josipa", "filipa", "marina", "nikola"]))  # 결과: "vinko"

 

예제 #3:

print(solution(["mislav", "stanko", "mislav", "ana"], ["stanko", "ana", "mislav"]))  # 결과: "mislav"

 

코드 설명

  • participant와 completion 배열을 정렬하여 순서를 맞춥니다.
  • 두 배열을 비교하며 첫 번째로 다른 이름을 반환합니다.
  • 만약 모든 이름이 일치하면 participant 배열의 마지막 이름을 반환합니다. 이는 정렬된 completion 배열의 마지막 요소와 비교했을 때, 남는 한 명이기 때문입니다.

시간 복잡도

이 솔루션은 정렬에 의해 O(nlog⁡n)O(n \log n)의 시간 복잡도를 가집니다. nn은 participant 배열의 길이입니다.

마무리

이 방법은 배열 정렬과 비교를 사용하여 효율적이고 직관적인 솔루션을 제공합니다. 동명이인이 있어도 정확히 동작하도록 설계되었습니다.

TODAY TIL

안녕하세요! 이번 포스팅에서는 폰켓몬 선택과 관련된 흥미로운 코딩 문제를 다뤄보겠습니다. 단계적으로 설명하고 코드 구현을 공유합니다.

 

문제 설명

여러분은 오랜 여행 끝에 홍 박사님의 연구실에 도착했습니다. 홍 박사님은 여러분에게 연구실에 있는 N마리의 폰켓몬 중 N/2마리를 선택해도 좋다고 했습니다. 같은 종류의 폰켓몬은 같은 번호를 가지며, 여러분은 최대한 다양한 종류의 폰켓몬을 선택하고 싶습니다.

문제의 목표: N마리의 폰켓몬 중 최대 N/2마리를 선택할 때, 가장 다양한 종류의 폰켓몬을 선택하는 경우를 찾고, 그때의 폰켓몬 종류의 수를 반환하는 것입니다.

제한사항

  • nums는 폰켓몬의 종류 번호가 담긴 1차원 배열입니다.
  • N은 항상 짝수이며, 1 이상 10,000 이하의 자연수입니다.
  • 폰켓몬의 종류 번호는 1 이상 200,000 이하의 자연수입니다.

단계별 해결 방법

  1. 입력 분석:
    • nums 배열에는 각 폰켓몬의 종류 번호가 포함되어 있습니다.
    • 배열의 길이 N은 항상 짝수입니다. 따라서 N/2마리의 폰켓몬을 선택할 수 있습니다.
  2. 중복 제거:
    • set 자료형을 사용하여 배열에서 중복을 제거하고 고유한 폰켓몬 종류의 수를 구합니다.
  3. 최대 선택 가능한 폰켓몬 수 계산:
    • 선택할 수 있는 최대 종류의 개수는 min(len(unique_pokemon), N // 2)입니다.
      • len(unique_pokemon)은 중복 제거 후 고유한 종류의 개수입니다.
      • N // 2는 선택할 수 있는 폰켓몬의 총 수입니다.
  4. 코드 구현
def solution(nums):
    # 중복 제거 후 고유한 폰켓몬 종류의 수 계산
    unique_pokemon = set(nums)
    
    # 선택할 수 있는 폰켓몬 종류의 최댓값 계산
    return min(len(unique_pokemon), len(nums) // 2)

 

코드 설명

  • set(nums)를 사용하여 nums 배열에서 중복된 종류 번호를 제거합니다.
  • min(len(unique_pokemon), len(nums) // 2)를 사용해 선택할 수 있는 폰켓몬 종류의 최대 개수를 계산합니다.
    • 고유한 폰켓몬 종류의 수(len(unique_pokemon))가 선택 가능한 수(N/2)보다 작으면 모든 고유 종류를 선택할 수 있습니다.
    • 고유한 폰켓몬 종류의 수가 N/2보다 크다면 N/2만큼의 고유 종류만 선택할 수 있습니다.

예제

입력: nums = [3, 1, 2, 3]

  1. set(nums) 결과: {1, 2, 3} (고유한 폰켓몬 종류: 3개)
  2. 선택할 수 있는 최대 개수: len(nums) // 2 = 2
  3. 반환값: min(3, 2) = 2

결과: 최대 2종류의 폰켓몬을 선택할 수 있습니다.

결론

이 문제는 배열에서 중복된 항목을 제거하고 선택할 수 있는 폰켓몬의 종류를 비교하는 간단한 문제였습니다. 중복 제거를 위한 set 사용과 최소값 계산을 통해 다양한 경우를 쉽게 처리할 수 있었습니다.

이제 여러분도 다양한 알고리즘 문제를 해결할 때 중복 제거와 최소값 계산을 활용해 보세요!

TODAY TIL

안녕하세요! 이번 포스팅에서는 비밀번호 찾기 문제 와 관련된 흥미로운 코딩 문제를 다뤄보겠습니다. 단계적으로 설명하고 코드 구현을 공유합니다.

 

문제 설명

창영이는 민균이의 컴퓨터에서 비밀번호가 포함된 텍스트 파일을 얻었습니다. 이 파일에는 여러 단어가 줄마다 적혀있으며, 민균이의 비밀번호는 특정 조건을 만족해야 합니다:

  1. 목록에 포함된 단어의 길이는 모두 홀수입니다.
  2. 비밀번호를 뒤집은 형태의 문자열도 목록에 포함되어 있습니다.

목표는 목록에서 비밀번호를 찾아 비밀번호의 길이와 가운데 글자를 출력하는 것입니다.

 

 

문제 해결을 위한 단계별 접근 방법

1단계: 입력받기

  • 첫째 줄에 단어의 개수 NN이 주어집니다.
  • 이후 NN개의 단어를 입력받아 words 리스트에 저장합니다.
# 입력 받기
N = int(input())
words = [input().strip() for _ in range(N)]

2단계: 단어와 뒤집은 단어 비교

  • 모든 단어에 대해 해당 단어의 뒤집힌 형태가 리스트에 있는지 확인합니다.
    • 예를 들어, 단어가 "tulipan"이라면, 뒤집은 형태는 "napilut"입니다.
  • 이를 위해 for 루프를 사용해 words 리스트의 각 단어를 순회하며 뒤집힌 단어가 words에 있는지 검사합니다.
# 비밀번호 찾기
password = ""
for word in words:
    reversed_word = word[::-1]  # 단어 뒤집기
    if reversed_word in words:  # 뒤집은 단어가 목록에 있는지 확인
        password = word
        break

 

3단계: 비밀번호 길이와 가운데 글자 찾기

  • 비밀번호를 찾았다면:
    • 길이는 len(password)로 구할 수 있습니다.
    • 가운데 글자는 (길이 // 2) 인덱스를 통해 찾습니다.
# 비밀번호 길이와 가운데 글자 찾기
length = len(password)
middle_char = password[length // 2]

 

4단계: 결과 출력

  • 비밀번호의 길이와 가운데 글자를 한 줄에 출력합니다.
# 결과 출력
print(length, middle_char)

 

전체 코드

아래는 전체 코드를 정리한 것입니다.

# 1. 입력 받기
N = int(input())
words = [input().strip() for _ in range(N)]

# 2. 비밀번호 찾기
password = ""
for word in words:
    reversed_word = word[::-1]
    if reversed_word in words:
        password = word
        break

# 3. 비밀번호 길이와 가운데 글자 찾기
length = len(password)
middle_char = password[length // 2]

# 4. 결과 출력
print(length, middle_char)

 

예제와 결과

예제 입력

4
tulipan
napilut
apple
banana

 

예제 출력

7 i

요약

이 문제는 문자열을 뒤집어 비교하는 방법과 문자열의 가운데 글자를 찾는 기본적인 접근 방식을 통해 해결할 수 있습니다. 단계별로 문제를 나누고 각 단계에서 필요한 작업을 순차적으로 구현하면 쉽게 답을 구할 수 있습니다.

TODAY TIL

안녕하세요! 이번 포스팅에서는 군대 근무 시간 공평성 확인 문제와 관련된 흥미로운 코딩 문제를 다뤄보겠습니다. 단계적으로 설명하고 코드 구현을 공유합니다.

 

군대 근무 시간 공평성 확인 문제 풀이 (단계별 접근법)

문제 개요

푸앙이와 동기들은 군대에서 4교대 근무를 합니다. 각 시간대(08:00 :12:00, 12:00 : 18:00, 18:00 :22:00, 22:00 :08:00)별로 근무 시간이 다르고, 각자의 근무 시간이 최대한 공평하게 배분되기를 원합니다. 주어진 근무표가 공평하게 분배되었는지, 즉 각 근무자의 총 근무 시간 차이가 12시간 이하인지 판단하는 프로그램을 작성해보겠습니다.

 

단계별 문제 해결 과정

1단계: 문제 이해하기

  • 주어진 정보
    • 주 수(N)가 주어지고, 각 주마다 4개의 근무 시간이 제공됩니다.
    • 시간대는 각각 4시간, 6시간, 4시간, 10시간으로 구성됩니다.
    • 근무표에서 -는 근무자가 없는 것을 의미하고, 근무자가 여러 명일 경우 공백으로 구분됩니다.
  • 목표
    • 근무표에서 모든 근무자의 총 근무 시간을 계산하여, 최대 근무 시간과 최소 근무 시간의 차이가 12시간 이하인지 확인합니다.
    • 근무자가 없는 경우는 공평한 것으로 간주합니다.

2단계: 계획 세우기

  1. 입력 처리: 주의 개수 N을 입력받고, 각 주별로 4줄씩 근무표를 읽어옵니다.
  2. 근무 시간 계산하기: 각 시간대의 근무자를 확인하여 근무 시간을 누적합니다. 각 시간대에 따라 4, 6, 4, 10시간을 해당 근무자에게 추가합니다.
  3. 공평성 검사: 모든 근무자의 근무 시간을 비교하여 차이가 12시간 이하인지 확인하고, 결과를 출력합니다.

 

3단계: 코드 작성 (단계별로 해결)

각 단계를 코드로 작성하면서 이해해보겠습니다

 

# 1. 입력 처리
N = int(input())  # 주의 개수 입력받기
schedule = [input().strip() for _ in range(N * 4)]  # 전체 근무표 입력받기

 

설명: N은 주의 개수이고, 근무표는 N * 4 줄로 주어집니다. schedule 리스트에 각 줄을 저장합니다.

 

# 2. 근무 시간 정의
hours = [4, 6, 4, 10]  # 각 시간대의 근무 시간 (08:00~12:00, 12:00~18:00, 18:00~22:00, 22:00~08:00)
work_time = {}  # 각 사람의 총 근무 시간을 저장할 딕셔너리
  • 설명: 각 시간대별 근무 시간을 리스트에 저장하여 반복문에서 참조하기 쉽게 합니다.
  • 딕셔너리 생성: work_time은 각 근무자의 이름을 키로 하고 근무 시간을 값으로 저장합니다.
# 3. 근무 시간 누적 계산
for i in range(N):  # 매 주마다 4개의 시간대가 있음
    for j in range(4):  # 각 시간대별로 근무자 확인
        people = schedule[i * 4 + j].split()  # 각 시간대별 근무자를 공백으로 분리
        for person in people:
            if person != '-':  # 근무자가 있는 경우만 처리
                if person not in work_time:
                    work_time[person] = 0
                work_time[person] += hours[j]  # 해당 시간대의 근무 시간을 더해줌

 

설명: i와 j를 이용해 각 주의 근무표에서 4개의 시간대를 차례로 가져오고, split()으로 각 시간대별 근무자를 분리합니다. -이 아닌 근무자에게만 시간을 누적합니다.

 

# 4. 공평성 검사
if work_time:  # 근무자가 있는 경우
    max_hours = max(work_time.values())
    min_hours = min(work_time.values())
    print("Yes" if max_hours - min_hours <= 12 else "No")
else:  # 근무자가 없는 경우
    print("Yes")

 

 

  • 설명: 모든 근무자의 근무 시간을 비교하여 차이가 12시간 이하인 경우 “Yes”, 그렇지 않으면 “No”를 출력합니다.
  • 예외 처리: 근무자가 없다면 바로 "Yes"를 출력합니다.

코드 전체

위의 각 단계를 하나의 코드로 합치면 다음과 같습니다.

 

# 입력 처리
N = int(input())  # 주의 개수
schedule = [input().strip() for _ in range(N * 4)]  # 전체 근무표 입력받기

# 각 시간대에 해당하는 근무 시간 정의
hours = [4, 6, 4, 10]  # 08:00~12:00, 12:00~18:00, 18:00~22:00, 22:00~08:00
work_time = {}  # 각 사람의 총 근무 시간을 저장할 딕셔너리

# 근무 시간 계산
for i in range(N):  # 매 주마다 4개의 시간대가 있음
    for j in range(4):  # 각 시간대별로 근무자 확인
        people = schedule[i * 4 + j].split()  # 각 시간대별 근무자를 분리
        for person in people:
            if person != '-':  # 근무자가 있는 경우만
                if person not in work_time:
                    work_time[person] = 0
                work_time[person] += hours[j]  # 해당 시간대의 근무 시간을 추가

# 공평성 검사
if work_time:  # 근무자가 있는 경우
    max_hours = max(work_time.values())
    min_hours = min(work_time.values())
    print("Yes" if max_hours - min_hours <= 12 else "No")
else:  # 근무자가 없는 경우
    print("Yes")

 

 

결론

이 문제를 통해 단계별로 문제를 나누어 풀어보았습니다. 입력을 먼저 처리한 후, 근무 시간을 누적 계산하고 공평성을 검사하는 방식으로 해결했습니다. 각 단계마다 목표를 명확히 설정하고 코드를 작성해 가면 더욱 이해하기 쉬울 것입니다.

 

TODAY TIL

 

안녕하세요! 이번 포스팅에서는 전주 듣고 노래 맞히기」 프로그램 와 관련된 흥미로운 코딩 문제를 다뤄보겠습니다. 첫 세 음만으로 노래 제목을 맞히는 프로그램을 단계적으로 설명하고 코드 구현을 공유합니다.

 

 

문제 설명

정환이 알고 있는 노래는 총 NN개이고, 각각의 노래는 제목과 일곱 개의 음으로 이루어진 전주를 가지고 있습니다. 정환은 이 전주의 첫 세 음을 듣고 제목을 맞히려고 합니다.

요구사항

  1. 주어진 첫 세 음에 맞는 노래가 딱 하나 있다면 해당 제목을 출력합니다.
  2. 같은 첫 세 음으로 시작하는 노래가 여러 개면 ?를 출력합니다.
  3. 해당하는 노래가 전혀 없다면 !를 출력합니다.

입력 및 출력 형식

  • 첫 줄에는 정환이 알고 있는 노래의 개수 NN과 맞히기를 시도할 노래의 개수 MM이 주어집니다.
  • 다음으로, NN개의 노래 정보가 각각 제목과 전주의 일곱 개 음으로 주어집니다.
  • 그 뒤에 맞히기를 시도할 첫 세 음이 MM개 주어집니다.

출력 형식: 각 시도에 대해 노래 제목, ?, 또는 ! 중 하나를 한 줄에 출력합니다.

 

해결 방법

이 문제는 특정 패턴(첫 세 음)을 기준으로 노래 제목을 빠르게 찾는 문제입니다. 노래 정보를 사전에 딕셔너리에 저장해 두고, 맞히기 시도마다 해당 패턴이 있는지 빠르게 탐색하도록 합니다.

  1. 아이디어 정리
    • 딕셔너리 자료 구조를 사용하여 각 노래의 첫 세 음을 키로 설정하고, 제목을 값으로 저장합니다.
    • 맞히기 시도 시, 입력된 첫 세 음으로 시작하는 노래를 딕셔너리에서 조회해 결과를 도출합니다.
    • 만약 해당 첫 세 음으로 시작하는 제목이 여러 개라면 ?, 하나라면 제목, 없으면 !를 출력합니다.
  2. 코드 구현 단계
    • 노래 데이터 저장: 노래 정보를 입력받아 딕셔너리에 첫 세 음을 키로 하고, 제목을 리스트로 저장합니다. 리스트에 저장함으로써 다중 매칭이 가능하도록 합니다.
    • 맞히기 시도 처리: 맞히기 시도 시 딕셔너리를 조회하여 조건에 맞는 결과를 출력합니다.
# 1. 입력 받기
N, M = map(int, input().split())

# 2. 노래 정보를 저장할 딕셔너리 생성
song_dict = {}

# 3. 각 노래 정보를 입력 받아 첫 세 음을 키로 노래 제목을 딕셔너리에 저장
for _ in range(N):
    data = input().split()
    title = data[1]
    melody = ''.join(data[2:5])  # 첫 세 음만 추출
    
    if melody in song_dict:
        song_dict[melody].append(title)
    else:
        song_dict[melody] = [title]

# 4. 맞히기 시도 처리
for _ in range(M):
    guess_melody = ''.join(input().split())
    
    if guess_melody in song_dict:
        titles = song_dict[guess_melody]
        if len(titles) == 1:
            print(titles[0])  # 유일하게 일치하는 제목
        else:
            print('?')  # 여러 개의 제목이 일치
    else:
        print('!')  # 일치하는 제목이 없음

 

코드 설명

  • 노래 정보 입력: 입력받은 각 노래 정보에서 첫 세 음만 추출해 딕셔너리에 저장합니다. 딕셔너리의 키는 첫 세 음, 값은 해당 제목의 리스트입니다.
  • 맞히기 시도 처리: 첫 세 음을 기반으로 딕셔너리를 조회하여 조건에 맞는 출력을 도출합니다.

이 코드와 설명을 통해 전주 듣고 노래 맞히기 프로그램을 성공적으로 구현할 수 있습니다.

TODAY TIL

안녕하세요! 이번 포스팅에서는 보드게임 할리갈리와 관련된 흥미로운 코딩 문제를 다뤄보겠습니다. 게임에서 한별이가 종을 쳐야 할 시점을 자동으로 판단하는 코드를 작성하는 방법을 단계별로 설명하겠습니다.

 

📋 문제 설명

할리갈리 게임은 과일이 그려진 카드들과 종으로 이루어져 있습니다. 카드를 차례로 펼쳐서 한 종류의 과일이 정확히 5개가 될 때 가장 먼저 종을 쳐야 하는 게임입니다. 만약 한 종류의 과일이 5개가 되는 순간을 놓치지 않고 종을 칠 수 있도록 도와주는 프로그램을 만들어봅시다!

 

입력 조건

  • 첫 번째 줄: 펼쳐진 카드의 개수 NN
  • 이후 각 줄에는 과일 종류 SS과일 개수 XX가 주어집니다.
  • 과일 종류는 STRAWBERRY, BANANA, LIME, PLUM 중 하나입니다.

출력 조건

  • 종을 쳐야 하면 "YES"를, 그렇지 않으면 "NO"를 출력합니다.

 

📝 문제 접근 방법

문제를 풀기 위해 각 과일의 개수를 누적한 후, 어떤 과일이 정확히 5개인지 확인하는 과정을 거칩니다.

  1. 입력 데이터 처리: 카드의 개수 NN과 카드별 과일 정보를 입력받습니다.
  2. 과일 개수 누적: 각 과일에 대한 개수를 누적하여 관리합니다.
  3. 종을 칠 조건 확인: 모든 카드의 정보를 누적한 후, 과일의 총 개수가 정확히 5인 과일이 있는지 확인합니다.

이제 코드로 문제를 해결해 보겠습니다.

# 입력 받기
N = int(input())  # 펼쳐진 카드 개수
fruit_counts = {"STRAWBERRY": 0, "BANANA": 0, "LIME": 0, "PLUM": 0}

# 카드 정보를 받아서 과일 수 누적
for _ in range(N):
    S, X = input().split()
    X = int(X)
    fruit_counts[S] += X

# 종을 칠 조건 확인
should_ring_bell = any(count == 5 for count in fruit_counts.values())

# 결과 출력
if should_ring_bell:
    print("YES")
else:
    print("NO")

 

코드 설명

  1. fruit_counts 딕셔너리를 통해 각 과일의 개수를 0으로 초기화합니다.
  2. 각 카드를 처리하면서 S와 X의 값을 읽고, fruit_counts의 해당 과일에 X를 더합니다.
  3. any(count == 5 for count in fruit_counts.values())로 과일이 정확히 5개가 된 경우를 확인합니다.
  4. 조건에 따라 "YES" 또는 "NO"를 출력합니다.

입력 예시

3
STRAWBERRY 2
BANANA 3
STRAWBERRY 3

 

출력 예시

YES

 

위 입력에서는 딸기가 총 5개(2 + 3)가 되므로, 한별이는 종을 쳐야 합니다.

 

🧩 마무리

이번 포스팅에서는 할리갈리 게임에서 종을 쳐야 하는 시점을 자동으로 판별하는 코드를 구현해 보았습니다. 과일 개수를 누적하면서 조건을 확인하는 문제를 통해 딕셔너리와 반복문의 활용을 연습할 수 있었습니다. 앞으로도 다양한 게임과 관련된 문제로 알고리즘을 즐겁게 풀어보아요!

 

TODAY TIL

오늘은 모스 부호를 원래의 문자로 해독하는 프로그램을 만들어 보겠습니다. 모스 부호는 짧은 신호와 긴 신호(‘.’, ‘-’)로 이루어져 있으며, 각 문자와 숫자를 모스 부호로 나타낼 수 있습니다. 예를 들어, ‘A’는 .-로, 숫자 ‘1’은 .----로 표기됩니다.

이 문제를 해결하기 위해 단계별로 접근해 보겠습니다.

문제 이해하기

  • 입력: 모스 부호로 변환한 메시지와 원래 문자열의 길이 NN이 주어집니다. 예를 들어, 모스 부호 .... . .-.. .-.. ---가 입력으로 주어지면 우리는 이것을 HELLO로 해독해야 합니다.
  • 출력: 주어진 모스 부호 메시지를 원래의 문자로 해독하여, 공백 없이 출력해야 합니다.

해결 순서

1단계: 모스 부호와 문자의 매핑 사전 만들기

모스 부호를 해독하기 위해서는 모스 부호와 알파벳(또는 숫자) 간의 변환이 필요합니다. 이를 위해 morse_code_dict라는 사전을 만들어 각 모스 부호와 해당되는 문자를 연결합니다.

morse_code_dict = {
    ".-": "A", "-...": "B", "-.-.": "C", "-..": "D", ".": "E",
    "..-.": "F", "--.": "G", "....": "H", "..": "I", ".---": "J",
    "-.-": "K", ".-..": "L", "--": "M", "-.": "N", "---": "O",
    ".--.": "P", "--.-": "Q", ".-.": "R", "...": "S", "-": "T",
    "..-": "U", "...-": "V", ".--": "W", "-..-": "X", "-.--": "Y",
    "--..": "Z", ".----": "1", "..---": "2", "...--": "3", "....-": "4",
    ".....": "5", "-....": "6", "--...": "7", "---..": "8", "----.": "9",
    "-----": "0", "--..--": ",", ".-.-.-": ".", "..--..": "?", "---...": ":",
    "-....-": "-", ".--.-.": "@"
}

 

2단계: 입력 받기

문제에서는 두 가지 입력이 주어집니다.

  • 첫 번째 줄은 변환할 원래 문자열의 길이인 NN (사용하지 않으므로 무시 가능)
  • 두 번째 줄은 모스 부호 메시지입니다.
N = int(input())  # 문자열의 길이 (사용하지 않음)
morse_code_message = input().split()  # 공백으로 구분된 모스 부호 메시지

 

split() 함수를 사용하여 모스 부호 메시지를 공백 기준으로 나누어 각 모스 부호가 리스트에 저장되도록 합니다.

3단계: 모스 부호 해독하기

모스 부호 메시지에 있는 각 모스 부호를 순서대로 morse_code_dict 사전을 통해 해독하여 원래의 문자로 변환합니다.

 

decoded_message = ""
for code in morse_code_message:
    decoded_message += morse_code_dict[code]  # 사전에서 해당 문자 찾기

 

이 과정에서는 for 반복문을 사용하여 각 모스 부호를 사전에서 찾아 decoded_message에 추가합니다.

4단계: 결과 출력

해독된 문자열 decoded_message를 출력합니다.

print(decoded_message)

 

전체 코드

아래는 위의 단계를 모두 포함한 전체 코드입니다

# 모스 부호와 문자 매핑 사전 만들기
morse_code_dict = {
    ".-": "A", "-...": "B", "-.-.": "C", "-..": "D", ".": "E",
    "..-.": "F", "--.": "G", "....": "H", "..": "I", ".---": "J",
    "-.-": "K", ".-..": "L", "--": "M", "-.": "N", "---": "O",
    ".--.": "P", "--.-": "Q", ".-.": "R", "...": "S", "-": "T",
    "..-": "U", "...-": "V", ".--": "W", "-..-": "X", "-.--": "Y",
    "--..": "Z", ".----": "1", "..---": "2", "...--": "3", "....-": "4",
    ".....": "5", "-....": "6", "--...": "7", "---..": "8", "----.": "9",
    "-----": "0", "--..--": ",", ".-.-.-": ".", "..--..": "?", "---...": ":",
    "-....-": "-", ".--.-.": "@"
}

# 입력 받기
N = int(input())  # 문자열의 길이 (사용하지 않음)
morse_code_message = input().split()  # 공백으로 구분된 모스 부호 메시지

# 모스 부호 해독
decoded_message = ""
for code in morse_code_message:
    decoded_message += morse_code_dict[code]  # 사전에서 변환

# 결과 출력
print(decoded_message)

 

마무리

이제 모스 부호 메시지를 해독하는 프로그램이 완성되었습니다! 각 단계를 순서대로 따라가며 코드를 작성하니 더 쉽게 이해할 수 있었을 거라 생각합니다. 앞으로도 다양한 문제를 해결하며 코딩 실력을 키워 나가길 응원합니다!

+ Recent posts