Erstellen Sie einen Taschenrechner mit römischen Zahlen


18

Erstellen Sie einen Basisrechner für römische Ziffern.

Bedarf

  • Unterstützt +, -, *,/
  • Eingabe und Ausgabe sollten nur ein Subtrahiererpräfix pro Symbol erwarten (dh 3 kann nicht sein, IIVweil es zwei Idavor gibt V)
  • Die Handhabung des Subtraktion Prinzips in Ein- und Ausgang muss bei Mindestunterstützung moderner Standard Konventionen, in denen nur Zehnerpotenzen sind von größeren Zahlen abgezogen (zB I, X, Csind erforderlich , Subtrahierern aber nicht V, L, D) und Subtraktion wird nie von einer Reihe mehr getan , als 10x der Subtrahierer (zB IXmuss unterstützt werden, ICist aber nicht erforderlich).
  • Eingabe und Ausgabe sollten in der Reihenfolge des Werts von links nach rechts erfolgen, beginnend mit dem größten (dh 19 = XIXnicht IXX, 10 ist größer als 9).
  • Von links nach rechts, kein Operator-Vorrang, als ob Sie einen Handrechner verwenden würden.
  • Unterstützt die Eingabe / Ausgabe ganzer positiver Zahlen zwischen 1-4999 (keine Notwendigkeit für V̅)
  • Keine Bibliotheken, die römische Zahlen für Sie konvertieren

Damit Sie sich entscheiden

  • Groß- und Kleinschreibung
  • Leerzeichen oder keine Leerzeichen bei der Eingabe
  • Was passiert, wenn Sie eine dezimale Ausgabe erhalten? Abschneiden, keine Antwort, Fehler usw.
  • Was tun bei Ausgaben, die Sie nicht verarbeiten können? Negative oder Zahlen sind zu groß, um gedruckt zu werden.
  • Ob eine liberalere Verwendung des Subtraktionsprinzips als die Mindestanforderung unterstützt werden soll.

Extra Gutschrift

Sample Input / Output

XIX + LXXX                 (19+80)
XCIX

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

Der kürzeste Code gewinnt.


(99 + 1/50 * 500 + 4) = (99 + 10 + 4) = 113, aber Ihre Probenein- / ausgabe besagt, dass es sich um MIV (1004) handelt.
Victor Stafusa

1
@Victor - Strikte Links-Rechts-Operation - Keine Vorrangregeln - Daher sollte 99 + 1/50 * 500 + 4 als ((((99 + 1) / 50) * 500) + 4)

Ist der Umgang mit Nummern wie IM = 999gewünscht?
Kendall Frey

@KendallFrey Ich würde erwarten, dass Sie eingeben könnten IM. Ob die Ausgabe IModer CMXCIXfür 999 ist, liegt bei Ihnen. Beides entspricht den Anforderungen.
Danny

2
IM ist kein Standard für die Verwendung von modernen römischen Zahlen. Typischerweise werden nur die 4er und 9er jeder Größenordnung (4, 9, 40, 90, 400, 900 usw.) durch Subtraktion ausgeführt. Für 1999 wäre MCMXCIX kanonisch, nicht MIM ... Sieh dir die Credits eines Films aus diesem Jahr an. Wo endet es sonst? Werden wir voraussichtlich auch andere nicht standardmäßige Subtraktionen wie VL für 45 unterstützen? Müsste IC mit einem Vinculum über dem C als 99999 für den Bonus unterstützt werden?
Jonathan Van Matre

Antworten:


9

JavaScript (ES6), 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}

Verwendung:

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

Kommentierte Version:

/**
 * 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

T-SQL, 1974 - 50 = 1924 Bytes

Ich weiß, dass das Golfen in SQL dem Spielen von 18 Löchern mit nichts als einem Sandkeil entspricht, aber ich habe die Herausforderung dieses Lochs genossen und ich denke, ich habe es geschafft, einige interessante Dinge methodisch zu tun.

Dies unterstützt das Vinculum sowohl für die Eingabe als auch für die Ausgabe. Ich habe mich an die Konvention gehalten, eine nachgestellte Tilde zu verwenden, um sie darzustellen, also ist V ~ 5000, X ~ 10000 usw. Entsprechend der Verwendung von modernen römischen Zahlen sollten auch Ausgaben von bis zu 399.999 verarbeitet werden. Danach wird eine teilweise nicht standardmäßige römische Codierung für alle Elemente im von INT unterstützten Bereich durchgeführt.

Da es sich ausschließlich um Ganzzahl-Mathematik handelt, werden alle nicht ganzzahligen Ergebnisse implizit gerundet.

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

Ich arbeite immer noch an einer satzbasierten Lösung, um einige WHILE-Schleifen zu ersetzen, die die Byteanzahl verringern und ein eleganteres Beispiel für idiomatisches SQL darstellen könnten. Es gibt auch einige Bytes zu gewinnen, indem die Verwendung von Tabellen-Aliasen auf ein Minimum reduziert wird. Aber da es in dieser Sprache im Wesentlichen nicht zu gewinnen ist, bin ich meistens nur hier, um mein Don Quijote-Outfit zu präsentieren. :)

SELECT @i oben wiederholt die Eingabe:

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

Und das SELECT am Ende gibt zurück:

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

Und Sie können es selbst an dieser SQLFiddle testen

Und ich werde wiederkommen, um ein paar Kommentare hinzuzufügen, wie es funktioniert, denn warum sollte man eine offensichtlich verlierende Antwort posten, wenn man sie nicht für einen pädagogischen Wert ausnutzen will?


2

Javascript - 482 476 Zeichen

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))))

Der Sample Input / Output funktioniert:

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

Es geht auch schlecht mit großen Zahlen um:

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

Und es akzeptiert, benötigt aber auch keine Leerzeichen.

Aber seit ich Golf gespielt habe, gibt es einige Probleme:

  • Es wird nicht überprüft, ob die Eingabe wohlgeformt ist. Wenn die Eingabe nicht korrekt ist, ist das Verhalten undefiniert (und in der Praxis ist es sehr bizarr und seltsam).
  • Es schneidet Bruchzahlen bei der Ausgabe ab (kann jedoch Zwischenberechnungen damit durchführen).
  • Es missbraucht wirklich die Bewertungsfunktion.
  • Es wird nicht versucht, negative Zahlen zu verarbeiten.
  • Es wird zwischen Groß- und Kleinschreibung unterschieden.

Diese alternative Version verarbeitet Zahlen über 5000 bis 99999, hat jedoch 600 598 584 Zeichen:

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))))

Ich glaube nicht, dass die -20 gilt: siehe vinculum
SeanC

Stimmen Sie mit @SeanCheshire hier überein. Für die Behandlung größerer Zahlen ist es beabsichtigt, ein Vinculum über die Zahl zu addieren , das das 1000-fache des Wertes dessen ist, was es normalerweise ist. Vielleicht sollte es größer als -20 sein, damit es sich lohnt, es für Leute zu versuchen.
Danny

1
@Danny Ich habe eine Version hinzugefügt, die den Vinculus behandelt, aber den Code in 116 Zeichen erhöht.
Victor Stafusa

2

Javascript 479 361 348 278 253

303 Zeichen - 50 für die Unterstützung von Zahlen bis zu 1 Million, einschließlich vinculum-Unterstützung:

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

Verbrauch: p(text)zB p('XIX + LXXX')kehrt zurück XCIX.

Code mit erläuternden Kommentaren:

// 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;
}

Dies funktioniert für die angegebenen Beispiele und für alle anderen, die ich ausprobiert habe. Beispiele:

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

Ruby 2.1, 353 (und viele andere Iterationen) , 295 - 50 = 245

Die vinculum-Behandlung fügt ~ 23 Zeichen hinzu.

Dies behandelt "IL" oder "VM" in der Eingabe und schlägt ohne Fehler bei Negativen (High-Ints) oder Dezimalzahlen (Kürzungen) oder Leerzeichen fehl. Behandelt jetzt auch eine negative erste Zahl (obwohl die Summe immer noch schlecht ausfällt, wenn sie negativ ist). Scheitert auch schlecht, wenn Sie mit * beginnen oder / oder wenn das Ergebnis 4 Millionen oder mehr beträgt.

Verwendet Object # send für die "Handrechner" -Funktionalität.

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

Python 2 - 427 418 404 401 396 395 392 Zeichen

Liest von der Standardeingabe. Es werden nur Großbuchstaben verarbeitet (bei 8 zusätzlichen Zeichen kann die Groß- und Kleinschreibung unberücksichtigt bleiben) und Leerzeichen benötigt. Keine Validierung - Ich habe nicht getestet, wie es in verschiedenen Fällen bricht. Zahlen wie VC = 95 werden jedoch verarbeitet.

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

Und die ungolfed version:

# 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

Ich habe das Gefühl, Perl wäre besser gewesen, aber ich weiß nicht genug davon. Für einen ersten Versuch mit Codegolf fühle ich mich jedoch ziemlich gut dabei.


1

PHP - 549 525 524 520 Bytes

Nichts allzu innovatives: Normalisiert die Operatoren, um den Vorrang von links nach rechts zu gewährleisten, konvertiert römische in dezimale Zeichen, führt evaldie Anweisung aus, z. B. wird XCIX + I / L * D + IV in so etwas wie return ((((((+90 +9) + (+1)) / (+50)) * (+500)) + (+4)); konvertiert dann die Dezimalstelle zurück in die römische.

  • Endergebnisse werden abgeschnitten
  • Antworten unter 1 sind leer
  • Ergebnisse sind bei falscher Eingabe undefiniert
$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";

z.B

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

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

0

Python - 446 Bytes

Dies könnte erheblich verbessert werden. Ich hatte das Gefühl, ich musste den ersten Schwung mit Python machen. Es macht 3 Dinge beim ersten Durchgang

  1. Tokenisiert die Zahlen und Operatoren
  2. wertet die Zahlen aus und erweitert die Symboltabelle xum alle möglichen Kombinationen (auch wenn sie nicht verwendet werden). Während zum Beispiel XIXwird die Teilwerte des gelext, "X":10, "XI":11und "XIX":19in die Symboltabelle hinzugefügt
  3. Fügt verschachtelte Parens ein, um die Auswertung von links nach rechts zu erzwingen

Am Ende wird evaldie ursprüngliche Zeichenfolge aufgerufen (außer bei hinzugefügten Parens) und die Symboltabelle ausgegeben.

Dann habe ich gerade eine bekannte Lösung eingefügt, um eine Ganzzahl in eine römische umzuwandeln, da ich lange genug daran gearbeitet hatte ... Bitte verbessere mich, damit ich etwas Neues lerne :)

m = zip ((1000,900,500,400,100,90,50,40,10,9,5,4,1),
('M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', ' ICH'))
def doit (s):
 x = {'M': 1e3, 'D': 500, 'C': 100, 'L': 50, 'X': 10, 'V': 5, 'I': 1}; y = [] ; z = ''; a = '0'; s = '+' + s
 für c an ober ():
  wenn c in x:
   z + = c; y.append (x [c])
   wenn len (y)> 1 und y [-1]> y [-2]: y [-2] * = -1
   x [z] = Summe (y)
  elif c in "+ / * -": a = '(' + a + z + ')' + c; y = []; z = ''
 a + = z; i = eval (a, x); r = ''
 für n ist c in m: d = int (i / n); r + = c * d; i- = n * d
 return r


print doit ("XIX + LXXX")
print doit ("XCIX + I / L * D + IV")
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.