fork(1) download
  1. import random
  2. import io
  3. import re
  4.  
  5. # ==========================================
  6. # 1. 題目標準解答 (Solver)
  7. # ==========================================
  8. def solve(input_text):
  9. lines = input_text.strip('\n').split('\n')
  10. if not lines:
  11. return ""
  12.  
  13. # 讀取匯率
  14. n = int(lines[0].strip())
  15. exchange_rates = {'USD': 1.0}
  16. for i in range(1, n + 1):
  17. currency, rate = lines[i].strip().split()
  18. exchange_rates[currency] = float(rate)
  19.  
  20. csv_start_idx = n + 1
  21. # 略過空行找到 CSV 起點
  22. while csv_start_idx < len(lines) and lines[csv_start_idx].strip() == "":
  23. csv_start_idx += 1
  24.  
  25. # 略過 Header
  26. csv_start_idx += 1
  27.  
  28. category_revenue = {}
  29.  
  30. # 手刻 CSV 橫列解析邏輯 (處理引號內的逗號)
  31. def parse_csv_line(line):
  32. result = []
  33. current = ""
  34. in_quotes = False
  35. for char in line:
  36. if char == '"':
  37. in_quotes = not in_quotes
  38. elif char == ',' and not in_quotes:
  39. result.append(current)
  40. current = ""
  41. else:
  42. current += char
  43. result.append(current)
  44. return result
  45.  
  46. for i in range(csv_start_idx, len(lines)):
  47. line = lines[i].strip()
  48. if not line:
  49. continue
  50.  
  51. fields = parse_csv_line(line)
  52.  
  53. # 條件 1: 缺少欄位 (固定 6 個欄位)
  54. if len(fields) != 6:
  55. continue
  56.  
  57. tid, product, category, price_str, currency, qty_str = [f.strip() for f in fields]
  58.  
  59. # 條件 1.5: 必填欄位不可為空
  60. if not all([tid, product, category, price_str, currency, qty_str]):
  61. continue
  62.  
  63. # 條件 2 & 3: 價格數量需為正數值
  64. try:
  65. price = float(price_str)
  66. qty = int(qty_str)
  67. if price <= 0 or qty <= 0:
  68. continue
  69. except ValueError:
  70. continue
  71.  
  72. # 條件 4: 貨幣必須存在
  73. if currency not in exchange_rates:
  74. continue
  75.  
  76. # 計算營收
  77. revenue = price * qty * exchange_rates[currency]
  78.  
  79. if category not in category_revenue:
  80. category_revenue[category] = 0.0
  81. category_revenue[category] += revenue
  82.  
  83. # 排序:營收降序,類別升序
  84. sorted_categories = sorted(category_revenue.items(), key=lambda x: (-x[1], x[0]))
  85.  
  86. output = []
  87. for cat, rev in sorted_categories:
  88. output.append(f"{cat},{rev:.2f}")
  89.  
  90. return "\n".join(output)
  91.  
  92. # ==========================================
  93. # 2. 測資產生器 (Test Data Generator)
  94. # ==========================================
  95. def generate_test_data(num_records=1000):
  96. currencies = {"TWD": 0.03, "EUR": 1.1, "JPY": 0.007, "GBP": 1.25}
  97. categories = ["Electronics", "Accessories", "Furniture", "Clothing", "Toys"]
  98. products_clean = ["Laptop", "Monitor", "Desk", "T-Shirt", "Bear"]
  99. products_comma = ["\"Mouse, Wireless\"", "\"Keyboard, RGB\"", "\"Cable, USB-C\"", "\"Chair, Ergonomic\""]
  100.  
  101. input_lines = []
  102.  
  103. # 1. 產生匯率表 (只放部分,讓一些貨幣變成無效)
  104. input_lines.append(str(len(currencies)))
  105. for cur, rate in currencies.items():
  106. input_lines.append(f"{cur} {rate}")
  107.  
  108. input_lines.append("")
  109. input_lines.append("TransactionID,ProductName,Category,Price,Currency,Quantity")
  110.  
  111. # 2. 產生 CSV 數據
  112. for i in range(1, num_records + 1):
  113. # 決定正常資料還是髒資料 (80% 正常, 20% 髒資料)
  114. is_clean = random.random() < 0.8
  115.  
  116. tid = str(i)
  117. product = random.choice(products_clean + products_comma)
  118. category = random.choice(categories)
  119. price = round(random.uniform(10, 1000), 2)
  120. currency = random.choice(list(currencies.keys()) + ["USD", "CAD"]) # CAD 會被過濾
  121. qty = random.randint(1, 10)
  122.  
  123. if not is_clean:
  124. error_type = random.randint(1, 4)
  125. if error_type == 1:
  126. category = "" # 缺漏欄位
  127. elif error_type == 2:
  128. price = "abc" # 非數值
  129. elif error_type == 3:
  130. qty = -5 # 負數
  131. elif error_type == 4:
  132. currency = "KRW" # 未知貨幣
  133.  
  134. line = f"{tid},{product},{category},{price},{currency},{qty}"
  135. input_lines.append(line)
  136.  
  137. return "\n".join(input_lines)
  138.  
  139. # ==========================================
  140. # 3. 執行與輸出範例
  141. # ==========================================
  142. if __name__ == "__main__":
  143. print("Generating test data...")
  144. test_input = generate_test_data(num_records=50) # 產生 50 筆做為範例
  145.  
  146. print("\n--- [Input.txt] ---")
  147. print(test_input)
  148.  
  149. print("\n--- [Output.txt] ---")
  150. test_output = solve(test_input)
  151. print(test_output)
  152.  
  153. # 若需存檔,可解除下方註解
  154. # with open("input.txt", "w", encoding="utf-8") as f:
  155. # f.write(test_input)
  156. # with open("output.txt", "w", encoding="utf-8") as f:
  157. # f.write(test_output)
Success #stdin #stdout 0.03s 11956KB
stdin
Standard input is empty
stdout
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