Wenn Sie in Rom sind, zählen Sie wie die Römer?


20

Hintergrund

Diese Herausforderung wurde von dieser Website inspiriert , auf der das folgende Diagramm veröffentlicht wurde:

Bildbeschreibung hier eingeben

Dieses Diagramm zeigt uns, dass der längste römische Ziffernausdruck unter 250 der von 188 ist, für dessen Angabe 9 Ziffern erforderlich sind.

Herausforderung

Die Standardsymbole verwendet meisten römischen Ziffern auszudrücken sind: { I, V, X, L, C, D, M}, wobei die numerischen Werte Zeichen M= 1000, D= 500, C= 100, L= 50, X= 10, V= 5 I= 1 ist .

In dieser Herausforderung besteht Ihr Ziel darin, bei einer positiven Ganzzahl n die Anzahl der gültigen Darstellungen römischer Zahlen zu berechnen, die durch Verketten von n der Standardsymbole erstellt werden können.

Dann muss Ihr Programm das Ergebnis dieser Berechnung ausgeben!

Eingabe : Eine positive ganze Zahl n .

Ausgabe : Die Anzahl der gültigen römischen Zahlen mit der Länge n .

Regeln für römische Zahlen

Römische Ziffern hatten ursprünglich nur "additive" Paarungen, was bedeutet, dass Ziffern immer in absteigender Reihenfolge geschrieben wurden und die Summe der Werte aller Ziffern der Wert der Zahl war.

Später wurde die subtraktive Paarung zur Verkürzung der Ausdrücke der römischen Zahl üblich, indem eine kleinere Zahl vor eine größere gestellt wurde, um die kleinere von der größeren zu subtrahieren. Subtraktiven Paare können nicht angekettet, wie in dem folgenden ungültigen Ausdruck werden: IXL.

Das Folgende sind die modernen Regeln für die additive und subtraktive Paarung.

  1. In einem subtraktiven Paar kann nur ein I, X und C als führende Ziffer verwendet werden.
  2. Ich kann nur in einem subtraktiven Paar vor V oder X gesetzt werden.
  3. X kann nur in einem subtraktiven Paar vor L oder C gesetzt werden.
  4. C kann nur in einem subtraktiven Paar vor D oder M gesetzt werden.
  5. Mit Ausnahme von subtraktiven Paaren müssen die Ziffern in absteigender Reihenfolge angegeben werden (dh, wenn Sie die führende Ziffer jedes subtraktiven Paars ablegen, werden die Ziffern in absteigender Reihenfolge angegeben).
  6. M, C und X können von kleineren Nennwerten nicht erreicht oder überschritten werden.
  7. D, L und V dürfen jeweils nur einmal vorkommen.
  8. Nur M kann 4 oder mehrmals wiederholt werden.

Weitere Hinweise

  • Wir werden die Balkennotation nicht verwenden. Stattdessen werden wir einfach weitere Ms hinzufügen , um eine beliebige Zahl auszudrücken.

  • Dies sind die einzigen Regeln, die wir für unsere römischen Ziffern befolgen werden. Dies bedeutet, dass auch ungerade Ausdrücke wie IVIin unserem System als gültig angesehen werden.

  • Denken Sie auch daran, dass wir nicht die Anzahl der Zahlen mit Ausdrücken der Länge n zählen , da einige Zahlen mehrere Ausdrücke haben. Stattdessen zählen wir nur die Anzahl der gültigen Ausdrücke.

Testfälle

17

231

3105

Ich habe die obigen Angaben von Hand überprüft. Überprüfen Sie daher die Testfälle sorgfältig und fügen Sie weitere hinzu, wenn Sie können.

Gewinnkriterien

Dies ist eine Herausforderung, also viel Spaß! Ich akzeptiere nur Lösungen, die mindestens Eingaben von 1 bis 9 verarbeiten können. Mehr ist Bonus!

Bearbeiten

Wie von Kommentatoren gefordert, finden Sie unten oder in diesem Pastebin-Link die 105 Combos, die ich für n = 3 gezählt habe

III IVI IXI IXV IXX VII XII XIV XIX XVI XXI XXV XXX XLI XLV XLX XCI XCV XCX XCL XCC LII LIV LIX LVI LXI LXV LXX CII CIV CIX CVI CXI CXV CXX CXL CXC CLI CLX CCI CCV CCX CDC CMI CMV CMX CML CMC CMD CMM DII DIV DIX DVI DXI DXV DXX DXL DXC DLI DLV DLX DCI DCX DCL DCC MII MIV MIX MVI MXI MXV MXX MXC MLI MLV MLX MCI MCV MCX MCL MCC MCD MCM MDM MDM MDM MMX MML MMC MMD MMM

Bearbeiten 2:

Verwenden Sie den folgenden Code , der nicht für Golfspieler bestimmt ist , mit freundlicher Genehmigung von Jonathan Allan, um Ihre Ergebnisse zu überprüfen.

Edit 3:

Ich entschuldige mich für alle Fehler bei dieser Herausforderung. Ich werde sicher gehen, dass ich das nächste Mal einen besseren Job mache!


Kommentare sind nicht für eine längere Diskussion gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Mego

Antworten:


3

Netzhaut , 111 Bytes

~(`.+
*$(CM)CDXCXCXCXLIXIXIXIVII
.(.)
.+¶$$&$¶$$&$1$¶$$&$&¶L`.{0,$+}\b¶D`¶
¶$
¶.+¶$$&$¶$$&I¶L`[A-Z]{$+}\b¶D`¶.+

Probieren Sie es online! Dies ist eine komplette Neufassung als ich 1. Regel falsch verstanden bedeuten , dass Sie nur ein jeder der subtraktiven nutzen könnten I, Xund C. Erläuterung: Der erste Teil des Skripts erweitert die Eingabe in eine Folge von CMPaaren, gefolgt von den anderen möglichen subtraktiven Paaren. Jedes Paar ist optional, und das erste Zeichen jedes Paares ist auch innerhalb des Paares optional. In der dritten Stufe wird die Liste der Paare zu einer Liste von Retina-Befehlen erweitert, die die Eingabe übernehmen und drei Kopien mit der Option des zweiten oder beider Zeichen aus dem Paar erstellen. Anschließend werden die Ergebnisse gekürzt und dedupliziert. In der letzten Phase wird dann Code angehängt, um die endgültigen Aufgaben auszuführen: Erweitern Sie zuerst die Eingabe, um möglicherweise ein Finale hinzuzufügenI, um dann die Ergebnisse mit der falschen Länge herauszufiltern, die Ergebnisse zu deduplizieren und schließlich die Ergebnisse zu zählen. Das resultierende Retina-Skript wird dann ausgewertet.

Hinweis: Theoretisch könnten ab dem Ende der 4. Zeile 15 Byte gespeichert werden, aber dies macht das Skript zu langsam, um es auf TIO auch für zu demonstrieren n=1.


@ JonathanAllan Ah, dann schließen Sie mehrere subtraktive Paare mit derselben führenden Ziffer ein, was falsch ist.
Neil

2
@JonathanAllan Neues Umschreiben, zufällig für genau die gleiche Byteanzahl!
Neil

5

Python 2 , 177 168 162 Bytes

import re,itertools as q
f=lambda n:sum(None!=re.match("^M*(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$",(''.join(m)))for m in q.product('MDCLXVI',repeat=n))

Probieren Sie es online!

Ich bin ziemlich neu, hilf mir Golf zu spielen! Damit nach tatsächlichen römischen Ziffern gesucht wird, muss der reguläre Ausdruck angepasst werden, um die ungeraden Fälle zu berücksichtigen, wie zIVI

-9 Bytes dank @Dead Possum!

-6 Bytes dank @ovs


Ja, ich denke, der Fall n = 3 könnte im Beispiel falsch sein. Ich bekam ursprünglich 93 mit^M*(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$
Easton Bornemeier


1
@JonathanAllan Ich habe ungefähr zwei Tage bei Math stackexchange herumgefragt, um sicherzustellen, dass diese Regeln sinnvoll sind. Ich schätze, ich habe nicht genug getan :(
Don Thousand

1
@RushabhMehta Dies ist eine sehr gut formatierte Herausforderung und macht Spaß beim Programmieren. Es ist Ihre Herausforderung, spezifizieren Sie sie, wie Sie es für richtig halten. es ist in dem anderen Sinne praktikabel, nur schwieriger
Easton Bornemeier

1
Dies scheint nicht die richtige Antwort für 3 zu geben. 93Statt105
Jo King

3

JavaScript (ES7), 133 Byte

Bearbeiten : Korrigiert, um den Ergebnissen zu entsprechen, die von Jonathan Allans Code zurückgegeben wurden , der vom OP als Referenzimplementierung angegeben wurde.


n=>[...Array(m=k=7**n)].reduce(s=>s+/^1*5?4{0,3}3?2{0,3}6?0{0,3}$/.test((--k+m).toString(7).replace(/0[62]|2[34]|4[51]/g,s=>s[1])),0)

Probieren Sie es online!

Wie?

N1

[...Array(m = k = 7 ** n)].reduce(s => … (--k + m).toString(7) …, 0)

Ab sofort wird jede Ziffer als römisches Zahlensymbol interpretiert:

0ich,1M,2X,3L,4C,5D,6V

2) Wir ersetzen alle gültigen subtraktiven Paare des Formulars ABdurch B:

.replace(/0[62]|2[34]|4[51]/g, s => s[1]))  // in the code
.replace(/I[VX]|X[LC]|C[DM]/g, s => s[1]))  // with Roman symbols

Beispiele:

  • XLIXIV wird LXV
  • XIIVwird XIV, Iwenn Sie ein verlassen , schlägt der nächste Test fehl
  • ICbleibt unverändert, wodurch auch ein ungültiger Ian Ort und Stelle bleibt

3) Wir überprüfen, ob die verbleibenden Symbole in der richtigen Reihenfolge sind und nicht öfter erscheinen, als es ihnen gestattet ist:

/^1*5?4{0,3}3?2{0,3}6?0{0,3}$/.test(…)  // in the code
/^M*D?C{0,3}L?X{0,3}V?I{0,3}$/.test(…)  // with Roman symbols

Heilige Kuh, ich hätte nicht erwartet, dass dies in weniger als 200 Bytes in nicht esoterischen Sprachen gemacht wird! Möchten Sie erklären, wie das funktioniert?
Don Thousand

Allerdings ist mir aufgefallen, dass dies bei * n *> 4 auf TIO nicht funktioniert, was etwas unglücklich ist.
Don Thousand

@ RushabhMehta Ich habe eine nicht-rekursive Version hinzugefügt, um höhere Werte zu testen. Ich werde eine Erklärung hinzufügen, wenn ich damit fertig bin.
Arnauld

0

C 150 123 Bytes

Ich habe die Beschreibung nicht genau genug gelesen, daher ergibt sich die Anzahl der römischen Standardzahlen (wobei Ausdrücke wie IVInicht gezählt werden). Da ich einige Anstrengungen unternommen habe, dachte ich, ich würde sowieso teilen.

#define F(X) for(X=10;X--;)
x[]={0,1,2,3,2,1,2,3,4,2};f(i,o,a,b,c){for(i++;i--;)F(a)F(b)F(c)o+=i==x[a]+x[b]+x[c];return o;}

Original (150 Bytes):

#define F(X) for(X=10;X--;)
i,o,a,b,c,x[]={0,1,2,3,2,1,2,3,4,2};main(){scanf("%i",&i);for(i++;i--;)F(a)F(b)F(c)o+=i==x[a]+x[b]+x[c];printf("%i\n",o);}

1
Du darfst nur gültige Beiträge posten.
Okx

@CurtisBechtel Ich nehme an, Sie können die Lösung hier beibehalten, aber ich würde versuchen, sie so zu ändern, dass sie den Regeln der Herausforderung entspricht.
Don Thousand

1
Ich denke, Sie können das Leerzeichen zwischen F(X)und entfernenfor(X=10;X--;)
Zacharý
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.