암호화 된 로마 숫자를 아라비아 소수로 변환


16

일련의 문자를 로마 숫자로 해석하는 알고리즘을 작성하십시오. (아래 로마 숫자 규칙 참조)

각 고유 문자에는 일치하는 아라비아 소수 값이 있으며 최대 값은 없습니다. 그러나 사전에 열쇠가 없으므로 {A=10, I=1, X=5, ... Z=1000000}해석에 의해 결정됩니다.

도전

  1. 통해 입력 읽기 STDIN 을 통해 또는 동등 및 기록 출력 STDOUT또는 이와 동등한
  2. 유효한 입력은 대문자와 소문자의 조합입니다. \[a-zA-Z]+\
  3. 문자 순서가 유효한 로마 숫자로 해석 될 수 있는지 확인하려면 입력을 확인해야합니다.
  4. 입력이 유효성 검사를 통과하면, 유효 출력이 가장 낮은 아랍어 진수 해석해야하며, 키, 즉 사용 Aa으로 해석 4 {a=5, A=1} 하지 6 {A=5, a=1} 나 9 {a=10, a=1}

로마 숫자 규칙

  1. 10의 거듭 제곱을 나타내는 문자 만 연속적으로 최대 3 번, 총 4 번 반복 할 수 있습니다. II III XXXIX

  2. 하나 이상의 문자가 더 큰 다른 문자 뒤에 놓인 경우 해당 금액을 추가하십시오

    AAaa   => 22 {A=10, a=1}          (20 + 2 = 22)  
    bbAAaa => 222 {b=100, A=10, a=1}  (200 + 20 + 2 = 222)   
    
  3. 문자가 더 큰 다른 문자 앞에 놓이면 해당 금액을 뺍니다.

    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)  
    

    로마 숫자에서 금액을 빼는 데 몇 가지 규칙이 적용됩니다.

    • 만 빼기 열 즉의 힘 1, 10, 100... 없는 5, 50, 500...
    • 없음을 두 번 뺄셈 따라서 18으로 기록되지 않습니다 XVIII 하지 IIXX (10 + 10 - 1 - 1)
    • 10 배 이상 큰 숫자를 빼지 마십시오.
      당신은 뺄 수 1에서 5 또는 10 하지만 하지 에서50, 100, 500...

예

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 이것은 훌륭한 질문으로 바뀌었지만 그 과정에서 의견에 많은 질문을 끌었습니다. 평판이 충분하므로 샌드 박스를 권장합니다 . 게시 직전에 질문을받는 데 매우 유용합니다.
— trichoplax

CCCLXVII가 CCCXLVII로 해석되어 347을 제공하지 않습니까?
— Skyler

@Skyler 당신은 절대적으로 맞아, 지금 업데이트됩니다! 감사.
— iamogbz

개별 문자가 가질 수있는 값에 대한 제한은 없습니다 (실제로 표준 로마 숫자의 값이 아닌 20을 언급합니다). 당신은 말을 의미합니까 어떤 양의 정수는 로마 숫자로 표현 될 수있다? 이 경우 Aa값은 1입니다 (A = 1, a = 2).
— msh210

문자는 로마 숫자로만 해석 될 수 있기 때문에 @ msh210이므로 개별 문자 값은 10의 거듭 제곱 10의 거듭 제곱 만 될 수 있습니다. 20은 두 개의 로마 숫자를 결합하는 것과 관련하여 언급되었습니다 (그리고 IXX = 19는 유효한 빼기가 아닙니다). 희망이 당신을 위해 그것을 정리합니다.
— iamogbz

답변:


1

파이썬 2, 415 444 440 419 416 바이트

결국 로마 숫자가 많지는 않습니다. 이 스크립트는 이들을 모두 작성하고 입력의 모든 순열을 확인한 다음 가장 작은 일치 항목을 리턴합니다.

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

그것은 지금처럼 도전에 대한 좋은 대답입니다. 그러나 초기에 사라진 주석 대화 에서이 실제 시스템은 M = 1000 후에 5k, 10k 등의 기호가있는 이후에 진행된다는 것이 암시되었습니다. 상단의 첫 번째 예를 살펴보십시오. {A = 10, I = 1, X = 5, ... Z = 1000000}은 해석에 의해 결정됩니다
— edc65

.. 그리고 마지막 예, a = 5000 ...
— edc65

주어진 모든 테스트 사례를 처리하도록 업데이트했습니다. 로마 자릿수에 O (n!) 시간 이 걸리므로이 방법을 10,000 이상으로 확장 할 수있을 것 같습니다 .
— Skyler

@Skyler 테스트 사례가 완전하지는 않습니다. 이 프로그램은 로마 숫자 규칙에 따라 해석 될 수있는 유효한 입력의 모든 순열을 처리해야하며 모호한 경우 낮은 숫자를 선호합니다. 또한 코드는 마지막 테스트 케이스 처리 할 수있는 링크를
— iamogbz

아닌가 import itertools as i하고 i.permutations짧은?
— cat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.