백전백계 문제 (100전으로 100마리 닭 구입)
한 마리의 수탉은 5전, 암탉은 3전, 병아리는 3마리에 1전이다. 총 100전을 사용해 정확히 100마리의 닭을 사야 할 때, 각각의 수탉, 암탉, 병아리 수를 구하는 문제다.
이 문제는 세 변수에 대한 방정식으로 표현할 수 있다:
- x + y + z = 100 (총 수)
- 5x + 3y + z/3 = 100 (총 비용)
여기서 x는 수탉, y는 암탉, z는 병아리 수다. 가능한 해는 유한하므로 완전 탐색이 가능하다. 하지만 반복 범위를 줄여 효율성을 높일 수 있다.
def solve_chickens():
solutions = []
for rooster in range(0, 21): # 최대 100 / 5 = 20
for hen in range(0, 34): # 최대 100 / 3 ≈ 33
chick = 100 - rooster - hen
if chick % 3 != 0 or chick < 0:
continue
total_cost = 5 * rooster + 3 * hen + chick // 3
if total_cost == 100:
solutions.append((rooster, hen, chick))
return solutions
result = solve_chickens()
for r, h, c in result:
print(f"수탉: {r}, 암탉: {h}, 병아리: {c}")
도서 대출 조합 문제
서로 다른 5권의 책을 A, B, C 세 명의 아이에게 한 명당 한 권씩 나눠줄 때 가능한 모든 배분 방법의 수를 구하는 문제다.
이 경우, 순서가 중요하며 중복이 허용되지 않는다. 즉, A가 책 1을 선택하면 B와 C는 그 책을 선택할 수 없다. 이는 순열 문제로 볼 수 있으며, 전체 경우의 수는 P(5,3) = 5×4×3 = 60가지다.
모든 가능한 조합을 출력하려면 다음과 같이 구현할 수 있다:
def distribute_books():
count = 0
books = [1, 2, 3, 4, 5]
for a_book in books:
for b_book in books:
if b_book == a_book:
continue
for c_book in books:
if c_book == a_book or c_book == b_book:
continue
print(f"A:{a_book}, B:{b_book}, C:{c_book}")
count += 1
print(f"총 조합 수: {count}")
distribute_books()
삼일 낚시 이틀 말리기 (주기성 판단 문제)
"삼일 낚시 이틀 말리기"란 속담처럼, 어떤 사람이 1990년 1월 1일부터 5일 주기로 3일은 낚시를 하고 2일은 그물 말리기를 한다고 가정하자. 특정 날짜에 그 사람이 낚시 중인지, 말리기 중인지를 판단하는 문제다.
풀이 전략:
- 기준일(1990-01-01)부터 입력일까지의 총 일수를 계산한다.
- 윤년 여부를 고려하여 월별 일수를 누적한다.
- 총 일수를 5로 나눈 나머지에 따라 상태를 결정한다: 나머지가 1, 2, 3이면 낚시, 4 또는 0이면 말리기.
def fishing_or_drying():
target_year = int(input("년도 입력: "))
target_month = int(input("월 입력: "))
target_day = int(input("일 입력: "))
if target_year < 1990:
print("기준일 이후의 날짜를 입력하세요.")
return
days_in_month = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
total_days = 0
# 1990년부터 전년도까지의 날짜 합산
for year in range(1990, target_year):
if is_leap(year):
total_days += 366
else:
total_days += 365
# 올해의 월별 일수 합산
for month in range(1, target_month):
total_days += days_in_month[month]
if month == 2 and is_leap(target_year):
total_days += 1
# 일 추가
total_days += target_day
# 상태 판별
remainder = total_days % 5
if remainder in [1, 2, 3]:
print("낚시 중")
else:
print("그물 말리기 중")
def is_leap(year):
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
fishing_or_drying()