m-abdur2024's picture
Upload 40 files
0d3476b verified
raw
history blame
No virus
7.26 kB
import json
import logging
import re
from flask import Flask, request, jsonify
from routes import app
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def parse_markdown_table(table_str):
"""
Parses a markdown table string and returns a list of lab configurations.
Each configuration is a dictionary with keys:
- lab: int
- cell_counts: list of ints
- increment: str
- condition: list of three ints
"""
lines = table_str.strip().split('\n')
# Remove header and separator
data_lines = lines[2:]
lab_configs = {}
for line in data_lines:
# Split by '|' and strip spaces
parts = [part.strip() for part in line.strip().split('|')]
if len(parts) < 4:
continue # Skip incomplete lines
lab_str, cell_counts_str, increment_str, condition_str = parts[:4]
lab = int(lab_str)
# Extract cell counts
cell_counts = list(map(int, cell_counts_str.split()))
# Extract increment expression
increment = increment_str
# Extract condition
# Use regular expression to extract numbers, considering multiple spaces
condition_numbers = re.findall(r'\d+', condition_str)
condition = list(map(int, condition_numbers))
if len(condition) != 3:
raise ValueError("Condition does not have exactly three numbers.")
# Store in lab_configs
lab_configs[lab] = {
'cell_counts': cell_counts,
'increment': increment,
'condition': condition
}
return lab_configs
def apply_increment(count, expr):
"""
Applies the increment expression to the given count.
"""
tokens = expr.split()
if len(tokens) != 3:
raise ValueError(f"Invalid increment expression: {expr}")
op1, operator, op2 = tokens
if op1 != 'count':
raise ValueError(f"Invalid operand: {op1}")
if op2 == 'count':
operand = count
else:
operand = int(op2)
if operator == '+':
return count + operand
elif operator == '*':
return count * operand
else:
raise ValueError(f"Unknown operator: {operator}")
def evaluate_condition(count, condition):
"""
Evaluates the condition and returns the target lab.
Condition is a list of three integers: [divisor, lab_if_true, lab_if_false]
"""
divisor, lab_if_true, lab_if_false = condition
if divisor == 0:
raise ValueError("Divisor in condition cannot be zero.")
if count % divisor == 0:
return lab_if_true
else:
return lab_if_false
@app.route('/lab_work', methods=['POST'])
def lab_work():
try:
data = request.get_json()
if not isinstance(data, list):
return jsonify({"error": "Input data should be a list of markdown tables."}), 400
test_cases = data # List of markdown table strings
output = []
for idx, table_str in enumerate(test_cases):
logger.info(f"Processing Test Case {idx + 1}")
# Parse the table
lab_configs = parse_markdown_table(table_str)
if not lab_configs:
return jsonify({"error": f"No lab configurations found in Test Case {idx + 1}."}), 400
# Determine the number of labs
lab_numbers = sorted(lab_configs.keys())
num_labs = len(lab_numbers)
max_lab_number = max(lab_numbers)
# Initialize labs data
labs = {}
for lab in lab_numbers:
labs[lab] = {
'increment': lab_configs[lab]['increment'],
'condition': lab_configs[lab]['condition'],
'current_dishes': lab_configs[lab]['cell_counts'][:], # Make a copy
'next_day_dishes': []
}
# Initialize analysis counts
analysis_counts = {lab: 0 for lab in lab_numbers}
# Initialize records at intervals
records = {}
# Simulate 10,000 days
for day in range(1, 10001):
# Initialize processing lists for the day
processing_lists = {lab: labs[lab]['current_dishes'][:] for lab in lab_numbers}
# Clear current_dishes for receiving new dishes passed to labs already processed
for lab in lab_numbers:
labs[lab]['current_dishes'] = []
# Process labs in order
for lab in lab_numbers:
dishes_to_process = processing_lists[lab]
for dish in dishes_to_process:
# Apply increment
try:
updated_count = apply_increment(dish, labs[lab]['increment'])
except ValueError as ve:
return jsonify({"error": f"Error in increment expression for lab {lab}: {str(ve)}"}), 400
# Evaluate condition
try:
target_lab = evaluate_condition(updated_count, labs[lab]['condition'])
except ValueError as ve:
return jsonify({"error": f"Error in condition for lab {lab}: {str(ve)}"}), 400
# Increment analysis count
analysis_counts[lab] += 1
# Assign to target lab
if target_lab not in lab_configs:
return jsonify({"error": f"Target lab {target_lab} does not exist in Test Case {idx + 1}."}), 400
if target_lab > lab:
# Target lab has not been processed yet today
processing_lists[target_lab].append(updated_count)
else:
# Target lab has already been processed today
labs[target_lab]['next_day_dishes'].append(updated_count)
# After processing all labs, update current_dishes for next day
for lab in lab_numbers:
# Append dishes passed to labs already processed today
labs[lab]['current_dishes'].extend(labs[lab]['next_day_dishes'])
# Clear next_day_dishes for the next day
labs[lab]['next_day_dishes'] = []
# Record counts at intervals of 1000 days
if day % 1000 == 0:
# Prepare the counts list ordered by lab numbers
counts_list = [analysis_counts[lab] for lab in lab_numbers]
records[str(day)] = counts_list
logger.info(f"Recorded counts for day {day}: {counts_list}")
# After simulation, prepare the output for this test case
output.append(records)
return jsonify(output), 200
except Exception as e:
logger.error(f"An error occurred: {str(e)}")
return jsonify({"error": f"An error occurred: {str(e)}"}), 500