import random import io import re # ========================================== # 1. 題目標準解答 (Solver) # ========================================== def solve(input_text): lines = input_text.strip('\n').split('\n') if not lines: return "" # 讀取匯率 n = int(lines[0].strip()) exchange_rates = {'USD': 1.0} for i in range(1, n + 1): currency, rate = lines[i].strip().split() exchange_rates[currency] = float(rate) csv_start_idx = n + 1 # 略過空行找到 CSV 起點 while csv_start_idx < len(lines) and lines[csv_start_idx].strip() == "": csv_start_idx += 1 # 略過 Header csv_start_idx += 1 category_revenue = {} # 手刻 CSV 橫列解析邏輯 (處理引號內的逗號) def parse_csv_line(line): result = [] current = "" in_quotes = False for char in line: if char == '"': in_quotes = not in_quotes elif char == ',' and not in_quotes: result.append(current) current = "" else: current += char result.append(current) return result for i in range(csv_start_idx, len(lines)): line = lines[i].strip() if not line: continue fields = parse_csv_line(line) # 條件 1: 缺少欄位 (固定 6 個欄位) if len(fields) != 6: continue tid, product, category, price_str, currency, qty_str = [f.strip() for f in fields] # 條件 1.5: 必填欄位不可為空 if not all([tid, product, category, price_str, currency, qty_str]): continue # 條件 2 & 3: 價格數量需為正數值 try: price = float(price_str) qty = int(qty_str) if price <= 0 or qty <= 0: continue except ValueError: continue # 條件 4: 貨幣必須存在 if currency not in exchange_rates: continue # 計算營收 revenue = price * qty * exchange_rates[currency] if category not in category_revenue: category_revenue[category] = 0.0 category_revenue[category] += revenue # 排序:營收降序,類別升序 sorted_categories = sorted(category_revenue.items(), key=lambda x: (-x[1], x[0])) output = [] for cat, rev in sorted_categories: output.append(f"{cat},{rev:.2f}") return "\n".join(output) # ========================================== # 2. 測資產生器 (Test Data Generator) # ========================================== def generate_test_data(num_records=1000): currencies = {"TWD": 0.03, "EUR": 1.1, "JPY": 0.007, "GBP": 1.25} categories = ["Electronics", "Accessories", "Furniture", "Clothing", "Toys"] products_clean = ["Laptop", "Monitor", "Desk", "T-Shirt", "Bear"] products_comma = ["\"Mouse, Wireless\"", "\"Keyboard, RGB\"", "\"Cable, USB-C\"", "\"Chair, Ergonomic\""] input_lines = [] # 1. 產生匯率表 (只放部分,讓一些貨幣變成無效) input_lines.append(str(len(currencies))) for cur, rate in currencies.items(): input_lines.append(f"{cur} {rate}") input_lines.append("") input_lines.append("TransactionID,ProductName,Category,Price,Currency,Quantity") # 2. 產生 CSV 數據 for i in range(1, num_records + 1): # 決定正常資料還是髒資料 (80% 正常, 20% 髒資料) is_clean = random.random() < 0.8 tid = str(i) product = random.choice(products_clean + products_comma) category = random.choice(categories) price = round(random.uniform(10, 1000), 2) currency = random.choice(list(currencies.keys()) + ["USD", "CAD"]) # CAD 會被過濾 qty = random.randint(1, 10) if not is_clean: error_type = random.randint(1, 4) if error_type == 1: category = "" # 缺漏欄位 elif error_type == 2: price = "abc" # 非數值 elif error_type == 3: qty = -5 # 負數 elif error_type == 4: currency = "KRW" # 未知貨幣 line = f"{tid},{product},{category},{price},{currency},{qty}" input_lines.append(line) return "\n".join(input_lines) # ========================================== # 3. 執行與輸出範例 # ========================================== if __name__ == "__main__": print("Generating test data...") test_input = generate_test_data(num_records=50) # 產生 50 筆做為範例 print("\n--- [Input.txt] ---") print(test_input) print("\n--- [Output.txt] ---") test_output = solve(test_input) print(test_output) # 若需存檔,可解除下方註解 # with open("input.txt", "w", encoding="utf-8") as f: # f.write(test_input) # with open("output.txt", "w", encoding="utf-8") as f: # f.write(test_output)
Standard input is empty
Generating test data... --- [Input.txt] --- 4 TWD 0.03 EUR 1.1 JPY 0.007 GBP 1.25 TransactionID,ProductName,Category,Price,Currency,Quantity 1,"Mouse, Wireless",Electronics,963.04,EUR,2 2,Bear,Furniture,611.92,TWD,2 3,Bear,Electronics,886.76,EUR,9 4,"Chair, Ergonomic",Clothing,195.44,GBP,5 5,"Mouse, Wireless",,418.0,GBP,1 6,"Chair, Ergonomic",Toys,516.74,JPY,7 7,"Keyboard, RGB",Electronics,365.22,JPY,8 8,Bear,Electronics,253.21,USD,-5 9,"Cable, USB-C",Clothing,44.23,TWD,5 10,"Cable, USB-C",,630.79,CAD,7 11,"Cable, USB-C",Accessories,356.31,USD,-5 12,T-Shirt,Electronics,67.54,USD,9 13,"Chair, Ergonomic",Electronics,825.45,USD,9 14,Bear,Accessories,216.51,USD,1 15,T-Shirt,Accessories,820.51,JPY,-5 16,"Keyboard, RGB",Accessories,593.91,JPY,8 17,Monitor,,624.04,EUR,3 18,"Mouse, Wireless",Electronics,681.13,KRW,9 19,"Chair, Ergonomic",Accessories,775.98,CAD,9 20,"Keyboard, RGB",Furniture,488.36,TWD,5 21,"Chair, Ergonomic",Clothing,871.48,GBP,10 22,"Cable, USB-C",Accessories,967.4,USD,6 23,"Mouse, Wireless",Clothing,287.29,CAD,6 24,"Cable, USB-C",Electronics,353.93,JPY,5 25,Bear,Clothing,80.38,TWD,4 26,Desk,Clothing,496.07,TWD,5 27,"Keyboard, RGB",Clothing,739.45,KRW,3 28,Laptop,Toys,423.06,USD,3 29,Desk,,153.81,JPY,4 30,"Cable, USB-C",Furniture,891.31,USD,2 31,Desk,Clothing,838.04,TWD,-5 32,Desk,Toys,452.2,CAD,10 33,"Cable, USB-C",Clothing,201.64,TWD,10 34,Desk,Clothing,114.1,CAD,10 35,Desk,Toys,305.93,CAD,5 36,Desk,Toys,740.17,USD,2 37,Laptop,Furniture,232.63,USD,9 38,"Chair, Ergonomic",Toys,877.49,USD,8 39,"Chair, Ergonomic",Furniture,587.34,EUR,8 40,"Chair, Ergonomic",Toys,794.77,EUR,4 41,T-Shirt,Clothing,103.7,TWD,3 42,"Keyboard, RGB",Electronics,783.66,GBP,-5 43,Desk,Accessories,546.07,USD,5 44,Laptop,Clothing,634.14,KRW,2 45,Laptop,Accessories,987.76,GBP,5 46,Laptop,Toys,522.74,TWD,3 47,"Keyboard, RGB",Accessories,535.08,USD,10 48,"Mouse, Wireless",Accessories,406.88,USD,9 49,Monitor,Electronics,abc,GBP,7 50,"Cable, USB-C",Toys,380.45,GBP,9 --- [Output.txt] --- Accessories,23970.74 Electronics,18967.36 Toys,17618.86 Clothing,12275.52 Furniture,9154.85