標籤:

Python-Fun Merchants Guide To The Galaxy

這幾天在面試,面試後又有一道筆試題,感覺很有意思,分享給大家

代碼放在github上:鏈接地址

題目如下:

Description

You decided to give up on earth after the latest financial collapse left 99.99% of the earths population with 0.01% of the wealth. Luckily, with the scant sum of money that is left in your account, you are able to afford to rent a spaceship, leave earth, and fly all over the galaxy to sell common metals and dirt (which apparently is worth a lot).

Buying and selling over the galaxy requires you to convert numbers and units, and you decided to write a program to help you. The numbers used for intergalactic transactions follows similar convention to the roman numerals and you have painstakingly collected the appropriate translation between them.

Numbers are formed by combining symbols together and adding the values. For example, MMVI is 1000 + 1000 + 5 + 1 = 2006. Generally, symbols are placed in order of value, starting with the largest values. When smaller values precede larger values, the smaller values are subtracted from the larger values, and the result is added to the total. For example MCMXLIV = 1000 + (1000 ? 100) + (50 ? 10) + (5 ? 1) = 1944.

The symbols "I", "X", "C", and "M" can be repeated three times in succession, but no more. (They may appear four times if the third and fourth are separated by a smaller value, such as XXXIX.) "D", "L", and "V" can never be repeated. "I" can be subtracted from "V" and "X" only. "X" can be subtracted from "L" and "C" only. "C" can be subtracted from "D" and "M" only. "V", "L", and "D" can never be subtracted. Only one small-value symbol may be subtracted from any large-value symbol. A number written in Arabic numerals can be broken into digits. For example, 1903 is composed of 1, 9, 0, and 3. To write the Roman numeral, each of the non-zero digits should be treated separately. In the above example, 1,000 = M, 900 = CM, and 3 = III. Therefore, 1903 = MCMIII.

Input to your program consists of lines of text detailing your notes on the conversion between intergalactic units and roman numerals.

You are expected to handle invalid queries appropriately.

INPUT:

glob is I

prok is V

pish is X

tegj is L

glob glob Silver is 34 Credits

glob prok Gold is 57800 Credits

pish pish Iron is 3910 Credits

how much is pish tegj glob glob ?

how many Credits is glob prok Silver ?

how many Credits is glob prok Gold ?

how many Credits is glob prok Iron ?

OUTPUT

pish tegj glob glob is 42

glob prok Silver is 68 Credits

glob prok Gold is 57800 Credits

glob prok Iron is 782 Credits

大致意思是,這商人要去外球做生意,但語言不通啊,得做個自動轉換星際數字的程序來算賬,而星際數字又與羅馬數字類似。

所以我們需要做一個程序,來轉換星際數字為阿拉伯數字,方便我們的計算與理解

看輸入輸出,大概可以知道程序要分兩部分,一部分為從輸入中提取關鍵信息,來得到星際數字轉換為羅馬數字的字典,第二部分為羅馬數字轉換為阿拉伯數字的方法,最後求出星際金屬的價格,然後根據問題格式化輸出答案。

import redef parser(str): # 星際語言轉換為羅馬字元的字典 star_to_roma = {} # 金屬價格字典 metal_price = {} content_array = str.split(
) for i in content_array: # 將文章分成三種類型進行解析 # 第一種句型,分析後完成星際語言與羅馬數字轉換字典 if re.search(ris [A-Z], i): try: star_to_roma[i.split( is )[0]] = i.split( is )[1] except: print("請檢查此行是否輸入有誤:{0}".format(i)) # 第二種句型,分析後可以將星際語言轉換為羅馬數字後,求出金屬的Credit價格 elif re.search(ris d+, i): m = re.match(r([a-z ]+[a-z]) ([A-Z][a-z]+) is (d+) Credits, i) s = for k in m.group(1).split(" "): s += star_to_roma[k] # 構成羅馬字元串,交給羅馬字元串處理函數去處理 try: metal_price[m.group(2)] = int(m.group(3)) / transform_roman_num2_alabo(s) except: print({0}中有字元不屬於羅馬字元.format(s)) # 第三種句型,分析後可以解析問題,求出答案。 elif re.search(rhow, i): # 對how many類的問題進行分析,匹配出對應信息 if re.search(how much, i): star_str = re.match(rhow much is ([a-z ]+[a-z]) ?, i) try: star_str_array = star_str.group(1).split( ) roma_str = for i in star_str_array: roma_str += star_to_roma[i] print(star_str.group(1), is, transform_roman_num2_alabo(roma_str)) except: print("請檢查此行是否輸入有誤:{0}".format(i)) # 對how many類的問題進行分析,匹配出對應信息 elif re.search(how many, i): star_str = re.match(rhow many Credits is (([a-z ]+[a-z]) ([A-Z][a-z]+)) ?, i) try: star_str_array = star_str.group(2).split( ) roma_str = for i in star_str_array: roma_str += star_to_roma[i] print(star_str.group(1), is, transform_roman_num2_alabo(roma_str) * metal_price[ star_str.group(3)], Credits) except: print("請檢查此行是否輸入有誤:{0}".format(i)) else: print("請檢查一下這行輸入是否有誤:{0}
程序停止運行".format(i)) breakdef transform_roman_num2_alabo(roma_str): 將羅馬數字轉化為阿拉伯數字 roma_dict={I:1,V:5,X:10,L:50,C:100,D:500,M:1000} if roma_str==0: return 0 else: res=0 for i in range(0,len(roma_str)): if i==0 or roma_dict[roma_str[i]]<=roma_dict[roma_str[i-1]]: res+=roma_dict[roma_str[i]] else: res+=roma_dict[roma_str[i]]-2*roma_dict[roma_str[i-1]] return resif __name__ == __main__: with open(rtest.txt) as f: str = f.read() parser(str)

這道題比較開放,答案不唯一,歡迎大家來進行討論。


推薦閱讀:

python基礎-*args和**kwargs
怎麼啟動Python?
python - 環境配置
Windows下如何最省事最穩定的安裝Python與Scrapy
怎樣才能寫出 Pythonic 的代碼?

TAG:Python |