Überblick
Die alten Römer entwickelten ein Zahlensystem mit lateinischen Buchstaben, das ihnen gute Dienste leistete und das von der modernen Zivilisation immer noch verwendet wird, wenn auch in viel geringerem Maße. In der Zeit seiner Verwendung hätten die Römer lernen müssen, diese Zahlen zu verwenden und zu manipulieren, um für viele Anwendungen von großem Nutzen zu sein. Wenn zum Beispiel ein Mann 35 Ochsen besaß und 27 weitere beschaffte, wie würde er dann die neue Summe kennen, außer sie alle zu zählen? ( Ok, das und mit einem Abakus ... ) Wenn die Römer es könnten, könnten wir es sicherlich auch herausfinden.
Ziel
Schreiben Sie den kürzesten Algorithmus / die kürzeste Funktion / das kürzeste Programm, mit dem zwei römische Ziffern addiert werden , und geben Sie das Ergebnis aus, ohne die Zeichenfolgendarstellung einer der Eingaben in eine Zahl umzuwandeln.
Regeln / Einschränkungen
Aufgrund historischer / vormittelalterlicher Inkonsistenzen bei der Formatierung werde ich einige nicht standardmäßige (für die moderne Verwendung) Regeln für die Rechtschreibung skizzieren. Siehe die unten stehende Wertanleitung als Beispiel.
- Die Buchstaben I, X, C und M können bis zu vier Mal hintereinander wiederholt werden, jedoch nicht mehr. D, L und V können niemals wiederholt werden.
- Der Buchstabe unmittelbar rechts von einem anderen Buchstaben in der römischen Darstellung hat den gleichen oder einen geringeren Wert als der links davon.
- Mit anderen Worten,
VIIII == 9
aberIX != 9
und ist ungültig / nicht erlaubt.
- Mit anderen Worten,
- Alle Eingabewerte betragen 2.000 (MM) oder weniger. Für Zahlen größer als M ist keine Darstellung erforderlich.
- Alle Eingabewerte sind eine gültige römische Ziffer gemäß den obigen Regeln.
- Sie dürfen im Rahmen Ihrer Lösung keine Zahlen in Dezimal-, Binär- oder andere Zahlensysteme konvertieren (Sie können gerne eine solche Methode verwenden, um Ihre Ergebnisse zu überprüfen ).
- Dies ist Code Golf, also gewinnt der kürzeste Code.
Werteführer
Symbol Value
I 1
II 2
III 3
IIII 4
V 5
VIIII 9
X 10
XIIII 14
XXXXIIII 44
L 50
LXXXXVIIII 99
C 100
D 500
M 1,000
Beispiele
XII + VIII = XX (12 + 8 = 20)
MCCXXII + MCCXXII = MMCCCCXXXXIIII (1,222 + 1,222 = 2,444)
XXIIII + XXXXII = LXVI (24 + 42 = 66)
Wenn weitere Erläuterungen erforderlich sind, fragen Sie bitte.
quelle
Antworten:
APL (
5956)Eingabe in einer Zeile (dh
XII + XII
obwohl dies+
nicht erforderlich ist).Bearbeiten: Verschiebung geändert, um zu drehen, um drei Zeichen zu speichern - es ist nur wichtig, wenn die Antwort ≥ 5000 ist, was niemals passieren sollte, da die Frage besagt, dass die Eingabewerte immer ≤ 2000 sind. Der einzige Effekt ist, dass es jetzt bei 5000 "überläuft", was ergibt 5000 = 1, 5001 = 2 usw.
(Ich glaube nicht, dass die Römer es so gemacht haben ... APL ist eher etwas für alte Ägypter, denke ich :))
Erläuterung:
⍞
: Benutzereingaben abrufen(N←'MDCLXVI')∘=¨
: 'MDCLXVI' in N speichern. Für jedes Zeichen der Eingabezeichenfolge einen Vektor mit einer 1 an der Stelle zurückgeben, an der das Zeichen einem von 'MDCLXVI' entspricht, andernfalls 0.⊃+/
: Summiere die Vektoren und entkapsele sie. Wir haben jetzt einen Vektor mit Informationen darüber, wie viele von jeder römischen Ziffer wir haben. Dh wenn die Eingabe warXXII XIIII
, haben wir jetzt:{
...:
...⋄
...}
ist eine Funktion mit einem if-else-Konstrukt.D←7⍴5 2
:D
ist der Vektor5 2 5 2 5 2 5
. So viele römische Ziffern sind nicht erlaubt. Das heißt, wenn Sie 5I
s haben, sind das zu viele, und wenn Sie 2V
s haben, sind das auch zu viele. Dieser Vektor ist zufällig auch der Multiplikationsfaktor für jede römische Ziffer, dh aV
ist 5I
s wert und anX
ist 2V
s wert .∨/K←⍵≥D
:K
ist der Vektor, in dem es eine 1 gibt, wenn wir zu viele römische Ziffern einer bestimmten Art haben.∨/
ODERs diesen Vektor zusammen.K×D
: Multipliziere K mit D. Dieser Vektor hat Nullen, bei denen wir nicht zu viele römische Ziffern haben, und die Anzahl der römischen Ziffern, bei denen wir dies tun.⍵+(1⌽K)
: Drehen Sie K um 1 nach links und fügen Sie es dem Eingang hinzu. Für jede römische Zahl, die wir zu viele haben, wird eine der nächsthöheren hinzugefügt.⍵+(1⌽K)-K×D
: Subtrahiere dies vom anderen Vektor. Der Effekt ist, wenn Sie beispielsweise 6I
s haben, wird eine hinzugefügtV
und 4I
s entfernt.∇
: Rekurs.⋄⍵
: WennK
aber alle Nullen waren, dann steht ⍵ für eine gültige römische Ziffer, also geben Sie ⍵ zurück.N⍴⍨¨
: Erstellen Sie für jedes Element des resultierenden Vektors so viele der entsprechenden römischen Ziffern.,/
: Verbinden Sie diese Vektoren miteinander, um die hässlichen Leerzeichen in der Ausgabe zu entfernen.quelle
Python, 100
Nimmt eine Zeichenfolge von der Eingabe (z . B.
VIII + XII
oderVIII + XII =
).quelle
Perl, 132 Zeichen
Deklariert eine Funktion,
s
die eine beliebige Anzahl von Argumenten akzeptiert und summiert. Ziemlich einfach: Es hängt die Eingabe an, reduziert alles aufI
s und stellt dann sofort die römischen Ziffern wieder her. (Hoffentlich zählt dies nicht als Verwendung des unären Zahlensystems!)quelle
Ruby,
8582 ZeichenDiese Version nimmt die Eingabe in STDIN als einzelne Zeichenfolge (z. B.
XXIIII + XXXXII
) auf und druckt die Ausgabe in STDOUT.Die zweite ist eine Implementierung als Funktion. Nimmt zwei (oder mehr) Zeichenfolgen und gibt die summierten Werte zurück. Verwendungszweck:
quelle
GNU Sed, 131 Zeichen
quelle
Python, 174 Zeichen
Ein sehr einfacher Algorithmus - zählen Sie jede Ziffer, Schleife, um den Überlauf zur nächsten zu verarbeiten, drucken Sie.
Liest von der Standardeingabe. So etwas
XVI + CXX
würde funktionieren (ignoriert alles außer Ziffern, daher wird das+
nicht wirklich benötigt).quelle
Scala 150
Aufruf:
ungolfed Version:
quelle
JavaScript
195179Mein System ist ziemlich rudimentär, reduzieren Sie alle römischen Ziffern auf eine Reihe von
I
für beide Zahlen, verbinden Sie sie und kehren Sie dann den Prozess um, indem Sie bestimmte BlöckeI
in ihre jeweiligen größeren Versionen verwandeln ...Iteration 1
a="IIIII0VV0XXXXX0LL0CCCCC0DD0M".split(0);d=b=>x.replace(g=RegExp((c=z)>b?a[c][0]:a[c],"g"),c>b?a[b]:a[b][0]);x=prompt().replace("+","");for(z=6;0<z;z--)x=d(z-1);for(z=0;6>z;z++)x=d(z+1);alert(x)
Iteration 2
a="IIIII0VV0XXXXX0LL0CCCCC0DD0M".split(0);x=prompt().replace("+","");for(z=-6;6>z;z++)b=0>z?-z:z,c=0>z?~z:z+1,x=x.replace(g=RegExp(b>c?a[b][0]:a[b],"g"),b>c?a[c]:a[c][0]);alert(x)
Eigenschaften:
Die Eingabe erfolgt über eine Eingabeaufforderung in Form von
<first roman number>+<second roman number>
(keine Leerzeichen), die Ausgabe in Form einer Warnung.z.B
quelle
VBA, 187 Zeichen
quelle
o
es nur einmal verwendet wird, können Sie 3 Bytes sparen, indem Sie die Zuordnung und Auswertung entfernen undn Mod r
direkt in denString(
Funktionsaufruf einsteckenJavaScript, 190
Wenn Sie eine Anweisung in den dritten Steckplatz des
for
Operators einfügen, kann ich einige Semikolons speichern!Wenn Sie zur Eingabe aufgefordert werden, geben Sie die beiden Zahlen ein (die
+
Leerzeichen und sind nicht erforderlich, aber wenn Sie sie eingeben, wird kein Fehler angezeigt). Dann zeigt Ihnen der Alarm die Summe.quelle
C ++, 319 Zeichen
quelle
PHP, 136 Bytes
Probieren Sie es online aus!
quelle