แปลงตัวเลขโรมันที่เข้ารหัสได้เป็นทศนิยมอารบิก


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. มีเพียงตัวอักษรที่เป็นตัวแทนของพลังสิบสามารถทำซ้ำได้สูงสุดสามครั้งติดต่อกันและรวมสี่ครั้งเช่น 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)
    • อย่าลบตัวเลขจากตัวเลขที่มากกว่าสิบครั้ง
      คุณสามารถลบ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 สิ่งนี้ได้กลายเป็นคำถามที่ยอดเยี่ยม แต่ดึงดูดคำถามจำนวนมากในความคิดเห็นไปพร้อมกัน ตอนนี้คุณมีชื่อเสียงพอผมขอแนะนำให้Sandbox ฉันพบว่ามันมีประโยชน์มากสำหรับการรับคำถามก่อนโพสต์
trichoplax

CCCLXVII จะไม่ถูกตีความเป็น CCCXLVII ซึ่งให้ 347 หรือไม่
Skyler

@Skyler คุณพูดถูกจะอัปเดตทันที! ขอบคุณ
iamogbz

ฉันไม่เห็นข้อ จำกัด ใด ๆ เกี่ยวกับค่าที่ตัวอักษรแต่ละตัวมี (และแน่นอนคุณพูดถึง 20 ซึ่งไม่ใช่ค่าของเลขโรมันมาตรฐาน) คุณหมายถึงจะบอกว่าเลขจำนวนเต็มบวกใด ๆสามารถแทนด้วยเลขโรมันได้หรือไม่? ในกรณีนั้นAaมีค่า 1 (A = 1, a = 2)
msh210

@ msh210 เป็นตัวอักษรที่สามารถตีความได้ว่าเป็นตัวเลขโรมันมันตามมาว่าค่าตัวอักษรแต่ละตัวสามารถเป็นพลังของ 10 หรือ 5 เท่าพลังของ 10 10. 20 ถูกกล่าวถึงเฉพาะในการรวมสองตัวเลขโรมัน (และเน้นที่ IXX = 19 ไม่ใช่การลบที่ถูกต้อง) หวังว่าจะล้างมันให้คุณ
iamogbz

คำตอบ:


1

Python 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 = 1,000 โดยมีสัญลักษณ์ 5k, 10k และอื่น ๆ ดูตัวอย่างแรกที่ด้านบน: {A = 10, I = 1, X = 5, ... Z = 1000000} ตัดสินโดยการตีความของคุณ
edc65

.. และตัวอย่างสุดท้ายคือ a = 5000 ...
edc65

ฉันอัปเดตเพื่อจัดการกรณีทดสอบที่ให้มาทั้งหมด ฉันสงสัยว่าวิธีการนี้สามารถขยายได้เกิน 10,000 รายการเนื่องจากใช้เวลาO (n!)กับจำนวนหลักโรมัน
Skyler

@Skyler กรณีทดสอบไม่ครบถ้วนสมบูรณ์ โปรแกรมควรจัดการการเรียงสับเปลี่ยนที่เป็นไปได้ทั้งหมดของอินพุตที่ถูกต้องซึ่งสามารถตีความได้ตามกฎเลขโรมันโดยมีการกำหนดหมายเลขต่ำกว่าในกรณีที่ไม่ชัดเจน รหัสของคุณไม่สามารถจัดการกับกรณีทดสอบล่าสุดลิงก์
iamogbz

ไม่ได้เป็นimport itertools as iแล้วi.permutationsลงเรื่อย ๆ ?
แมว
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.