Adventure Time - Finn 3
본문 바로가기
코테연습/python

게임 이벤트 유저 분류

by hyun9_9 2026. 4. 19.

문제 설명

게임 회사에서 특별 이벤트를 진행한다. 이벤트 시작일을 기준으로 유저들의 접속 로그를 분석하여 각 유저를 4가지 유형으로 분류하고, 각 유형별 유저 수를 구하여라.


유저 유형 정의

유형 조건

복귀 유저 이벤트 시작일 기준 30일 초과 이전에 마지막으로 접속했다가, 이벤트 시작일 이후 다시 접속한 유저
기존 유저 이벤트 시작일 기준 30일 이내에 접속한 이력이 있고, 이벤트 시작일 이후에도 접속한 유저
신규 유저 이벤트 시작일 이전 접속 기록이 전혀 없고, 이벤트 시작일 이후에 처음 접속한 유저
미접속 유저 이벤트 시작일 이전 접속 기록만 있고, 이벤트 시작일 이후에는 한 번도 접속하지 않은 유저

입력 형식

logs: List[List[int]]  # [user_id, year, month, day] 형태의 접속 로그 목록 (날짜 오름차순 정렬)
date: List[int]        # [year, month, day] 형태의 이벤트 시작일

출력 형식

[comeback, existing, new, inactive]  # 복귀, 기존, 신규, 미접속 유저 수

제약 조건

  • 로그는 날짜 오름차순으로 정렬되어 있다.
  • 같은 유저가 같은 날 여러 번 접속할 수 있다.
  • 윤년은 고려하지 않는다. (2월은 항상 28일)
  • 1 ≤ logs의 길이 ≤ 100,000

예시

입력

logs = [
    [1, 2024, 9, 10],   # user_1: 이벤트 30일 초과 이전 접속
    [1, 2024, 11, 20],  # user_1: 이벤트 이후 재접속
    [2, 2024, 10, 20],  # user_2: 이벤트 30일 이내 접속
    [2, 2024, 11, 18],  # user_2: 이벤트 이후 접속
    [3, 2024, 11, 20],  # user_3: 이벤트 이후 첫 접속 (신규)
    [4, 2024, 10, 5],   # user_4: 이벤트 이전만 접속
]
date = [2024, 11, 15]

출력

[1, 1, 1, 1]
# comeback=1 (user_1), existing=1 (user_2), new=1 (user_3), inactive=1 (user_4)

풀이

days_in_month = {
    1: 31, 2: 28, 3: 31, 4: 30,
    5: 31, 6: 30, 7: 31, 8: 31,
    9: 30, 10: 31, 11: 30, 12: 31
}

logs = [
    [1, 2024, 9, 10],
    [1, 2024, 11, 20],
    [2, 2024, 10, 20],
    [2, 2024, 11, 18],
    [3, 2024, 11, 20],
    [4, 2024, 10, 5],
]
date = [2024, 11, 15]

# 이벤트 날짜 → 총 일수 변환
totday = date[0] * 365
for i in range(1, date[1]):
    totday += days_in_month[i]
totday += date[2]

user = 0
l = 0  # 0: 초기, 1: 30일 초과 이전, 2: 30일 이내, 3: 이벤트 이후 접속
res = [0, 0, 0, 0]  # 복귀, 기존, 신규, 미접속

for i in range(len(logs)):
    if user != logs[i][0]:
        user = logs[i][0]
        l = 0

    # 현재 로그 날짜 → 총 일수 변환
    day = logs[i][1] * 365
    for j in range(1, logs[i][2]):
        day += days_in_month[j]
    day += logs[i][3]

    if totday <= day:          # 이벤트 이후 접속
        if l == 0:   res[2] += 1  # 신규
        elif l == 1: res[0] += 1  # 복귀
        else:        res[1] += 1  # 기존
        l = 3
    elif totday - day > 30:    # 30일 초과 이전 접속
        l = 1
    else:                      # 30일 이내 이전 접속
        l = 2

    # 마지막 로그이거나 다음 로그가 다른 유저일 때 미접속 체크
    if (i + 1 == len(logs) or user != logs[i+1][0]) and l != 3:
        res[3] += 1

print(res)  # [1, 1, 1, 1]

핵심 아이디어

  1. 날짜를 총 일수로 변환해서 비교 — year * 365 + 각 월 일수 합계 + day
  2. 유저별 상태(l)를 순서대로 추적 — 로그가 날짜 오름차순 정렬되어 있다는 조건 활용
  3. 이벤트 이후 접속 여부(l == 3)가 확정되면 이전 상태(l)로 유형 결정
  4. 유저가 바뀔 때 l != 3이면 미접속 처리

'코테연습 > python' 카테고리의 다른 글

씨름 선수(그리디)  (0) 2026.04.20
회의실 배정(그리디)  (0) 2026.04.20
마구간 정하기(결정알고리즘)  (0) 2026.04.18
뮤직비디오(결정알고리즘)  (0) 2026.04.18
랜선자르기(결정알고리즘)  (0) 2026.04.16