Simulation
Just simulate the process of the entire problem, updating the required states, and returning the desired output.
Problem 1 - Shell Game
In this game, there are three shells with a hidden pebble under one, but the player doesn’t know its starting position. The game is played n$ times: in each round, the cow swaps two shells, and the player guesses the pebble's location. We want to find the maximum possible score, where the player scores one point for each correct guess.
To handle each start location, we label the shells pebble_at_pos = [0,1,2]
. We also initialize counter_at_pebble = [0,0,0]
, where counter_at_pebble[i]
keeps track of the score if the pebble starts at position i$.
For each round:
- Process the swap.
- Check the guessed shell's label.
- Increment
counter_at_pebble
for the index corresponding to the guessed label.
This setup allows us to track scores across all starting positions and determine the maximum possible score.
read = open("shell.in")
n = int(read.readline())
pebble_at_pos = [0,1,2]
counter_at_pebble = [0,0,0]
for _ in range (n):
a, b, g = [int(i) - 1 for i in read.readline().split()]
pebble_at_pos[a], pebble_at_pos[b] = pebble_at_pos[b], pebble_at_pos[a]
counter_at_pebble[pebble_at_pos[g]] += 1
print(max(counter_at_pebble), file=open("shell.out", "w"))
Problem 2 - Milk Mixing
We have three buckets, each with a capacity
-
Pouring Logic:
To pour milk from bucketto bucket : - Calculate the maximum amount that can be poured, denoted by
. - Update the amounts:
This ensures that we don’t exceed bucket
's capacity and that is emptied only as much as possible. - Calculate the maximum amount that can be poured, denoted by
-
Simulating the Pouring Cycle:
We perform the pouring operations in a fixed sequence to achieve exactly 100 pours:- Pour from bucket 1 to bucket 2.
- Pour from bucket 2 to bucket 3.
- Pour from bucket 3 back to bucket 1.
We repeat this sequence 33 times (for 99 pours), then execute one additional pour from bucket 1 to bucket 2 to reach exactly 100 pours.
Pseudocode for the sequence:
- For each cycle:
- After 99 pours, finish with
.
-
Final State:
The values of, , and after these 100 operations represent the final milk amounts in each bucket, each bounded by the capacity constraints at each step.
In summary, we solve this by enforcing capacity limits in each pour operation and iteratively applying a fixed sequence until reaching 100 total pours.
read = open("mixmilk.in")
c1, m1 = [int(i) for i in read.readline().split()]
c2, m2 = [int(i) for i in read.readline().split()]
c3, m3 = [int(i) for i in read.readline().split()]
def pour(x_cap: int, x_amt:int, y_cap:int, y_amt:int):
pourable_amount = min(x_amt, y_cap - y_amt)
x_amt -= pourable_amount
y_amt += pourable_amount
return x_amt, y_amt
for _ in range (0, 99, 3):
m1,m2 = pour(c1,m1,c2,m2)
m2,m3 = pour(c2,m2,c3,m3)
m3,m1 = pour(c3,m3,c1,m1)
m1, m2 = pour(c1, m1, c2, m2)
milk = [m1,m2,m3]
with open("mixmilk.out", "w") as out:
for m in milk:
print(m, file=out)
Problem - 3 Cow Signal
This one is self explanatory. for each line, initialize an empty string, append each character k times into the string, and then append the resulting string k times into a list, print the list of strings top to bottom.
read = open("cowsignal.in")
m,n,k = [int(i) for i in read.readline().split()]
signal = []
for _ in range(m):
s = ""
t = read.readline()
for char in t:
if char != '\n':
s += char * k
for _ in range(k):
signal.append(s)
with open("cowsignal.out", "w") as out:
for s in signal:
print(s, file=out)
Problem - 4 Stuck In A Rut
In this problem, we are given an infinite grid with ( n ) cows, each starting at unique coordinates. Each cow moves in one of two directions:
- East: ((x, y) \to (x+1, y))
- North: ((x, y) \to (x, y+1))
As cows move, they eat grass in each cell they pass over, creating barren paths. If a cow encounters a barren cell, it stops. If two cows reach the same cell simultaneously, they both consume the grass and continue moving.
The objective is to determine how much grass each cow consumes before it stops (or if it continues infinitely).
Step 1: Define Classes
- Cow: Holds properties
id
,direction
('E' for east, 'N' for north), and starting coordinates (x
,y
). - Collision: Represents a collision event, storing:
stopper
: the cow that stops another.stopped
: the cow that will be stopped.collision_time
: the time at which thestopped
cow reaches the collision point.
Step 2: Organize Cows by Direction
- Input data is processed to create lists,
eastward_cows
andnorthward_cows
, grouping cows by their movement direction.
Step 3: Identify Potential Collisions
For each eastward and northward cow pair:
-
Calculate the potential collision time for both the x and y axes:
- Time on x-axis =
northward_cow.x - eastward_cow.x
- Time on y-axis =
eastward_cow.y - northward_cow.y
- Time on x-axis =
-
Determine the stopper and stopped cows:
- If
time_x > time_y > 0
, the northward cow is the stopper. - If
time_y > time_x > 0
, the eastward cow is the stopper.
- If
-
Store valid collisions in
collisions
and sort bycollision_time
.
Step 4: Process Collisions
For each collision
in the sorted list:
-
If both cows are still moving (
stop_times
is set to infinity for both):- Set the
stop_time
of thestopped
cow to thecollision_time
.
- Set the
-
If the
stopper
cow has already stopped:- Calculate the final position it reached before stopping:
- Northward stopper:
final_y = start_y + stop_times[stopper.id]
- Eastward stopper:
final_x = start_x + stop_times[stopper.id]
- Northward stopper:
- If this final position meets or exceeds the coordinates of the
stopped
cow, set thestop_time
of thestopped
cow to thecollision_time
.
- Calculate the final position it reached before stopping:
Step 5: Output Results
For each cow:
- Print its stop time if it stops.
- Print "Infinity" if the cow never stops.
n = int(input())
class Cow:
def __init__(self, id: int, x: int, y: int, direction: str):
self.id = id
self.x = x
self.y = y
self.direction = direction
class Collision:
def __init__(self, stopper: Cow, stopped: Cow, time: int):
self.stopper = stopper
self.stopped = stopped
self.time = time
eastward_cows = []
northward_cows = []
stop_times = [float('inf')] * n
collisions = []
# Read input and categorize cows by direction
for i in range(n):
direction, x, y = input().split()
if direction == 'E':
eastward_cows.append(Cow(i, int(x), int(y), direction))
else:
northward_cows.append(Cow(i, int(x), int(y), direction))
# Calculate potential collisions between each pair of eastward and northward cows
for e_cow in eastward_cows:
for n_cow in northward_cows:
time_x = n_cow.x - e_cow.x
time_y = e_cow.y - n_cow.y
if time_x == time_y or time_x <= 0 or time_y <= 0:
continue
elif time_x > time_y:
collisions.append(Collision(n_cow, e_cow, time_x)) # North cow stops East cow
elif time_y > time_x:
collisions.append(Collision(e_cow, n_cow, time_y)) # East cow stops North cow
# Sort collisions by occurrence time
collisions.sort(key=lambda collision: collision.time)
# Process collisions to determine stop times
for collision in collisions:
stopper, stopped, collision_time = collision.stopper, collision.stopped, collision.time
if stop_times[stopper.id] == float('inf') and stop_times[stopped.id] == float('inf'):
stop_times[stopped.id] = collision_time
elif stop_times[stopper.id] != float('inf') and stop_times[stopped.id] == float('inf'):
if stopper.direction == 'N':
y_position = stopper.y + stop_times[stopper.id]
if y_position >= stopped.y:
stop_times[stopped.id] = collision_time
elif stopper.direction == 'E':
x_position = stopper.x + stop_times[stopper.id]
if x_position >= stopped.x:
stop_times[stopped.id] = collision_time
# Output results
for stop_time in stop_times:
print('Infinity' if stop_time == float('inf') else stop_time)
Problem - 5 Milk Measurement
This program tracks the milk production of three cows over a series of days, updating their milk levels based on input data and counting how many times the maximum milk producer changes.
Class Definitions
-
Data Class:
- Represents an entry for a cow's milk measurement.
- Contains the following attributes:
id
: Identifier for the cow.day
: The day the measurement was recorded.add
: Amount of milk added on that day.sub
: Amount of milk subtracted on that day.
-
Cow Class:
- Represents each cow and its current milk production.
- Contains the following attributes:
milk
: The current milk amount (initially set to 7).top
: Indicates if the cow is the top producer (used for tracking).
- Includes a method to update the milk production based on additions and subtractions.
Data Input and Processing
- Mapping: A dictionary maps cow names (Mildred, Elsie, Bessie) to unique IDs (0, 1, 2).
- Input Reading:
- The program reads from a file containing multiple entries for daily milk measurements.
- Each entry specifies the day, the cow's name, and the quantity of milk (positive for addition, negative for subtraction).
- Data Storage: Each measurement is stored in a list as instances of the
Data
class.
Sorting and Updating Milk Values
- The list of measurements is sorted by day.
- For each measurement:
- The corresponding cow's milk level is updated.
- A check is made to determine the current maximum milk value among the cows.
- If the maximum producer changes (i.e., if the cow with the highest milk value differs from the previous day), a counter is incremented.
Output
- Finally, the program outputs the total number of times the maximum milk producer changed during the recorded days to a specified output file.
class Data:
def __init__(self, id: int, day: int, add: int, sub: int):
self.id = id
self.day = day
self.add = add
self.sub = sub
class Cow:
def __init__(self, milk: int = 7, top: bool = False):
self.milk = milk
self.top = top
def update(self, add, sub):
self.milk += add
self.milk -= sub
names_to_id = {'Mildred': 0, 'Elsie': 1, 'Bessie': 2}
read = open("measurement.in")
n = int(read.readline())
data_list = []
for _ in range(n):
day, name, quantity = read.readline().split()
day = int(day)
if quantity[0] == '+':
data_list.append(Data(names_to_id[name], day, int(quantity[1:]), 0))
elif quantity[0] == '-':
data_list.append(Data(names_to_id[name], day, 0, int(quantity[1:])))
# Sort `data_list` by the day attribute
data_list.sort(key=lambda obj: obj.day)
# Initialize list of Cows with default milk values of 7
Cows = [Cow() for _ in range(3)]
Max_tuples = [False, False, False]
counter = 0
for d in data_list:
# Update the milk production for the current cow
Cows[d.id].update(d.add, d.sub)
# Create a list of current milk values
milk_values = [cow.milk for cow in Cows]
max_milk = max(milk_values)
# Determine if each cow is currently at the maximum
max_now = [milk == max_milk for milk in milk_values]
# Increment the counter if there's a change in who has max milk
if max_now != Max_tuples:
counter += 1
Max_tuples = max_now
# Output the counter result to txt.out
with open("measurement.out", "w") as output_file:
output_file.write(f"{counter}\n")