Übereinstimmung mit römischen Ziffern


19

Herausforderung

Wenn Sie eine Eingabezeichenfolge angeben, geben Sie einen Wahrheitswert zurück, wenn diese eine korrekte römische Zahl zwischen 1 (= I) und 3999 (= MMMCMXCIX) darstellt, andernfalls einen falschen Wert.

Einzelheiten

  • Die Eingabe ist eine nicht leere Zeichenfolge, die nur die Zeichen enthält IVXLCDM.
  • Die römischen Ziffern (die wir hier in dieser Herausforderung verwenden) sind wie folgt definiert:

Wir verwenden nur folgende Symbole:

Symbol  I   V   X   L   C   D    M
Value   1   5  10  50 100 500 1000

Um zu definieren, welche Zeichenfolgen tatsächlich gültige römische Ziffern sind, ist es wahrscheinlich am einfachsten, die Konversationsregel anzugeben: Um eine Dezimalzahl a3 a2 a1 a0(wobei jede aieine Ziffer darstellt. Zum Beispiel um darzustellen, was 792wir haben a3=0, a2=7, a1=9, a0=2) als römische Ziffer zu schreiben , zerlegen wir sie in die Macht der Zehner. Die verschiedenen Zehnerpotenzen können wie folgt geschrieben werden:

      1-9: I, II, III, IV, V, VI, VII, VIII, IX
    10-90: X, XX, XXX, XL, L, LX, LXX, LXXX, XC
  100-900: C, CC, CCC, CD, D, DC, DCC, DCCC, CM
1000-3000: M, MM, MMM

Beginnend auf der linken Seite mit der höchstwertigen Ziffer der können wir die Zahl, die jede Ziffer darstellt, separat konvertieren und verketten. Für das obige Beispiel würde dies also so aussehen:

Digit        a3    a2   a1   a0
Decimal       0     7    9    2
Roman             DCC   XC   II

Daher 792lautet die römische Ziffer für DCCXCII. Hier finden Sie eine vollständige Liste aller römischen Ziffern, die für diese Herausforderung relevant sind: OEIS a006968.txt

Beispiele

Wahrheit

MCCXXXIV (1234)
CMLXXXVIII (988)
DXIV (514)
CI (101)

Falsey

MMIXVIII
IVX
IXV
MMMM
XXXVX
IVI
VIV


Ich denke immer noch nicht, dass dies als "Teilmenge" qualifiziert ist, da die Menge der ungültigen Eingaben größer ist. Diese Herausforderung bezieht sich hier nur auf die "gut" definierten Zahlen, die in OEIS A006968
Fehler

2
Warum ist MMMMungültig? Gibt es einen Buchstaben für 5000, der stattdessen für M <letter> verwendet werden sollte?
Skyler

Schauen Sie sich die Spezifikationen an, es gibt keinen solchen Brief. Die einzigen verwendeten Symbole sind I,V,X,L,C,D,M.
Fehler

Antworten:


17

Ausführlich , 1362 Bytes

GET A ROMAN NUMERAL TYPED IN BY THE CURRENT PERSON USING THIS PROGRAM AND PUT IT ONTO THE TOP OF THE PROGRAM STACK
PUT THE NUMBER MMMM ONTO THE TOP OF THE PROGRAM STACK
MOVE THE FIRST ELEMENT OF THE PROGRAM STACK TO THE SECOND ELEMENT'S PLACE AND THE SECOND ELEMENT OF THE STACK TO THE FIRST ELEMENT'S PLACE
DIVIDE THE FIRST ELEMENT OF THE PROGRAM STACK BY THE SECOND ELEMENT OF THE PROGRAM STACK AND PUT THE RESULT ONTO THE TOP OF THE PROGRAM STACK
PUT THE NUMBER V ONTO THE TOP OF THE PROGRAM STACK
GET THE FIRST ELEMENT OF THE PROGRAM STACK AND THE SECOND ELEMENT OF THE PROGRAM STACK AND IF THE SECOND ELEMENT OF THE PROGRAM STACK IS NOT ZERO JUMP TO THE INSTRUCTION THAT IS THE CURRENT INSTRUCTION NUMBER AND THE FIRST ELEMENT ADDED TOGETHER'S RESULT
PUT THE NUMBER I ONTO THE TOP OF THE PROGRAM STACK
GET THE TOP ELEMENT OF THE STACK AND OUTPUT IT FOR THE CURRENT PERSON USING THIS PROGRAM TO SEE
PUT THE NUMBER III ONTO THE TOP OF THE PROGRAM STACK
GET THE FIRST ELEMENT OF THE PROGRAM STACK AND THE SECOND ELEMENT OF THE PROGRAM STACK AND IF THE SECOND ELEMENT OF THE PROGRAM STACK IS NOT ZERO JUMP TO THE INSTRUCTION THAT IS THE CURRENT INSTRUCTION NUMBER AND THE FIRST ELEMENT ADDED TOGETHER'S RESULT
PUT THE NUMBER NULLA ONTO THE TOP OF THE PROGRAM STACK
GET THE TOP ELEMENT OF THE STACK AND OUTPUT IT FOR THE CURRENT PERSON USING THIS PROGRAM TO SEE

Ausgaben Ifür gültige römische Ziffern im Bereich I-MMMCMXCIXund NULLA(0) oder Benutzereingaben sind ansonsten keine gültigen römischen Ziffern.


12
Ich kann mich nicht entscheiden, ob dies das richtige Werkzeug für den Job ist oder nicht.
Vaelus

5
Ist dies das richtige Werkzeug für jeden Job?
Omzrs

8

C # (Visual C # Interactive Compiler) , 79 109 Byte

Dies scheint eine Regex-Herausforderung zu sein, ich bin sicher, dass eine kürzere Lösung gefunden werden kann ...

s=>System.Text.RegularExpressions.Regex.IsMatch(s,"^M{0,3}(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$")

Probieren Sie es online!


Könnten Sie nicht verkürzen {0,3}zu {,3}?
Fehler

@flawr scheint dann nichts zu erfassen
Innat3

1
Ah sorry, nur Dinge wie {5,}Arbeit, aber nicht {,5}.
Fehler

2
Sie können es stattdessen als Compiler-Flag hinzufügen, sodass es 72 Byte groß ist und die Sprache wie diese Antwort in C # (Visual C # Interactive Compiler) mit Flag/u:System.Text.RegularExpressions.Regex geändert werden sollte :)
Kevin Cruijssen

3
Alternate regex: ^M?M?M?(C[MD]|D?C?C?C?)(X[CL]|L?X?X?X?)(I[XV]|V?I?I?I?)$. Gleiche Länge, aber seltsamer (was ist das Ziel, oder?)
Verkörperung der Ignoranz

8

Wolfram Language (Mathematica) , 35 Byte

Check[FromRomanNumeral@#<3999,1<0]&

Probieren Sie es online!

5 Bytes gespart, dank @attinat

die [1,3999]begrenzung kostet leider 7 bytes ...
hier ist der code für jede römische nummer

Wolfram Language (Mathematica) , 28 Byte

Check[FromRomanNumeral@#,F]&

Probieren Sie es online!

der obige code funktioniert für jede nummer, nicht nur für [1,3999]


2
@ExpiredData "Die Eingabe ist eine nicht leere Zeichenfolge, die nur die Zeichen enthält IVXLCDM."
Mathmandan

35 Bytes . Booleist auch kürzer (um ein Byte) als Ifauf diese Weise zu verwenden.
11.

8

CP-1610- Baugruppe ( Intellivision ),  52 ... 48  47 DECLEs 1 = 59 Byte

Lassen Sie uns dies auf einem System versuchen, das Perl um gute 7 Jahre voraus ist. :-)

Nimmt einen Zeiger auf eine nullterminierte Zeichenfolge in R4 . Setzt das Null- Flag, wenn die Eingabe eine gültige römische Zahl ist, oder löscht es anderweitig.

                ROMW    10              ; use 10-bit ROM width
                ORG     $4800           ; map this program at $4800

                ;; ------------------------------------------------------------- ;;
                ;;  test code                                                    ;;
                ;; ------------------------------------------------------------- ;;
4800            EIS                     ; enable interrupts

4801            SDBD                    ; R5 = pointer into test case index
4802            MVII    #ndx,     R5
4805            MVII    #$214,    R3    ; R3 = backtab pointer
4807            MVII    #11,      R0    ; R0 = number of test cases

4809  loop      SDBD                    ; R4 = pointer to next test case
480A            MVI@    R5,       R4
480B            PSHR    R0              ; save R0, R3, R5 onto the stack
480C            PSHR    R3
480D            PSHR    R5
480E            CALL    isRoman         ; invoke our routine
4811            PULR    R5              ; restore R5 and R3
4812            PULR    R3

4813            MVII    #$1A7,    R0    ; use a white 'T' by default
4815            BEQ     disp

4817            MVII    #$137,    R0    ; or a white 'F' is the Z flag was cleared

4819  disp      MVO@    R0,       R3    ; draw it
481A            INCR    R3              ; increment the backtab pointer

481B            PULR    R0              ; restore R0
481C            DECR    R0              ; and advance to the next test case, if any
481D            BNEQ    loop

481F            DECR    R7              ; loop forever

                ;; ------------------------------------------------------------- ;;
                ;;  test cases                                                   ;;
                ;; ------------------------------------------------------------- ;;
4820  ndx       BIDECLE test0, test1, test2, test3
4828            BIDECLE test4, test5, test6, test7, test8, test9, test10

                ; truthy
4836  test0     STRING  "MCCXXXIV", 0
483F  test1     STRING  "CMLXXXVIII", 0
484A  test2     STRING  "DXIV", 0
484F  test3     STRING  "CI", 0

                ; falsy
4852  test4     STRING  "MMIXVIII", 0
485B  test5     STRING  "IVX", 0
485F  test6     STRING  "IXV", 0
4863  test7     STRING  "MMMM", 0
4868  test8     STRING  "XXXVX", 0
486E  test9     STRING  "IVI", 0
4872  test10    STRING  "VIV", 0

                ;; ------------------------------------------------------------- ;;
                ;;  routine                                                      ;;
                ;; ------------------------------------------------------------- ;;
      isRoman   PROC

4876            PSHR    R5              ; push the return address

4877            MOVR    R7,       R2    ; R2 = dummy 1st suffix
4878            MOVR    R2,       R5    ; R5 = pointer into table
4879            ADDI    #@tbl-$+1,R5

487B  @loop     MVI@    R5,       R1    ; R1 = main digit (M, C, X, I)
487C            MVI@    R5,       R3    ; R3 = prefix or 2nd suffix (-, D, L, V)

487D            MVI@    R4,       R0    ; R0 = next digit

487E            CMPR    R0,       R3    ; if this is the prefix ...
487F            BNEQ    @main

4881            COMR    R2              ; ... disable the suffixes
4882            COMR    R3              ; by setting them to invalid values
4883            MVI@    R4,       R0    ; and read R0 again

4884  @main     CMPR    R0,       R1    ; if R0 is not equal to the main digit,
4885            BNEQ    @back           ; assume that this part is over

4887            MVI@    R4,       R0    ; R0 = next digit
4888            CMPR    R0,       R1    ; if this is a 2nd occurrence
4889            BNEQ    @suffix         ; of the main digit ...

488B            CMP@    R4,       R1    ; ... it may be followed by a 3rd occurrence
488C            BNEQ    @back

488E            MOVR    R2,       R0    ; if so, force the test below to succeed

488F  @suffix   CMPR    R0,       R2    ; otherwise, it may be either the 1st suffix
4890            BEQ     @next
4892            CMPR    R0,       R3    ; or the 2nd suffix (these tests always fail
4893            BEQ     @next           ; if the suffixes were disabled above)

4895  @back     DECR    R4              ; the last digit either belongs to the next
                                        ; iteration or is invalid

4896  @next     MOVR    R1,       R2    ; use the current main digit
                                        ; as the next 1st suffix

4897            SUBI    #'I',     R1    ; was it the last iteration? ...
4899            BNEQ    @loop

489B            CMP@    R4,       R1    ; ... yes: make sure that we've also reached
                                        ; the end of the input

489C            PULR    R7              ; return

489D  @tbl      DECLE   'M', '-'        ; table format: main digit, 2nd suffix
489F            DECLE   'C', 'D'
48A1            DECLE   'X', 'L'
48A3            DECLE   'I', 'V'

                ENDP

Wie?

Der reguläre Ausdruck kann in 4 Gruppen mit derselben Struktur umgeschrieben werden, vorausgesetzt, es #handelt sich um ein ungültiges Zeichen, das garantiert nicht in der Eingabezeichenfolge enthalten ist.

                 +-------+---> main digit
                 |       |
(M[##]|#?M{0,3})(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})
                   ||  |
                   |+--+-----> prefix or second suffix
                   |
                   +---------> first suffix

Das erste Suffix der Gruppe N ist die Hauptziffer der Gruppe N-1 . Daher können wir die Muster mit dem Paar (main_digit,zweites_suffix)

Unsere Routine versucht, die eingegebene Zeichenfolge zeichenweise nach diesen Mustern zu analysieren und prüft schließlich, ob das Ende der Zeichenfolge erreicht ist.

Ausgabe

Ausgabe

Screenshot von jzIntv


1. Ein CP-1610-Opcode wird mit einem 10-Bit-Wert codiert, der als "DECLE" bezeichnet wird. Diese Routine ist 47 DECLE lang und beginnt bei 4876 US-Dollar und endet bei 48A4 US-Dollar (im Lieferumfang enthalten).


würde dies sein nicht die wenige Orte , an denen fraktionierte Bytes sind gültig
ASCII-only

@ ASCII-only Früher habe ich das gedacht, aber ich weiß es nicht genau. In den Kommentaren dieser Antwort finden Sie einige Einsichten dazu.
Arnauld

@ Nur ASCII Außerdem habe ich diesen Beitrag gerade in Meta gefunden , das bestätigt, dass es wahrscheinlich am besten ist, auf ganze Bytes zu runden.
Arnauld

Ah, also sind es nur 10 Bits, wenn es im RAM ist?
Nur ASCII

Das Programm wird niemals im RAM gespeichert, sondern nur im ROM. Das hängt also von den in der Kassette verwendeten Speicherchips ab. Die CPU ist für den Zugriff auf 10-Bit- oder 16-Bit-ROM ausgelegt. Die Direktive "ROMW 10" zwingt den Compiler, Code im 10-Bit-Format zu generieren.
Arnauld

7

Java 8, 70 Bytes

s->s.matches("M{0,3}(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})")

Hafen von @ Innat3 's C # Antwort , also stelle sicher, dass du ihn positiv bewertest!

Probieren Sie es online aus.

Erläuterung:

s->                // Method with String parameter and boolean return-type
  s.matches("...") //  Check if the string matches the regex fully
                   //  (which implicitly adds a leading "^" and trailing "$")

M{0,3}             // No, 1, 2, or 3 adjacent "M"
(     |        )   // Followed by either:
 C[MD]             //  A "C" with an "M" or "D" after it
      |            // or:
       D?          //  An optional "D"
         C{0,3}    //  Followed by no, 1, 2, or 3 adjacent "C"
(     |        )   // Followed by either:
 X[CL]             //  An "X" with a "C" or "L" after it
      |            // or:
       L?          //  An optional "L"
         X{0,3}    //  Followed by no, 1, 2, or 3 adjacent "X"
(     |        )   // Followed by either:
 I[XV]             //  An "I" with an "X" or "V" after it
      |            // or:
       V?          //  An optional "V"
         I{0,3}    //  Followed by no, 1, 2, or 3 adjacent "I"

5

R , 74 71 56 Bytes

Vielen Dank an @RobinRyder, @Giuseppe und @MickyT für ihre Vorschläge, wie Grep effektiv mit den in R integrierten Funktionen verwendet werden kann as.roman.

sub("^M(.+)","\\1",scan(,""))%in%paste(as.roman(1:2999))

Probieren Sie es online!


as.romanwird sowieso nicht funktionieren, da es nur 3899aus irgendeinem Grund funktioniert .
Giuseppe

Ich sollte die Dokumentation wirklich besser lesen, wahrscheinlich, weil 4000 keine eindeutige Darstellung in Roman hat, also wie hat man 3900 gemacht. Das ist ähnlich wie 390 und jetzt habe ich gerade ein Problem mit meinem grep gefunden, wo ich hätte müssen Verankern Sie das Muster.
CT Hall

@ Giuseppe, angesprochen, mit dem gleichen regulären Ausdruck wie die anderen Antworten.
CT Hall

2
66 Bytes mit as.roman: Zuerst die Initiale entfernen, Mwenn es eine gibt, dann prüfen, ob das Ergebnis in ist as.roman(1:2999). Dies erfordert eine spezielle Behandlung für den Fall, dass die Eingabe erfolgt M.
Robin Ryder

1
Meine letzte Frage ist, wer zum Teufel hat entschieden, dass romansdas eine nützliche Sache für R ist ??? Es wurde in 2.5.0 (April 2007) hinzugefügt ...
Giuseppe


2

Jelly ,  48 47 46  44 Bytes

-1 danke an Nick Kennedy

5Żo7;“ÆæC‘ð“IVXLCDM”ṃ@3Ƥm2”MẋⱮ3¤ṭŻ€ṚŒpF€ḟ€0ċ

Ein monadischer Link, der eine nicht leere Liste von Zeichen akzeptiert, die nur aus IVXLCDMdiesen bestehen, ergibt entweder 1(wenn es sich um eine gültige römische Zahl zwischen 1 und 2 handelt)1 und 3999) oder 0 (falls nicht).

Probieren Sie es online!Oder sehen Sie die Testsuite an .

Wie?

5Żo7;“ÆæC‘ð“IVXLCDM”ṃ@3Ƥm2”MẋⱮ3¤ṭŻ€ṚŒpF€ḟ€0ċ  - Main Link: list of characters S

5Żo7;“ÆæC‘  - chain 1: f(S) -> X
5Ż          - zero range of five = [0,1,2,3,4,5]
  o7        - OR seven             [7,1,2,3,4,5]
     “ÆæC‘  - list of code-page indices        [13,22,67]
    ;       - concatenate          [7,1,2,3,4,5,13,22,67]

          ð - start a new dyadic chain...

“IVXLCDM”ṃ@3Ƥm2”MẋⱮ3¤ṭŻ€ṚŒpF€ḟ€0ċ - chain 2: f(X,S) -> isValid
“IVXLCDM”                         - list of characters, IVXLCDM
           3Ƥ                     - for infixes of length three:
                                  - (i.e. IVX VXL XLC LCD CDM)
         ṃ@                       -   base decompression with swapped arguments
                                  -   (i.e. use characters as base-3 digits of X's values)
                                  -   (e.g. IVX -> VI I V IX II IV III VII VIII)
             m2                   - modulo two slice (results for IVX XLC and CDM only)
                    ¤             - nilad followed by link(s) as a nilad:
               ”M                 -   character 'M'
                  Ɱ3              -   map across [1,2,3] with:
                 ẋ                -     repeat -> M MM MMM
                     ṭ            - tack
                      Ż€          - prepend a zero to each
                        Ṛ         - reverse
                                  -   -- now we have the table: 
                                  -    0 M MM MMM
                                  -    0 DC C D CM CC CD CCC DCC DCCC
                                  -    0 LX X L XC XX XL XXX LXX LXXX
                                  -    0 VI I V IX II IV III VII VIII
                         Œp       - Cartesian product   [[0,0,0,0],...,["M","CM",0,"IV"],...]
                           F€     - flatten €ach  [[0,0,0,0],...,['M','C','M',0,'I','V'],...]
                             ḟ€0  - filter out the zeros from €ach       ["",...,"MCMIV",...]
                                ċ - count occurrences of S

In der ersten Zeile scheint ein redundanter Platz zu sein. Noch ein Byte. Ein weiteres Byte kann mit einer einfacheren ersten Zeile gespeichert werden. Probieren Sie es online!
Nick Kennedy

Danke, ich habe noch einen davon gerettet.
Jonathan Allan

1

Perl 5 ( -p), 57 Bytes

$_=/^M*(C[MD]|D?C*)(X[CL]|L?X*)(I[XV]|V?I*)$/&!/(.)\1{3}/

TIO

  • verwendet fast den gleichen regulären Ausdruck, außer dass der {0,3}Quantifizierer von geändert wurde*
  • &!/(.)\1{3}/ um sicherzustellen, dass das gleiche Zeichen nicht viermal hintereinander vorkommen kann.
  • kann nicht mit golfed werden , -/(.)\1{3}/da geben würde , -1für IIIIVIzum Beispiel

1

Python 2 , 81 Bytes

import re
re.compile('M{,3}(D?C{,3}|C[DM])(L?X{,3}|X[LC])(V?I{,3}|I[VX])$').match

Probieren Sie es online!

Schauen wir uns den letzten Teil des regulären Ausdrucks an, der mit den römischen Ziffern bis 9 übereinstimmt (einschließlich der leeren Zeichenfolge).

V?I{,3}|I[VX]

Dies hat zwei Alternativen, die durch Folgendes getrennt sind |:

  • V?I{,3}: Optional Vgefolgt von bis zu 3 I. Das paßt die leere Zeichenkette I, II, III, V,VI , VII, VIII.
  • I[VX]: Ein Igefolgt von einem Voder X. Das passtIV und IX.

Die gleichen Dinge mit X,L,Cden Zehnerpaaren, mitC,D,M Anpassen der Hunderter und schließlich für das ^M{,3}Zulassen von bis zu drei MTausendern am Anfang.

Ich habe versucht, die Vorlage für jedes Zeichentrio zu generieren, anstatt sie dreimal zu schreiben, aber das war viel länger.


Der ^Anker ist am Anfang nicht erforderlich . matchimpliziert bereits, dass es am Anfang der Zeichenfolge übereinstimmt.
ShadowRanger

@ ShadowRanger Danke, ich habe die entfernt ^.
12.

Obwohl ich denke, dass Sie die Zählung in der Bearbeitung durcheinander gebracht haben; sollte 83 sein, nicht 81.
ShadowRanger

@ShadowRanger Die Zählung ist 81, weil die f= Code keine anonymen Funktionen enthält. Es ist nur für TIO.
12.

1
Ah, macht Sinn. Es ist ärgerlich, dass es keine Möglichkeit gibt, das in der Kopf- oder Fußzeile zu verbergen, aber ja, nicht zugewiesene lambdas sind legal, daher sollten auch nicht zugewiesene gebundene Methoden für kompilierten regulären Ausdruck gut sein.
ShadowRanger

1

Retina , 56 51 Bytes

(.)\1{3}
0
^M*(C[MD]|D?C*)(X[CL]|L?X*)(I[XV]|V?I*)$

Port of @NahuelFouilleuls Perl 5-Antwort , also stelle sicher, dass du ihn positiv bewertest!

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

(.)\1{3}        # If four adjacent characters can be found which are the same
0               # Replace it with a 0

^...$           # Then check if the string matches the following fully:
 M*             #  No or any amount of adjacent "M"
 (     |    )   #  Followed by either:
  C[MD]         #   A "C" with an "M" or "D" after it
       |        #  or:
        D?      #   An optional "D"
          C*    #   Followed by no or any amount of adjacent "C"
 (     |    )   #  Followed by either:
  X[CL]         #   An "X" with a "C" or "L" after it
       |        #  or:
        L?      #   An optional "L"
          X*    #   Followed by no or any amount of adjacent "X"
 (     |    )   #  Followed by either:
  I[XV]         #   An "I" with an "X" or "V" after it
       |        #  or:
        V?      #   An optional "V"
          I*    #   Followed by no or any amount of adjacent "I"

1

05AB1E , 61 9 8 Bytes

ŽF¯L.XIå

Aufregend -52 Bytesdanke an @Adnan , weil anscheinend die Roman Number von 05AB1E nicht dokumentiert wurde, haha ​​.. xD

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

ŽF¯       # Push comressed integer 3999
   L      # Create a list in the range [1,3999]
    .X    # Convert each integer in this list to a roman number string
      Iå  # Check if the input is in this list
          # (and output the result implicitly)

Sehen Sie sich meinen Tipp 05AB1E (Abschnitt Wie komprimiere ich große ganze Zahlen? ) An, um zu verstehen, warum dies so ŽF¯ist 3999.


Ursprüngliche 61-Byte-Antwort:

•1∞Γ'иÛnuÞ\₂…•Ž8вв€SÐ)v.•6#&‘нδ•u3ôNèyè}'M3L×)Rεõš}`3Fâ}€˜JIå

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

1∞Γ'иÛnuÞ\₂…•             '# Push compressed integer 397940501547566186191992778
              Ž8в           # Push compressed integer 2112
                 в          # Convert the integer to Base-2112 as list:
                            #  [1,11,111,12,2,21,211,2111,10]
S                          # Convert each number to a list of digits
  Ð                         # Triplicate this list
   )                        # And wrap it into a list of lists (of lists)
    v                       # Loop `y` over each these three lists:
     .•6#&‘нδ•              #  Push compressed string "xivcxlmcd"
              u             #  Uppercased
               3ô           #  And split into parts of size 3: ["XIV","CXL","MCD"]
     Nè                     #  Use the loop index to get the current part
       yè                   #  And index the list of lists of digits into this string
    }'M                    '# After the loop: push "M"
       3L                   # Push list [1,2,3]
         ×                  # Repeat the "M" that many times: ["M","MM","MMM"]
          )                 # Wrap all lists on the stack into a list:
                            # [[["I"],["I","I"],["I","I","I"],["I","V"],["V"],["V","I"],["V","I","I"],["V","I","I","I"],["I","X"]],[["X"],["X","X"],["X","X","X"],["X","L"],["L"],["L","X"],["L","X","X"],["L","X","X","X"],["X","C"]],[["C"],["C","C"],["C","C","C"],["C","D"],["D"],["D","C"],["D","C","C"],["D","C","C","C"],["C","M"]],["M","MM","MMM"]]
           R                # Reverse this list
            εõš}            # Prepend an empty string "" before each inner list
                `           # Push the four lists onto the stack
                 3F         # Loop 3 times:
                   â        #  Take the cartesian product of the two top lists
                    }€˜     # After the loop: flatten each inner list
                       J    # Join each inner list together to a single string
                        Iå  # And check if the input is in this list
                            # (after which the result is output implicitly)

Siehe meinen Tipp zu 05AB1E (Abschnitte Wie komprimiere ich Zeichenfolgen, die nicht Teil des Wörterbuchs sind ? , Wie komprimiere ich große Ganzzahlen? Und Wie komprimiere ich Ganzzahllisten?). ), um zu verstehen, warum:

  • •1∞Γ'иÛnuÞ\₂…• ist 397940501547566186191992778
  • Ž8в ist 2112
  • •1∞Γ'иÛnuÞ\₂…•Ž8вв ist [1,11,111,12,2,21,211,2111,10]
  • .•6#&‘нδ• ist "xivcxlmcd"

1
Ich bin nicht sicher, warum .Xnicht dokumentiert ist, aber ich denke, das sollte funktionieren:3999L.XQO
Adnan

@Adnan Haha, -52 Bytes genau dort. Völlig vergessen, dass Sie uns tatsächlich davon erzählt haben, eine eingebaute römische Nummer hinzuzufügen. Bittet @ Mr.Xcoder im Chat, es den Dokumenten hinzuzufügen. Fehlen andere Befehle? ;) PS: Ein weiteres Byte durch Komprimieren gespeichert 3999. :)
Kevin Cruijssen

0

Perl -MRegexp :: Common -pe, 34 Bytes

$_=/^$RE{num}{roman}$/&!/(.)\1{3}/

Der &!/(.)\1{3}/Teil ist notwendig, da Regexp::Commonvier (aber nicht fünf) der gleichen Zeichen in einer Reihe erlaubt sind. Auf diese Weise passt es zu römischen Zahlen, die auf Ziffernblättern verwendet werden, woIIII oft 4 verwendet werden.


0

Python 3 , 116 113 109 107 105 106 Bytes

import re
lambda n:re.match(r'(M{,3}(C(M|CC?|D)?|DC{,3}))(X(C|XX?|L)?|(LX{,3}))?(I(X|II?|V)?|VI{,3})?$',n)

Probieren Sie es online!

-1 Byte dank ShadowRanger


2
Wie ich in der Py2-Antwort erwähnt habe, ^ ist der Zeilenabstand unnötig, da er matchnur am Anfang einer Zeichenkette steht.
ShadowRanger

@ShadowRanger fügte beim Debuggen Anker hinzu und versuchte es dann nicht mehr ohne. Ich werde mich jetzt daran erinnern - danke! :)
Noodle9

Nun, nur um klar zu sein, ist das Nachziehen $notwendig ( fullmatchimpliziert nur Anker an beiden Enden, und das würde offensichtlich mehr als a kosten $).
ShadowRanger

@ShadowRanger Ah! Das erklärt, warum ich Anker brauchte! Wusste nicht, dass ich nur das Ende verankern musste. Danke noch einmal.
Noodle9

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.