무지의 먹방 라이브 문서의 문제 1 풀이 코드다. if __name__ == "__main__": 아래가 자체 테스트다.

"""무지의 먹방 라이브 (프로그래머스 42891) 풀이와 검증."""
import random
import time


def solution(food_times, k):
    if sum(food_times) <= k:
        return -1
    foods = sorted((t, i + 1) for i, t in enumerate(food_times))   # 빨리 끝나는 음식부터
    n, prev = len(foods), 0
    for idx, (t, _) in enumerate(foods):
        m = n - idx                            # 아직 남은 음식 수
        layer = (t - prev) * m                 # 이 음식이 끝날 때까지 한 바퀴씩 도는 시간
        if k < layer:
            rest = sorted(i for _, i in foods[idx:])
            return rest[k % m]
        k -= layer
        prev = t
    return -1


def trace_layers(food_times, k):
    foods = sorted((t, i + 1) for i, t in enumerate(food_times))
    n, prev, rows = len(foods), 0, []
    for idx, (t, i) in enumerate(foods):
        m = n - idx
        layer = (t - prev) * m
        rows.append((i, t, m, layer, k))
        if k < layer:
            return rows
        k -= layer
        prev = t
    return rows


def by_seconds(food_times, k):
    """1초씩 그대로 흉내 낸다."""
    left = food_times[:]
    n = len(left)
    if sum(left) <= k:
        return -1
    i = 0
    for _ in range(k):
        while left[i] == 0:
            i = (i + 1) % n
        left[i] -= 1
        i = (i + 1) % n
    while left[i] == 0:
        i = (i + 1) % n
    return i + 1


if __name__ == "__main__":
    assert solution([3, 1, 2], 5) == 1 == by_seconds([3, 1, 2], 5)
    assert trace_layers([3, 1, 2], 5) == [(2, 1, 3, 3, 5), (3, 2, 2, 2, 2), (1, 3, 1, 1, 0)]
    assert solution([4, 2, 3, 6, 7, 1, 5, 8], 16) == 3 == by_seconds([4, 2, 3, 6, 7, 1, 5, 8], 16)
    assert trace_layers([4, 2, 3, 6, 7, 1, 5, 8], 16) == [(6, 1, 8, 8, 16), (2, 2, 7, 7, 8), (3, 3, 6, 6, 1)]
    rng = random.Random(42891)
    for _ in range(3000):
        ft = [rng.randint(1, 8) for _ in range(rng.randint(1, 8))]
        k = rng.randint(1, sum(ft) + 3)
        assert solution(ft, k) == by_seconds(ft, k), (ft, k)
    # 효율성: 음식 20만 개, 시간 1억까지, k 2×10^13까지
    ft = [rng.randint(1, 100_000_000) for _ in range(200_000)]
    t0 = time.perf_counter()
    assert solution(ft, sum(ft) - 1) != -1 and solution(ft, sum(ft)) == -1
    solution(ft, sum(ft) // 2)
    t = time.perf_counter() - t0
    assert t < 10, t
    print(f"200k foods: {t:.2f}s")
    print("ALL CHECKS PASSED")