m-abdur2024's picture
Upload 40 files
0d3476b verified
raw
history blame contribute delete
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