Chuyển đổi chữ số La Mã được mã hóa thành số thập phân Ả Rập


16

Viết một thuật toán để giải thích một chuỗi các chữ cái là một chữ số La Mã. (xem quy tắc số La Mã dưới đây)

Mỗi chữ cái riêng biệt có một giá trị thập phân Ả Rập phù hợp, không có tối đa. Nhưng bạn không có chìa khóa trước, do đó, {A=10, I=1, X=5, ... Z=1000000}được quyết định bởi sự giải thích của bạn.

Thử thách

  1. Đọc đầu vào qua STDINhoặc tương đương và ghi đầu ra qua STDOUThoặc tương đương
  2. Đầu vào hợp lệ là sự kết hợp của chữ hoa và chữ thường tức là khớp \[a-zA-Z]+\
  3. Đầu vào phải được xác thực để xem chuỗi ký tự có thể được hiểu là số La Mã hợp lệ
  4. Nếu đầu vào vượt qua xác thực, đầu ra hợp lệ phải là giải thích thập phân tiếng Ả Rập thấp nhất và khóa được sử dụng tức Aalà được hiểu là 4 {a=5, A=1} không 6 {A=5, a=1} hoặc 9 {a=10, a=1}

Quy tắc số La Mã

  1. Chỉ các chữ cái đại diện cho sức mạnh của mười có thể được lặp lại, tối đa ba lần liên tiếp và tổng cộng bốn lần, ví dụ II III XXXIX

  2. Nếu một hoặc nhiều chữ cái được đặt sau một chữ cái khác có giá trị lớn hơn, hãy thêm số tiền đó

    AAaa   => 22 {A=10, a=1}          (20 + 2 = 22)  
    bbAAaa => 222 {b=100, A=10, a=1}  (200 + 20 + 2 = 222)   
    
  3. Nếu một chữ cái được đặt trước một chữ cái khác có giá trị lớn hơn, hãy trừ đi số tiền đó

    Aa    => 4 {a=5, A=1}                 (5 – 1 = 4)  
    AaA   => 19 {A=10, a=1}               (10 + 10 – 1 = 19)  
    BbBaA => 194 {B=100, b=10, A=5, a=1}  (100 + 100 - 10 + 5 - 1 = 194)  
    

    Một số quy tắc được áp dụng để trừ số tiền từ chữ số La Mã:

    • Chỉ trừ đi sức mạnh của mười tức là 1, 10, 100... không 5, 50, 500...
    • Không có phép trừ kép do đó 18được viết là XVIII không IIXX (10 + 10 - 1 - 1)
    • Đừng trừ một số lớn hơn một số lớn hơn mười lần.
      Bạn có thể trừ 1từ 5 hay 10 nhưng không từ50, 100, 500...

Thí dụ

Input:

Aa  
BAa  
CCCXLVII   
MMMCDVII  
ABADDF  
XVVX  
FAASGSH  
DXCCDA  
AaBbcDEf   

Output:

4 {a=5, A=1}  
14 {B=10, a=5, A=1}  
347 {C=100, L=50, X=10, V=5, I=1}  
347 {M=100, D=50, C=10, V=5, I=1}  
1921 {A=1000, B=100, D=10, F=1}  
'XVVX' failed Roman numeral test  
7191 {F=5000, A=1000, S=100, G=10, H=1}  
'DXCCDA' failed Roman numeral test
4444 {a=5000, A=1000, b=500, B=100, D=50, c=10, f=5, E=1}  

3
@IamOgbz điều này đã trở thành một câu hỏi tuyệt vời nhưng đã thu hút rất nhiều câu hỏi trong các bình luận trên đường đi. Bây giờ bạn đã có đủ danh tiếng, tôi khuyên bạn nên dùng hộp cát . Tôi thấy nó rất hữu ích để nhận được câu hỏi ngay trước khi đăng.
trichoplax

CCCLXVII sẽ không được hiểu là CCCXLVII, mang lại cho 347?
Skyler

@Skyler bạn hoàn toàn đúng, sẽ cập nhật ngay! cảm ơn.
iamogbz

Tôi không thấy bất kỳ hạn chế nào về những giá trị mà các chữ cái riêng lẻ có thể có (và thực sự bạn đề cập đến 20, không phải là giá trị của một chữ số La Mã tiêu chuẩn). Bạn có nghĩa là để nói rằng bất kỳ số nguyên dương có thể được đại diện bởi một chữ số La Mã? Trong trường hợp đó, Aacó giá trị là 1 (A = 1, a = 2).
msh210

@ msh210 vì các chữ cái chỉ có thể được hiểu là Chữ số La Mã, theo sau các giá trị chữ cái riêng lẻ chỉ có thể là lũy thừa 10 hoặc 5 lần lũy thừa 10. 20 chỉ được đề cập liên quan đến việc kết hợp hai chữ số La Mã (và nhấn mạnh rằng IXX = 19 không phải là một phép trừ hợp lệ). Hy vọng rằng sẽ xóa nó cho bạn.
iamogbz

Câu trả lời:


1

Python 2, 415 444 440 419 416 byte

Rốt cuộc, không có nhiều chữ số La Mã. Kịch bản lệnh này tạo ra tất cả chúng và kiểm tra tất cả các hoán vị của đầu vào, sau đó trả về kết quả khớp nhỏ nhất.

a=raw_input()
g=range
b=list(set(a))+[' ']*9
from itertools import*
c=[]
s={}
u=1000
for i in g(10*u):
 t,f=(10*u,9*u,5*u,4*u,u,900,500,400,100,90,50,40,10,9,5,4,1),i;r=""
 for j in g(17):k=i/t[j];r+=('W MW Q MQ M CM D CD C XC L XL X IX V IV I').split()[j]*k;i-=t[j]*k
 s[r]=f
for i in permutations(b[:9]):
 r=''
 for j in a:r+='IVXLCMQWE'[i.index(j)]
 if r in s:c+=[s[r]]
print c and min(c)or'%s failed Roman numeral test'%a

Đó là một câu trả lời tốt cho thách thức như bây giờ. Nhưng trong cuộc trò chuyện bình luận bị xóa sổ sớm, có gợi ý rằng hệ thống này (không có thật) diễn ra sau M = 1000, có các biểu tượng cho 5k, 10k, v.v. Nhìn vào ví dụ đầu tiên ở trên cùng: {A = 10, I = 1, X = 5, ... Z = 1000000} được quyết định bởi cách giải thích của bạn
edc65

.. và ví dụ cuối cùng, a = 5000 ...
edc65

Tôi đã cập nhật nó để xử lý tất cả các trường hợp thử nghiệm nhất định. Tôi nghi ngờ cách tiếp cận này có thể được kéo dài hơn 10.000 vì phải mất thời gian O (n!) Về số chữ số La Mã.
Skyler

@Skyler các trường hợp thử nghiệm không đầy đủ. Chương trình sẽ xử lý tất cả các hoán vị có thể có của các đầu vào hợp lệ có thể được hiểu theo các quy tắc số La Mã, với ưu tiên cho các số thấp hơn trong các trường hợp mơ hồ. Ngoài ra, mã của bạn không thể xử lý liên kết
iamogbz

Không phải import itertools as ivà sau đó i.permutationsngắn hơn?
mèo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.