Dopasuj cyfry rzymskie


19

Wyzwanie

Biorąc pod uwagę jakiś ciąg wejściowy, zwróć prawdziwą wartość, jeśli reprezentuje poprawną liczbę rzymską między 1 (= I) a 3999 (= MMMCMXCIX), a w przeciwnym razie wartość falsey.

Detale

  • Dane wejściowe są niepustym ciągiem znaków, który zawiera tylko znaki IVXLCDM.
  • Cyfry rzymskie (których używamy tutaj w tym wyzwaniu) są zdefiniowane w następujący sposób:

Używamy tylko następujących symboli:

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

Aby zdefiniować, które ciągi są faktycznie poprawnymi cyframi rzymskimi, prawdopodobnie najłatwiej jest podać regułę konwersacji: Aby zapisać liczbę dziesiętną a3 a2 a1 a0(gdzie każda aireprezentuje jedną cyfrę. Na przykład, aby przedstawić, 792że mamy a3=0, a2=7, a1=9, a0=2) jako cyfrę rzymską, rozkładamy ją w potęgę dziesiątek. Różne potęgi dziesięciu można zapisać w następujący sposób:

      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

Zaczynając od lewej strony z najbardziej znaczącą cyfrą, możemy przekonwertować liczbę, którą każda cyfra reprezentuje osobno, i połączyć je. Na przykład z góry wyglądałoby to tak:

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

Dlatego cyfrą rzymską dla 792jest DCCXCII. Oto pełna lista wszystkich cyfr rzymskich istotnych dla tego wyzwania: OEIS a006968.txt

Przykłady

Prawda

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

Falsey

MMIXVIII
IVX
IXV
MMMM
XXXVX
IVI
VIV


Nadal nie sądzę, że kwalifikuje się to jako „podzbiór”, ponieważ zestaw nieprawidłowych danych wejściowych jest większy. To wyzwanie dotyczy tylko „dobrze” zdefiniowanych liczb używanych w OEIS A006968
błąd

2
Dlaczego jest MMMMnieważny? Czy istnieje litera 5000, która powinna być używana zamiast M <letter>?
Skyler

Sprawdź specyfikację, nie ma takiej litery. Jedynymi używanymi symbolami są I,V,X,L,C,D,M.
flawr

Odpowiedzi:


17

Pełne , 1362 bajtów

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

Dane wyjściowe Idla prawidłowych cyfr rzymskich w zakresie I-MMMCMXCIXi NULLA(0) lub informują, że dane wprowadzone przez użytkownika nie są poprawnymi cyframi rzymskimi.


12
Nie mogę zdecydować, czy jest to odpowiednie narzędzie do pracy, czy nie.
Vaelus

5
Czy to odpowiednie narzędzie do każdego zadania?
omzrs

8

C # (interaktywny kompilator Visual C #) , 79 109 bajtów

To wydaje się być wyzwaniem Regex, jestem pewien, że można znaleźć krótsze rozwiązanie ...

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})$")

Wypróbuj online!


Nie udało się skrócić {0,3}do {,3}?
flawr

@ flawr nie wydaje się wtedy niczego uchwycić
Innat3

1
Ach, przepraszam, tylko rzeczy takie jak {5,}praca, ale nie {,5}.
flawr

2
Zamiast tego możesz dodać go jako flagę kompilatora, więc ma 72 bajty a język powinien zostać zmieniony na C # (Visual C # Interactive Compiler) z flagą/u:System.Text.RegularExpressions.Regex , tak jak ta odpowiedź :)
Kevin Cruijssen

3
Alternatywne wyrażenie regularne: ^M?M?M?(C[MD]|D?C?C?C?)(X[CL]|L?X?X?X?)(I[XV]|V?I?I?I?)$ . Ta sama długość, ale wygląda dziwniej (który jest celem, prawda?)
Embodiment of Ignorance

8

Wolfram Language (Mathematica) , 35 bajtów

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

Wypróbuj online!

5 bajtów zapisanych dzięki @attinat

ograniczenie [1,3999]niefortunnie kosztuje 7 bajtów ...
oto kod dla dowolnej liczby rzymskiej

Wolfram Language (Mathematica) , 28 bajtów

Check[FromRomanNumeral@#,F]&

Wypróbuj online!

powyższy kod działa dla dowolnej liczby, nie tylko [1,3999]


2
@ExpiredData „Dane wejściowe są niepustym ciągiem znaków, który zawiera tylko znaki IVXLCDM.”
matmandan

35 bajtów . Boolejest również krótszy (o jeden bajt) niż użycie Ifw ten sposób.
attinat

8

Zespół CP-1610 ( Intellivision ),  52 ... 48  47 DECLE 1 = 59 bajtów

Wypróbujmy to na systemie, który wyprzedza Perla o dobre 7 lat. :-)

Pobiera wskaźnik do łańcucha zakończonego znakiem NUL w R4 . Ustawia zero flagę jeśli dane wejściowe są prawidłową cyfrą rzymską, lub usuwa je w inny sposób.

                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

W jaki sposób?

Wyrażenie regularne może zostać przepisane jako 4 grupy o tej samej strukturze, pod warunkiem, że #jakikolwiek nieprawidłowy znak, który na pewno nie będzie obecny w ciągu wejściowym.

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

NN1(main_digit,second_suffix) .

Nasza rutyna próbuje przeanalizować wejściowy ciąg znaków po znaku zgodnie z tymi wzorami i ostatecznie sprawdza, czy osiągnięto koniec łańcucha.

Wynik

wynik

zrzut ekranu jzIntv


1. Kod operacyjny CP-1610 jest kodowany za pomocą 10-bitowej wartości, zwanej „DECLE”. Ta procedura ma długość 47 DECLE, zaczynając od 4876 $, a kończąc na 48A4 $ (w zestawie).


czy nie byłoby to jedno z niewielu miejsc, w których bajty ułamkowe ważne
tylko ASCII

@ Tylko ASCII Tak myślałem, ale nie jestem tego pewien. Zobacz komentarze do tej odpowiedzi, aby uzyskać wgląd w to.
Arnauld

@ Tylko ASCII Również właśnie znalazłem ten post w meta, który ma tendencję do potwierdzania, że ​​prawdopodobnie najlepiej jest zaokrąglać do pełnych bajtów.
Arnauld

ah, więc to tylko 10 bitów, gdy jest w pamięci RAM?
Tylko ASCII,

Program nigdy nie jest przechowywany w pamięci RAM, tylko w pamięci ROM. To zależy od układów pamięci używanych we wkładzie. Procesor jest zaprojektowany tak, aby uzyskać dostęp do 10-bitowej lub 16-bitowej pamięci ROM. Dyrektywa „ROMW 10” zmusza kompilator do generowania kodu w formacie 10-bitowym.
Arnauld

7

Java 8, 70 bajtów

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

Port @ Innat3 „s C # odpowiedzi , więc upewnij się, że go głosujesz!

Wypróbuj online.

Wyjaśnienie:

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 bajtów

Dzięki @RobinRyder, @Giuseppe, & @MickyT dla ich sugestie jak używać grep skutecznie R wbudowanego w as.roman.

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

Wypróbuj online!


as.romani tak nie będzie działać, ponieważ działa tylko z 3899jakiegoś powodu.
Giuseppe

Naprawdę powinienem lepiej przeczytać dokumentację, prawdopodobnie dlatego, że 4000 nie ma określonej reprezentacji w języku rzymskim, więc jak to zrobić 3900. To jest podobne do 390 i teraz właśnie znalazłem problem z moim grepem, w którym musiałbym zakotwicz wzór.
CT Hall

@Giuseppe, zaadresowany, używając tego samego wyrażenia regularnego, co inne odpowiedzi.
CT Hall

2
66 bajtów przy użyciu as.roman: najpierw Musuń inicjał, jeśli taki istnieje, a następnie sprawdź, czy wynik jest as.roman(1:2999). Wymaga to specjalnej obsługi przypadku, w którym znajduje się wejście M.
Robin Ryder

1
Moje ostatnie pytanie brzmi: kto do cholery zdecydował, romansże przydałaby się w R ??? Dodano go w wersji 2.5.0 (kwiecień 2007) ...
Giuseppe


2

Galaretka ,  48 47 46  44 bajtów

-1 dzięki Nickowi Kennedy'emu

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

IVXLCDM1139990

Wypróbuj online! Lub zobacz zestaw testowy .

W jaki sposób?

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

Wydaje się, że w pierwszej linii jest zbędne miejsce. Kolejny bajt. Kolejny bajt można zapisać, używając prostszej pierwszej linii. Wypróbuj online!
Nick Kennedy,

Dzięki, uratowałem jeszcze jeden.
Jonathan Allan

1

Perl 5 ( -p), 57 bajtów

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

TIO

  • używa prawie tego samego wyrażenia regularnego, z tym że {0,3}zmiennik kwantyfikatora został zmieniony przez*
  • &!/(.)\1{3}/ aby upewnić się, że ten sam znak nie może wystąpić 4 razy z rzędu.
  • Nie można golfed z -/(.)\1{3}/ponieważ dałoby -1na IIIIVIprzykład

1

Python 2 , 81 bajtów

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

Wypróbuj online!

Spójrzmy na ostatnią część wyrażenia regularnego, która odpowiada cyfrom rzymskim do 9 (w tym pusty ciąg znaków)

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

Ma dwie alternatywy oddzielone |:

  • V?I{,3}: Opcjonalny, Vpo którym następują maksymalnie 3 I. To dopasowuje pusty łańcuch I, II, III, V, VI, VII, VIII.
  • I[VX]: Po którym Inastępuje a Vlub X. To pasuje IVi IX.

To samo z X,L,Cdopasowywaniem dziesiątek, z dopasowywaniem C,D,Msetek, i na koniec ^M{,3}pozwala na 3 M(tysiące) na początku.

Próbowałem wygenerować szablon dla każdego trio znaków, zamiast pisać 3 razy, ale było to o wiele dłużej.


Na początku nie ma potrzeby używania ^kotwicy; matchjuż sugeruje, że pasuje na początku łańcucha.
ShadowRanger

@ShadowRanger Dzięki, usunąłem ^.
xnor

Chociaż myślę, że zawiodłeś liczbę w edycji; powinno być 83, a nie 81.
ShadowRanger

@ShadowRanger Liczba wynosi 81, ponieważ f=nie jest zawarta w kodzie, ponieważ dozwolone są funkcje anonimowe. To tylko dla TIO.
xnor

1
Ach, to ma sens. Irytujące, że nie ma sposobu na zorganizowanie tego, aby ukryć to w nagłówku lub stopce, ale tak, nieprzypisane lambdas są legalne, więc nieprzypisane powiązane metody skompilowanego wyrażenia regularnego również powinny być dobre.
ShadowRanger

1

Siatkówka , 56 51 bajtów

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

Port odpowiedzi Perla 5 na @NahuelFouilleul , więc upewnij się, aby go upvote!

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

(.)\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 bajtów

ŽF¯L.XIå

Solidny -52 bajtydzięki @Adnan , ponieważ najwyraźniej wbudowana liczba rzymska 05AB1E nie została udokumentowana, haha ​​.. xD

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

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

Zobacz moją wskazówkę 05AB1E (rozdział Jak kompresować duże liczby całkowite? ), Aby zrozumieć, dlaczego tak ŽF¯jest 3999.


Oryginalna 61 bajtów odpowiedź:

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

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

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)

Zobacz tę końcówkę 05AB1E kopalni (sekcje Jak kompresować strun nie jest częścią słownika? , Jak skompresować dużych liczb całkowitych? I jak skompresować list całkowitych? ) , Aby zrozumieć, dlaczego:

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

1
Nie jestem pewien, dlaczego .Xnie jest to udokumentowane, ale myślę, że to powinno działać:3999L.XQO
Adnan

@Adnan Haha, -52 bajtów tutaj. Zupełnie zapomniałeś, że rzeczywiście powiedziałeś nam o dodaniu wbudowanej liczby rzymskiej. Poprosi @ Mr.Xcoder na czacie o dodanie go do dokumentów. Czy brakuje innych poleceń? ;) PS: Zapisano kolejny bajt przez kompresję 3999. :)
Kevin Cruijssen

0

perl -MRegexp :: Common -pe, 34 bajty

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

Ta &!/(.)\1{3}/część jest konieczna, ponieważ Regexp::Commonpozwala na cztery (ale nie pięć) takich samych znaków z rzędu. W ten sposób dopasowuje cyfry rzymskie używane na tarczach zegara, gdzie IIIIczęsto stosuje się 4.


0

Python 3 , 116 113 109 107 105 106 bajtów

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)

Wypróbuj online!

-1 bajt dzięki ShadowRanger


2
Jak wspomniałem w odpowiedzi Py2, wiodące ^ jest zbędne, ponieważ matchpasuje już tylko na początku łańcucha.
ShadowRanger

@ShadowRanger dodał kotwice podczas debugowania, a następnie nie próbował ponownie bez nich. Teraz to zapamiętam - dzięki! :)
Noodle9

Cóż, dla jasności, trailing $jest konieczny ( fullmatchimplikuje tylko kotwice na obu końcach, i oczywiście kosztowałoby to więcej niż a $).
ShadowRanger

@ShadowRanger Ah! To wyjaśnia, dlaczego potrzebowałem kotwic! Nie zdawałem sobie sprawy, że muszę tylko zakotwiczyć koniec. Dzięki jeszcze raz.
Noodle9

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.