Urgent Help Needed: Kattis "Workout for a Dumbbell" - Wrong Answer and Failing Sample Case (Python)

Posted by Excellent_Dingo_7109@reddit | learnprogramming | View on Reddit | 9 comments

Hi r/learnprogramming,

I’m struggling with the Kattis problem "Workout for a Dumbbell" (https://open.kattis.com/problems/workout) and keep getting Wrong Answer (WA) verdicts. Worse, my code and a revised version I worked on don’t even pass the sample test case (outputting 100). A book I’m using calls this a "gym simulation" problem and suggests using 1D arrays to simulate time quickly, but I’m clearly misinterpreting something, especially the two-way waiting rule ("Jim’s usage sometimes results in the other people having to wait as well"). I’d really appreciate your help figuring out what’s wrong or how to approach this correctly!

Problem Description

Jim schedules workouts on 10 machines, using each exactly three times. He has fixed usage and recovery times per machine. Another person uses each machine with their own usage time, recovery time, and first-use time, following a periodic schedule. Key rules:

Input

Sample Input/Output

Input:

5 5 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
2 2 1
8 3 0
1 1 0
1 1 0
1 1 0
1 1 0
1 1 0
1 1 0
1 1 0
1 1 0

Output: 100

My Original Code

My approach used a fixed order (machines 1–10, three times), calculating wait times with modulo operations and an offset to adjust the other person’s schedule. It doesn’t produce 100 for the sample input and gets WA on Kattis, likely due to misinterpreting the two-way waiting rule.

def workout(jim_use, jim_recovery, machine_use, machine_recovery, machine_first_use, machine_offset, current_time):
    time_taken = 0
    wait_time = 0
    one_cycle = machine_recovery + machine_use
    if current_time < machine_first_use:
        wait_time = 0
    elif current_time == machine_first_use:
        wait_time = machine_use
    else:
        if current_time % one_cycle > (machine_first_use + machine_offset + machine_use) % one_cycle:
            wait_time = 0
        elif current_time % one_cycle == (machine_first_use + machine_offset + machine_use) % one_cycle:
            wait_time = machine_use
        else:
            wait_time = (machine_first_use + machine_offset + machine_use) % one_cycle - current_time % one_cycle
    new_offset = 0
    time_after_jim_use = current_time + wait_time + jim_use
    if time_after_jim_use < machine_first_use:
        new_offset = 0
    else:
        new_offset = time_after_jim_use - ((time_after_jim_use + machine_offset) // one_cycle) * one_cycle
    return time_after_jim_use + jim_recovery, new_offset

temp_jim = [*map(int, input().split())]
jim = [[temp_jim[2*i], temp_jim[2*i+1]] for i in range(10)]
machines = [[*map(int, input().split())] for _ in [0]*10]
offset = [0 for _ in range(10)]
current_time = 0
for _ in range(3):
    for machine_using in range(10):
        current_time, new_offset = workout(*jim[machine_using], *machines[machine_using], offset[machine_using], current_time)
        offset[machine_using] = new_offset
print(current_time)

Issues:

Latest Attempt (Also WA)

I tried a greedy approach, selecting the machine with the earliest start time, using 1D arrays (uses_left for remaining uses, next_usage for the other person’s next usage time). The other person’s schedule is updated to the next cycle boundary after Jim’s usage. It still fails the sample case (doesn’t output 100) and gets WA on Kattis.

def get_next_start(jim_use, machine_use, machine_recovery, machine_first_use, current_time, next_usage):
    cycle = machine_use + machine_recovery
    start_time = current_time
    k = max(0, (current_time - machine_first_use + cycle - 1) // cycle)
    while True:
        usage_start = max(machine_first_use + k * cycle, next_usage)
        usage_end = usage_start + machine_use
        if start_time < usage_start:
            return start_time, usage_start
        elif start_time == usage_start:
            return usage_end, usage_start  # Politeness: Jim waits
        elif usage_start < start_time < usage_end:
            return usage_end, usage_start
        k += 1

# Read input
temp_jim = list(map(int, input().split()))
jim = [[temp_jim[2*i], temp_jim[2*i+1]] for i in range(10)]
machines = [list(map(int, input().split())) for _ in range(10)]
uses_left = [3] * 10  # 1D array: remaining uses
next_usage = [m[2] for m in machines]  # 1D array: other person's next usage time
current_time = 0
last_machine10_end = 0

# Simulate 30 uses
for _ in range(30):
    earliest_start = float('inf')
    best_machine = -1
    best_usage_start = None
    for i in range(10):
        if uses_left[i] > 0:
            start_time, usage_start = get_next_start(jim[i][0], machines[i][0], machines[i][1], machines[i][2], current_time, next_usage[i])
            if start_time < earliest_start:
                earliest_start = start_time
                best_machine = i
                best_usage_start = usage_start
    if best_machine == -1:
        break
    jim_end = earliest_start + jim[best_machine][0]
    # Update other person's next usage
    cycle = machines[best_machine][0] + machines[best_machine][1]
    k = max(0, (jim_end - machines[best_machine][2] + cycle - 1) // cycle)
    next_usage[best_machine] = machines[best_machine][2] + k * cycle
    if next_usage[best_machine] < jim_end:
        next_usage[best_machine] += cycle
    current_time = jim_end + jim[best_machine][1]  # Update to end of recovery
    uses_left[best_machine] -= 1
    if best_machine == 9:
        last_machine10_end = jim_end  # End of usage, not recovery

print(last_machine10_end)

Issues:

Book’s Hint

The book suggests this is a "gym simulation" problem and recommends using 1D arrays to simulate time quickly. I’ve used arrays for uses_left and next_usage, but I’m not getting the sample output or passing Kattis tests.

Questions

  1. How should the two-way waiting rule ("Jim’s usage sometimes results in the other people having to wait as well") be implemented? Is the other person’s schedule supposed to shift to the next cycle boundary after Jim’s usage, or am I missing something?
  2. Is the greedy approach (earliest start time) correct, or do I need dynamic programming or another strategy?
  3. How do I correctly update the other person’s schedule after Jim’s usage? My latest attempt uses cycle boundaries, but it fails.
  4. Are there edge cases (e.g., negative machine_first_use, large times) I’m not handling?
  5. Has anyone solved this on Kattis? Could you share pseudocode or point out where my approach fails?
  6. Why don’t either code produce 100 for the sample input? What’s wrong with the simulation?

I’m really stuck and would love any insights, pseudocode, or corrections. If you’ve solved this, how did you handle the scheduling and waiting rules? Thanks so much for your help!