एक रोमन अंक कैलकुलेटर बनाएं


18

रोमन अंकों के लिए एक बुनियादी कैलकुलेटर बनाएँ।

आवश्यकताएँ

  • समर्थन +, -, *,/
  • इनपुट और आउटपुट में प्रति प्रतीक केवल एक सबट्रैक्टर उपसर्ग की उम्मीद होनी चाहिए (यानी 3 IIVइसलिए नहीं हो सकती क्योंकि Iपहले दो हैं V)
  • न्यूनतम समर्थन आधुनिक मानक सम्मेलनों में इनपुट और आउटपुट चाहिए में घटाव सिद्धांत की हैंडलिंग, जिसमें दस में से केवल शक्तियों बड़ी संख्या में (जैसे से घटाया जाता है I, X, Cके लिए आवश्यक हैं subtractors लेकिन नहीं V, L,D ) और घटाव की तुलना में अधिक एक नंबर से कभी नहीं किया गया है 10x सबट्रैक्टर (उदाहरण के IXलिए समर्थित होना चाहिए लेकिन ICआवश्यक नहीं है)।
  • मूल्य के क्रम में सबसे बड़े (यानी 19 =) से शुरू करते हुए इनपुट और आउटपुट को दाएं पर छोड़ देना चाहिए XIX नहीं IXX, 10 9 से बड़ा है)
  • बाएं से दाएं, कोई ऑपरेटर पूर्वता नहीं, जैसे कि आप हाथ कैलकुलेटर का उपयोग कर रहे थे।
  • 1-4999 के बीच पूरे सकारात्मक संख्या इनपुट / आउटपुट का समर्थन करता है (V̅ की कोई आवश्यकता नहीं)
  • कोई लाइब्रेरी जो आपके लिए रोमन अंक रूपांतरण नहीं करती है

आप के लिए तय करने के लिए

  • मामले की संवेदनशीलता
  • रिक्त स्थान या इनपुट पर कोई स्थान नहीं
  • अगर आपको दशमलव आउटपुट मिलता है तो क्या होता है। ट्रंकट, कोई जवाब नहीं, त्रुटि, आदि।
  • आउटपुट के लिए क्या करें जिसे आप संभाल नहीं सकते। मुद्रित होने के लिए बड़े होने की संख्या या संख्या।
  • न्यूनतम आवश्यकता की तुलना में घटाव सिद्धांत के अधिक उदार उपयोग का समर्थन करना है या नहीं।

अतिरिक्त श्रेय

  • -50 - 99999 तक या इससे बड़ा हैंडल। प्रतीकों में एक विनकुलम शामिल होना चाहिए

नमूना इनपुट / आउटपुट

XIX + LXXX                 (19+80)
XCIX

XCIX + I / L * D + IV      (99+1/50*500+4)
MIV

सबसे छोटा कोड जीतता है।


(99 + 1/50 * 500 + 4) = (99 + 10 + 4) = 113, लेकिन आपका नमूना इनपुट / आउटपुट कहता है कि यह MIV (1004) है।
विक्टर स्टाफ़ुसा

1
@ विक्टर - सख्त बाएं से दाएं ऑपरेशन - कोई पूर्ववर्ती नियम नहीं है - इसलिए 99 + 1/50 * 500 + 4 की गणना की जानी चाहिए ((((99 + 1) / 50) * 500) + 4)

क्या हैंडलिंग संख्या IM = 999आवश्यक है?
केंडल फ्रे

@KendallFrey मुझे उम्मीद है कि आप इनपुट कर सकते हैं IM। चाहे आउटपुट हो IMया CMXCIX999 के लिए आप पर निर्भर है। दोनों आवश्यकताओं को फिट करते हैं।
डैनी

2
आधुनिक रोमन अंकों के उपयोग के लिए IM गैर-मानक है। आमतौर पर यह परिमाण के प्रत्येक क्रम (4, 9, 40, 90, 400, 900, आदि) के केवल 4 वें और 9s है जो घटाव द्वारा किया जाता है। 1999 के लिए, MCMXCIX विहित होगा, एमआईएम नहीं ... उस वर्ष से किसी भी फिल्म का क्रेडिट देखें। अन्यथा, यह कहाँ समाप्त होता है? क्या हमें 45 के लिए वीएल जैसे अन्य गैर-मानक घटाव का समर्थन करने की भी उम्मीद है? क्या C के ऊपर एक vinculum के साथ IC को बोनस के लिए 99999 के रूप में समर्थित होना चाहिए?
जोनाथन वान मैटर

जवाबों:


9

जावास्क्रिप्ट (ईएस 6), 238

c=s=>{X={M:1e3,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1}
n=eval('W='+s.replace(/[\w]+/g,n=>(o=0,n.replace(/[MDLV]|C[MD]?|X[CL]?|I[XV]?/g,d=>o+=X[d]),
o+';W=W')));o='';for(i in X)while(n>=X[i])o+=i,n-=X[i];return o}

उपयोग:

c("XIX + LXXX")
> "XCIX"
c('XCIX + I / L * D + IV')
> "MIV"

एनोटेट संस्करण:

/**
 * Process basic calculation for roman numerals.
 * 
 * @param {String} s The calculation to perform
 * @return {String} The result in roman numerals
 */
c = s => {
  // Create a lookup table.
  X = {
    M: 1e3, CM: 900, D: 500, CD: 400, C: 100, XC: 90, 
    L: 50,  XL: 40,  X: 10,  IX: 9,   V: 5,   IV: 4, I: 1
  };
  // Do the calculation.
  // 
  // The evaluated string is instrumented to as below:
  //   99+1/50*500+4 -> W=99;W=W+1;W=W/50;W=W*500;W=W+4;W=W
  //                 -> 1004
  n = eval('W=' + s.replace(
    // Match all roman numerals.
    /[\w]+/g,
    // Convert the roman number into an integer.
    n => (
      o = 0,
      n.replace(
        /[MDLV]|C[MD]?|X[CL]?|I[XV]?/g,
        d => o += X[d]
      ),
      // Instrument number to operate left-side operations.
      o + ';W=W'
    )
  ));

  // Convert the result into roman numerals.
  o = '';
  for (i in X)
    while (n >= X[i])
      o += i,
      n -= X[i];

  // Return calculation result.
  return o
}

9

टी-एसक्यूएल, 1974 - 50 = 1924 बाइट्स

मुझे पता है कि एसक्यूएल में गोल्फिंग एक रेत की कील के साथ 18 छेदों के साथ खेलने के बराबर है, लेकिन मैंने इस एक की चुनौती को दोहराया और मुझे लगता है कि मैं कुछ दिलचस्प तरीके से करने में कामयाब रहा।

यह इनपुट और आउटपुट दोनों के लिए विनकुलम का समर्थन करता है। मैंने इसका प्रतिनिधित्व करने के लिए एक अनुगामी टिल्ड का उपयोग करने के सम्मेलन को अपनाया, इसलिए V ~ 5000 है, X ~ 10000 है, आदि। यह मानक आधुनिक रोमन संख्या उपयोग के अनुसार 399,999 तक आउटपुट को भी संभालना चाहिए। उसके बाद, यह INT की समर्थित सीमा में किसी भी चीज़ के आंशिक रूप से गैर-मानक रोमन एन्कोडिंग करेगा।

क्योंकि यह सभी पूर्णांक गणित है, किसी भी गैर पूर्णांक परिणाम अनुमानित रूप से गोल हैं।

DECLARE @i VARCHAR(MAX)
SET @i='I+V*IV+IX*MXLVII+X~C~DCCVI'
SELECT @i

DECLARE @t TABLE(i INT IDENTITY,n VARCHAR(4),v INT)
DECLARE @u TABLE(n VARCHAR(50),v INT)
DECLARE @o TABLE(n INT IDENTITY,v CHAR(1))
DECLARE @r TABLE(n INT IDENTITY,v INT,r VARCHAR(MAX))
DECLARE @s TABLE(v INT,s VARCHAR(MAX))
DECLARE @p INT,@x VARCHAR(4000)='SELECT ',@j INT=1,@m INT,@y INT,@z VARCHAR(2),@q VARCHAR(50)='+-/*~]%'
INSERT @t(n,v) VALUES('i',1),('iv',4),('v',5),('ix',9),('x',10),('xl',50),('l',50),('xc',90),('c',100),('cd',400),('d',500),('cm',900),('m',1000),('mv~',4000),('v~',5000),('mx~',9000),('x~',10000),('x~l~',40000),('l~',50000),('x~c~',90000),('c~',100000)
INSERT @u VALUES('%i[^i'+@q,-2),('%v[^vi'+@q,-10),('%x[^xvi'+@q,-20),('%l[^lxvi'+@q,-100),('%c[^clxvi'+@q,-200),('%d[^dclxvi'+@q,-1000),('%mx~%',-2010),('%x~l~%',-20060),('%x~c~%',-20110)
WHILE PATINDEX('%[+-/*]%', @i)!=0
BEGIN
    SET @p=PATINDEX('%[+-/*]%', @i)
    INSERT @o(v) SELECT SUBSTRING(@i,@p,1)
    INSERT @r(r) SELECT SUBSTRING(@i,1,@p-1)
    SET @i=STUFF(@i,1,@p,'')
END 
INSERT @r(r) SELECT @i
UPDATE r SET v=COALESCE(q.v,0) FROM @r r LEFT JOIN (SELECT r.r,SUM(u.v)v FROM @u u JOIN @r r ON r.r LIKE u.n GROUP BY r.r)q ON q.r=r.r
UPDATE r SET v=r.v+q.v FROM @r r JOIN (SELECT r.n,r.r,SUM((LEN(r.r)-LEN(REPLACE(r.r,t.n,REPLICATE(' ',LEN(t.n)-1))))*t.v) v FROM @r r JOIN @t t ON CHARINDEX(t.n,r.r) != 0 AND (LEN(t.n)=1 OR (LEN(t.n)=2 AND RIGHT(t.n,1)='~')) GROUP BY r.n,r.r) q ON q.r=r.r AND q.n = r.n
SELECT @m=MAX(n) FROM @o
SELECT @x=@x+REPLICATE('(',@m)+CAST(v AS VARCHAR) FROM @r WHERE n=1
WHILE @j<=@m
BEGIN
    SELECT @x=@x+o.v+CAST(r.v AS VARCHAR)+')'
    FROM @o o JOIN @r r ON r.n=o.n+1 WHERE o.n=@j
    SET @j=@j+1
END 
INSERT @s(v,s) EXEC(@x+',''''')
UPDATE @s SET s=s+CAST(v AS VARCHAR(MAX))+' = '
SET @j=21
WHILE @j>0
BEGIN
    SELECT @y=v,@z=n FROM @t WHERE i = @j
    WHILE @y<=(SELECT v FROM @s)
    BEGIN
        UPDATE @s SET v=v-@y,s=s+@z
    END  
    SET @j=@j-1
END
SELECT @x+' = '+UPPER(s) FROM @s

मैं अभी भी सेट-आधारित समाधान के साथ छेड़छाड़ कर रहा हूं, जिसमें से कुछ लूपिंग को बदलने के लिए है जो बाइट की संख्या को कम कर सकते हैं और मुहावरेदार एसक्यूएल का एक अधिक सुरुचिपूर्ण उदाहरण हो सकते हैं। वहाँ भी कुछ बाइट्स प्राप्त करने के लिए एक न्यूनतम करने के लिए टेबल उपनाम का उपयोग कम किया जा सकता है। लेकिन जैसा कि यह अनिवार्य रूप से इस भाषा में अप्राप्य है, मैं ज्यादातर अपने डॉन क्विक्सोट संगठन को दिखाने के लिए यहां हूं। :)

शीर्ष पर @i का चयन करें इनपुट दोहराता है:

I+V*IV+IX*MXLVII+X~C~DCCVI

और अंतिम रिटर्न पर चयन करें:

SELECT (((((1+5)*4)+9)*1047)+90706) = 125257 = C~X~X~V~CCLVII

और आप इसे इस SQLFiddle पर खुद का परीक्षण कर सकते हैं

और मैं यह कैसे काम करता है पर कुछ टिप्पणी जोड़ने के लिए वापस आ जाएगा, क्योंकि यदि आप शैक्षिक मूल्य पर इसका फायदा उठाने के लिए नहीं जा रहे हैं तो स्पष्ट रूप से खोने का जवाब क्यों दें?


2

जावास्क्रिप्ट - 482 476 अक्षर

String.prototype.m=String.prototype.replace;eval("function r(a){return a>999?'Mk1e3j899?'CMk900j499?'Dk500j399?'CDk400j99?'Ck100j89?'XCk90j49?'Lk50j39?'XLk40j9?'Xk10j8?'IX':a>4?'Vk5j3?'IV':a>0?'Ik1):''}".m(/k/g,"'+r(a-").m(/j/g,"):a>"));s=prompt();h=s.match(/\w+/gi);for(k in h)s=s.m(h[k],eval(eval("'0'+h[k].m(/IVu4pIXu9pXLu40pXCu90pCDu400pCMu900pMu1000pDu500pCu100pLu50pXu10pVu5pIu1')".m(/u/g,"/g,'+").m(/p/g,"').m(/")))+")");for(k in h)s="("+s;alert(r(Math.floor(eval(s))))

नमूना इनपुट / आउटपुट काम करता है:

XIX + LXXX -> XCIX
XCIX + I / L * D + IV -> MIV

यह बड़ी संख्या को भी बुरी तरह से संभालता है:

MMM+MMM -> MMMMMM
M*C -> MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

और यह स्वीकार करता है, लेकिन रिक्त स्थान भी आवश्यक नहीं है।

लेकिन, जब से मैं गोल्फ खेल रहा था, तब से कुछ समस्याएं हैं:

  • यदि इनपुट अच्छी तरह से बना है तो यह मान्य नहीं है। यदि इनपुट अच्छी तरह से नहीं बना है, तो व्यवहार अपरिभाषित है (और व्यवहार में यह बहुत ही विचित्र और अजीब है)।
  • यह आउटपुट पर अंश संख्याओं को काटता है (लेकिन यह उनके साथ मध्यवर्ती गणना करने में सक्षम है)।
  • यह वास्तव में निष्कासन समारोह का दुरुपयोग करता है।
  • यह नकारात्मक संख्या को संभालने का प्रयास नहीं करता है।
  • यह केस-संवेदी है।

यह वैकल्पिक संस्करण 99999 तक 5000 से अधिक संख्या को संभालता है, लेकिन इसमें 600 598 584 वर्ण हैं:

String.prototype.m=String.prototype.replace;eval("function r(a){return a>8zz?'XqCqk9e4j4zz?'Lqk5e4j3zz?'XqLqk4e4jzz?'Xqk1e4j89z?'IqXqk9e3j49z?'Vqk5e3j9z?'Mk1e3j8z?'CMk900j4z?'Dk500j3z?'CDk400jz?'Ck100j89?'XCk90j49?'Lk50j39?'XLk40j9?'Xk10j8?'IX':a>4?'Vk5j3?'IV':a>0?'Ik1):''}".m(/k/g,"'+r(a-").m(/j/g,"):a>").m(/q/g,"\u0305").m(/z/g,"99"));s=prompt();h=s.match(/\w+/gi);for(k in h)s=s.m(h[k],eval(eval("'0'+h[k].m(/IVu4pIXu9pXLu40pXCu90pCDu400pCMu900pMu1000pDu500pCu100pLu50pXu10pVu5pIu1')".m(/u/g,"/g,'+").m(/p/g,"').m(/")))+")");for(k in h)s="("+s;console.log(r(Math.floor(eval(s))))

मुझे नहीं लगता कि -20 लागू होता है:
सीन

यहां @SeanCheshire से सहमत हैं। बड़ी संख्या में इरादे को संभालने के लिए अंक के ऊपर एक विनकुलम जोड़ना है जो सामान्य रूप से 1000 गुना मूल्य है। हो सकता है कि यह -20 से बड़ा होना चाहिए, ताकि यह लोगों के लिए प्रयास करने लायक बन जाए।
डैनी

1
@ डैनी मैंने एक संस्करण जोड़ा, जो विनकुलस को संभालता है, लेकिन यह 116 वर्णों में कोड बढ़ाता है।
विक्टर स्टाफ़ुसा

2

जावास्क्रिप्ट 479 361 348 278 253

303 अक्षर - 1 मिलियन तक की संख्या के समर्थन के लिए 50, विनकुलम समर्थन के साथ पूरा:

function p(s){s=s[r](/(^|[*\/+-])/g,"0;s$1=");for(i in v){f=R("\\b"+i);while(f.test(s))s=s[r](f,v[i]+"+")}eval(s+"0");h="";for(i in v)while(s>=v[i]){h+=i;s-=v[i]}return h}v={M̅:1e6,D̅:5e5,C̅:1e5,L̅:5e4,X̅:1e4,V̅:5e3,M:1e3,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1};r="replace";R=RegExp

उपयोग: p(text)उदाहरण के लिए, p('XIX + LXXX')रिटर्न XCIX

व्याख्यात्मक टिप्पणियों के साथ कोड:

// Array mapping characters to values
v={M¯:1e6,D¯:5e5,C¯:1e5,L¯:5e4,X¯:1e4,V¯:5e3,M:1e3,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1};
// Shortcut for String.replace
r='replace';
R=RegExp;

// The heart of the program
function p(s) {
    // Replace operators with ";s+=", ";s-=", and so on
    s=s[r](/(^|[*\/+-])/g,'0;s$1=');
    // Loop over the character map and replace all letters with numbers
    for(i in v){
        f=R('\\b'+i);
        while(f.test(s))
            s=s[r](f, v[i]+'+')
    }
    eval(s+'0');
    // Set up our return string
    h='';
    // Replace digits with characters
    for(i in v)
        while(s>=v[i]) {
            h+=i;
            s-=v[i];
        }
    return h;
}

यह दिए गए नमूनों के लिए और मेरे द्वारा आजमाए गए अन्य सभी के लिए काम करता है। उदाहरण:

XIX + LXXX = XCIX
XCIX + I / L * D + IV = MIV
XL + IX/VII + II * XIX = CLXXI
CD + C + XL + X + I = DLI
M̅ + I = M̅I
MMMM + M = V̅

2

रूबी 2.1, 353 (और कई अन्य पुनरावृत्तियों) , 295 - 50 = 245

विनकुलम हैंडलिंग ~ 23 वर्ण जोड़ता है।

यह इनपुट में "आईएल" या "वीएम" को संभालता है, और नकारात्मक पर त्रुटि के बिना विफल हो जाता है (उच्च ints) या दशमलव (ट्रंकट्स), या किसी भी रिक्त स्थान पर जाता है। अब एक नकारात्मक पहली संख्या को भी संभालता है (हालांकि यदि कुल नकारात्मक है, तो यह अभी भी खराब रूप से विफल है)। यह भी खराब रूप से विफल होता है यदि आप * या / या यदि परिणाम 4 मिलियन या उससे अधिक के साथ शुरू करते हैं।

"हाथ-कैलकुलेटर" कार्यक्षमता के लिए ऑब्जेक्ट # भेजें का उपयोग करता है।

m=%w{I V X L C D M V̅ X̅ L̅ C̅ D̅ M̅};n=m.zip((0..12).map{|v|(v%2*4+1)*10**(v/2)}).to_h
d=0
gets.scan(/([-+*\/])?([A-Z̅]+)/){|o,l|f=t=0
l.scan(/.̅?/){t-=2*f if f<v=n[$&]
t+=f=v}
d=d.send o||:+,t}
7.downto(1){|v|z=10**v
y=(d%z)*10/z
q,w,e=m[v*2-2,3]
$><<(y>8?q+e : y<4?q*y : y<5?q+w : w+q*(y-5))}

Ungolfed:

m=%w{I V X L C D M V̅ X̅ L̅ C̅ D̅ M̅} # roman numerals
n=m.zip((0..12).map{|v|(v%2*4+1)*10**(v/2)}).to_h # map symbols to values
d=0
gets. # get input and...
  scan(/([-+*\/])?([A-Z̅]+)/) { |l,o|  # for each optional operator plus number
    f=t=0
    l.scan(/.̅?/){                           # read the number in one letter at a time
      t -= 2 * f if f < (v=n[$&])           # if the number's greater than the prev, subtract the prev twice since you already added it
      t += (f = v)                          # add this, and set prev to this number
    }
    d = d.send((o || :+), t)                # now that we've built our number, "o" it to the running total (default to +)
}
7.upto(1) { |v|                        # We now print the output string from left to right
  z = 10**v                            # z = [10, 100, 1000, etc.]
  y = (d%z)*10/z                       # if d is 167 and z is 100, y = 67/10 = 6 
  q,w,e = m[v*2-2,3]                   # q,w,e = X, L, C
  $><< (                               # print: 
    y>8 ? q+e :                        # if y==9,    XC
      y<4 ? q*y :                      # if y<4,     X*y
        y>3 ? q+w :                    # if y==4,    XL
          q*(y-5)                      # else,       L + X*(y-5)
  )
}

2

अजगर 2 - 427 418 404 401 396 395 392 अक्षर

मानक इनपुट से पढ़ता है। यह केवल अपरकेस को संभालता है (8 अतिरिक्त वर्णों की कीमत पर इसे असंवेदनशील बना सकता है) और रिक्त स्थान की आवश्यकता होती है। कोई मान्यता नहीं है - मैंने यह देखने के लिए परीक्षण नहीं किया है कि यह विभिन्न मामलों में कैसे टूटता है। हालाँकि, यह वीसी = 95 जैसी संख्याओं को संभालता है।

N=['?M','DC','LX','VI'];t=0;o='+'
for q in raw_input().split():
 if q in"+-*/":o=q;continue
 n=s=0;X=1
 for l in q:
  x=''.join(N).find(l);v=(5-x%2*4)*10**(3-x/2)
  if X<x:n+=s;s=v;X=x
  elif X>x:n+=v-s;s=0
  else:n+=v+s;s=0
 exec"t"+o+"=n+s"
r=t/1000*'M'
for p,d in enumerate("%04d"%(t%1e3)):
 i="49".find(d);g=N[p]
 if i<0:
  if'4'<d:r+=g[0]
  r+=int(d)%5*g[1]
 else:r+=g[1]+N[p-i][i]
print r

और अनगुल्ड संस्करण:

# Numerals grouped by powers of 10
N = ['?M','DC','LX','VI']
# Start with zero plus whatever the first number is
t = 0
o = '+'
for q in raw_input().split():
    if q in "+-*/":
        # An operator; store it and skip to the next entry
        o = q
        continue
    # n holds the converted Roman numeral, s is a temp storage variable
    n = s = 0
    # X stores our current index moving left-to-right in the string '?MDCLXVI'
    X = 1
    for l in q:
        # x is the index of the current letter in '?MDCLXVI'
        x = ''.join(N).find(l)
        # Calculate the value of this letter based on x
        v = (5 - x%2 * 4) * 10 ** (3 - x/2)
        if X < x:
            # We're moving forward in the list, e.g. CX
            n += s      # Add in any previously-stored value
            s = v       # Store this value in case we have something like CXL
            X = x       # Advance the index
        elif X > x:
            # Moving backward, e.g. XC
            n += v - s  # Add the current value and subtract the stored one
            s=0
        else:
            # Same index as before, e.g. XX
            n += v + s  # Add the current value and any stored one
            s = 0
    # Update total using operator and value (including leftover stored value
    # if any)
    exec "t" + o + "=n+s"

# Now convert the answer back to Roman numerals
# Special-case the thousands digit
r = t / 1000 * 'M'
# Loop over the number mod 1000, padded with zeroes to four digits (to make
# the indices come out right)
for p, d in enumerate("%04d" % (t % 1e3)):
    i = "49".find(d)
    g = N[p]
    if i < 0:
        # i == -1, thus d isn't '4' or '9'
        if '4' < d:
            # >= 5, so add the 5's letter
            r += g[0]
        # ... plus (digit % 5) copies of the 1's letter
        r += int(d) % 5 * g[1]
    else:
        # If it's a 4 or 9, add the 1's letter plus the appropriate
        # larger-valued letter
        r += g[1] + N[p-i][i]
print r

मुझे लगता है कि पर्ल बेहतर होगा, लेकिन मैं इसके बारे में पर्याप्त नहीं जानता। कोड गोल्फ में एक पहली वार के लिए, हालांकि, मैं इस बारे में बहुत अच्छा महसूस करता हूं।


1

PHP - 549 525 524 520 बाइट्स

कुछ भी अभिनव नहीं है: ऑपरेटरों को बाएं से दाएं वरीयता सुनिश्चित करने के लिए सामान्य करता है, रोमन को दशमलव में परिवर्तित करता है, evalकथन पर चलता है , जैसे XCIX + I / L * D + IV रिटर्न की तरह कुछ में परिवर्तित हो जाता है (और ((+90 +9) + (+1)) / (+50)) * (+500)) + (+4)); , फिर दशमलव को रोमन में वापस कनवर्ट करता है।

  • अंतिम परिणामों को काट दिया जाता है
  • 1 से कम जवाब वापस आते हैं
  • गलत इनपुट दिए जाने पर परिणाम अपरिभाषित होते हैं
$f='str_replace';$g='str_split';$c=array('M'=>1e3,'CM'=>900,'D'=>500,'CD'=>400,'C'=>100,'XC'=>90,'L'=>50,'XL'=>40,'X'=>10,'IX'=>9,'V'=>5,'IV'=>4,'I'=>1);$j='['.$f(array('+','-','*','/'),array('])+[','])-[','])*[','])/['), $argv[1]).'])';$j=str_repeat('(',substr_count($j,')')).$j;$j=$f('[','(',$j);$j=$f(']',')',$j);foreach($g('IVIXXLXCCDCM',2)as$w)$j=$f($w,'+'.$c[$w],$j);foreach($g('IVXLCDM')as$w)$j=$f($w,'+'.$c[$w],$j);$k=eval('return '.$j.';');$l='';foreach($c as$a=>$b){while($k>=$b){$l.=$a;$k-=$b;}}print$l."\n";

जैसे

$ php roman.php 'XCIX + I / L * D + IV' — test case
MIV                                     — 1004

$ php roman.php 'XXXII * LIX'           — 32 × 59
MDCCCLXXXVIII                           — 1888

0

पायथन - 446 बाइट्स

इसमें काफी सुधार किया जा सकता था। मुझे लगा कि मुझे पायथन का उपयोग करके पहला स्विंग लेना है। यह पहली पास पर 3 चीजें करता है

  1. संख्या और ऑपरेटरों को टोकन देता है
  2. संख्याओं का मूल्यांकन करता है, और xसभी संभावित संयोजनों को शामिल करने के लिए प्रतीक तालिका को बढ़ाता है (भले ही उनका उपयोग न किया गया हो)। उदाहरण के लिए, जबकि XIXलेक्स किया जा रहा है, के आंशिक मान "X":10, "XI":11और "XIX":19प्रतीक तालिका में जोड़े जाते हैं
  3. बाएं से दाएं मूल्यांकन को लागू करने के लिए नेस्टेड पैरेंस सम्मिलित करता है

अंत में, यह evalमूल स्ट्रिंग (अतिरिक्त पैरा के अलावा) पर कॉल करता है और इसे प्रतीक तालिका देता है।

तब मैं सिर्फ रोमन को पूर्णांक में बदलने के लिए एक ज्ञात समाधान में चिपकाया गया था, क्योंकि मैंने इस पर काफी लंबे समय तक काम किया था ... कृपया सुधार करने के लिए स्वतंत्र महसूस करें ताकि मैं कुछ नया सीखूं :)

मीटर = ज़िप ((1000,900,500,400,100,90,50,40,10,9,5,4,1),
( 'M', 'मुख्यमंत्री', 'डी', 'सीडी', 'सी', 'XC', 'एल', 'एक्स्ट्रा लार्ज', 'एक्स', 'नौवीं', 'वी', 'चतुर्थ', ' मैं'))
डीआईटी डिटेट:
 एक्स = { 'एम': 1e3, 'डी': 500, 'सी': 100, 'एल': 50, 'एक्स': 10, 'वी': 5, 'मैं': 1}; y = [] ; z = ''; एक = '0'; s = '+' + रों
 ग में s.upper के लिए ():
  यदि x में c:
   z + = ग; y.append (एक्स [सी])
   अगर len (y)> 1and y [-1]> y [-2]: y [-2] * = - 1
   एक्स [z] = राशि (y)
  elif c में "+ / * -": a = '(' + a + z + ')' + c; y = = []; z = ';
 a + = z; मैं = eval (a, x); r = ''
 n के लिए, c in m: d = int (i / n); r + = c * d; i- = n * d
 वापसी आर


प्रिंट डिट ("XIX + LXXX")
प्रिंट डिट ("XCIX + I / L * D + IV")
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.