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


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.