Chữ số La Mã phù hợp


19

Thử thách

Đưa ra một số chuỗi đầu vào, trả về giá trị trung thực nếu nó đại diện cho một số La Mã chính xác trong khoảng từ 1 (= I) đến 3999 (= MMMCMXCIX) và giá trị falsey khác.

Chi tiết

  • Đầu vào là một chuỗi không trống chỉ bao gồm các ký tự IVXLCDM.
  • Các chữ số La Mã (mà chúng tôi sử dụng ở đây trong thử thách này) được định nghĩa như sau:

Chúng tôi chỉ sử dụng các ký hiệu sau:

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

Để xác định chuỗi nào là số La Mã thực sự hợp lệ, có thể dễ dàng nhất để cung cấp quy tắc hội thoại: Để viết một số thập phân a3 a2 a1 a0(trong đó mỗi chuỗi aiđại diện cho một chữ số. Ví dụ: để biểu thị 792chúng ta có a3=0, a2=7, a1=9, a0=2.) Là một chữ số La Mã, chúng tôi phân tách nó thành sức mạnh của hàng chục. Các quyền hạn khác nhau của mười có thể được viết như sau:

      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

Bắt đầu ở phía bên trái với chữ số có nghĩa nhất, chúng ta có thể chuyển đổi số mà mỗi chữ số thể hiện riêng biệt và ghép chúng lại. Vì vậy, với ví dụ từ phía trên, nó sẽ trông như vậy:

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

Do đó, chữ số La Mã cho 792DCCXCII. Dưới đây là danh sách đầy đủ tất cả các chữ số La Mã có liên quan đến thử thách này: OEIS a006968.txt

Ví dụ

Sự thật

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

Falsey

MMIXVIII
IVX
IXV
MMMM
XXXVX
IVI
VIV

Tập hợp con của thách thức chuyển đổi này .
Xù xì

Tôi vẫn không nghĩ rằng điều này đủ điều kiện là một "tập hợp con" vì tập hợp các đầu vào không hợp lệ là lớn hơn. Thử thách này ở đây chỉ đề cập đến các số được xác định "tốt" được sử dụng trong OEIS A006968
flawr

2
Tại sao MMMMkhông hợp lệ? Có thư nào cho 5000 nên được sử dụng thay cho M <letter> không?
Skyler

Kiểm tra các thông số kỹ thuật, không có thư như vậy. Các biểu tượng duy nhất được sử dụng là I,V,X,L,C,D,M.
flawr

Câu trả lời:


17

Verbose , 1362 byte

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

Đầu ra Icho các chữ số La Mã hợp lệ trong phạm vi I-MMMCMXCIXNULLA(0) hoặc thông báo đầu vào của người dùng không phải là một chữ số La Mã hợp lệ.


12
Tôi không thể quyết định liệu đây có phải là công cụ phù hợp cho công việc hay không.
Vaelus

5
Đây có phải là công cụ phù hợp cho bất kỳ công việc?
omzrs

8

C # (Trình biên dịch tương tác Visual C #) , 79 109 byte

Đây dường như là một thử thách Regex, tôi chắc chắn có thể tìm ra giải pháp ngắn hơn ...

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

Hãy thử trực tuyến!


Bạn không thể rút ngắn {0,3}tới {,3}?
flawr

@flawr dường như không nắm bắt được bất cứ điều gì sau đó
Innat3

1
Ah xin lỗi, chỉ những thứ như {5,}công việc, nhưng không {,5}.
flawr

2
Thay vào đó, bạn có thể thêm nó làm cờ trình biên dịch, vì vậy, đó là 72 byte và ngôn ngữ nên được đổi thành C # (Trình biên dịch tương tác Visual C #) với cờ/u:System.Text.RegularExpressions.Regex , như câu trả lời này :)
Kevin Cruijssen

3
Regex thay thế : ^M?M?M?(C[MD]|D?C?C?C?)(X[CL]|L?X?X?X?)(I[XV]|V?I?I?I?)$. Cùng chiều dài, nhưng trông lạ hơn (đó là mục tiêu, phải không?)
Hiện thân của sự thiếu hiểu biết

8

Ngôn ngữ Wolfram (Mathicala) , 35 byte

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

Hãy thử trực tuyến!

Đã lưu 5 byte, nhờ @attinat

giới hạn [1,3999]unfortunateley có giá 7 byte ...
đây là mã cho bất kỳ số La Mã nào

Ngôn ngữ Wolfram (Mathicala) , 28 byte

Check[FromRomanNumeral@#,F]&

Hãy thử trực tuyến!

đoạn mã trên hoạt động với mọi số, không chỉ [1,3999]


2
@ExpiredData "Đầu vào là một chuỗi không trống chỉ bao gồm các ký tự IVXLCDM."
mathmandan

35 byte . Boolecũng ngắn hơn (bằng một byte) so với sử dụng Iftheo cách đó.
attinat

8

Lắp ráp CP-1610 ( Intellivision ),  52 ... 48  47 DECLE 1 = 59 byte

Hãy thử điều này trên một hệ thống có trước Perl 7 năm. :-)

Đưa một con trỏ tới một chuỗi kết thúc null trong R4 . Đặt cờ Zero nếu đầu vào là một chữ số La Mã hợp lệ hoặc xóa nó đi.

                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

Làm sao?

Biểu thức chính quy có thể được viết lại thành 4 nhóm có cùng cấu trúc, với điều kiện #là bất kỳ ký tự không hợp lệ nào được đảm bảo không có trong chuỗi đầu vào.

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

Thường trình của chúng tôi cố gắng phân tích ký tự chuỗi đầu vào theo ký tự theo các mẫu này và cuối cùng kiểm tra xem có kết thúc chuỗi không.

Đầu ra

đầu ra

ảnh chụp màn hình của jzIntv


1. Mã op CP-1610 được mã hóa với giá trị 10 bit, được gọi là 'DECLE'. Thủ tục này dài 47 DECLE, bắt đầu từ $ 4876 và kết thúc ở mức $ 48A4 (bao gồm).


điều này sẽ không thể là một trong số ít những nơi byte phân đoạn hợp lệ
ASCII chỉ

@ ASCII - chỉ tôi đã từng nghĩ như vậy, nhưng tôi không biết chắc chắn. Xem ý kiến của câu trả lời này cho một số cái nhìn sâu sắc về điều này.
Arnauld

Chỉ @ ASCII Ngoài ra, tôi vừa tìm thấy bài đăng này trong meta có xu hướng xác nhận có lẽ tốt nhất để làm tròn đến toàn bộ byte.
Arnauld

ah, vậy nó chỉ còn 10 bit khi ở trong RAM?
ASCII - chỉ

Chương trình không bao giờ được lưu trữ trong RAM, chỉ trong ROM. Vì vậy, nó phụ thuộc vào các chip bộ nhớ được sử dụng trong hộp mực. CPU được thiết kế để truy cập ROM 10 bit hoặc 16 bit. Lệnh "ROMW 10" buộc trình biên dịch tạo mã ở định dạng 10 bit.
Arnauld

7

Java 8, 70 byte

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

Câu trả lời C # của cảng @ Innat3 , vì vậy hãy đảm bảo nâng cao anh ấy!

Hãy thử trực tuyến.

Giải trình:

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 byte

Cảm ơn @RobinRyder, @Giuseppe và @MickyT vì những gợi ý của họ về cách sử dụng grep hiệu quả với R được tích hợp as.roman.

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

Hãy thử trực tuyến!


as.romanDù sao cũng không hoạt động, vì nó chỉ hoạt động 3899vì một số lý do.
Giuseppe

Tôi thực sự nên đọc tài liệu tốt hơn, Có lẽ vì 4000 không có đại diện xác định bằng tiếng La Mã, nên làm thế nào một người làm 3900. Điều này tương tự với 390 và bây giờ tôi chỉ thấy một vấn đề với grep của mình, nơi tôi phải neo mô hình.
Hội trường CT

@Giuseppe, được giải quyết, sử dụng regex giống như các câu trả lời khác.
Hội trường CT

2
66 byte bằng cách sử dụng as.roman: đầu tiên tước dải ban đầu Mnếu có, sau đó kiểm tra xem kết quả có trong đó không as.roman(1:2999). Điều này đòi hỏi xử lý đặc biệt của trường hợp đầu vào M.
Robin Ryder

1
Câu hỏi cuối cùng của tôi là, ai đã quyết định rằng đó romanssẽ là một điều hữu ích để đưa vào R ??? Nó đã được thêm vào 2.5.0 (tháng 4 năm 2007) ...
Giuseppe


2

Thạch ,  48 47 46  44 byte

-1 cảm ơn Nick Kennedy

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

IVXLCDM1139990

Hãy thử trực tuyến! Hoặc xem bộ thử nghiệm .

Làm sao?

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

Dường như có một không gian dư thừa trên dòng đầu tiên. Một byte khác. Một byte khác có thể được lưu bằng cách sử dụng một dòng đầu tiên đơn giản hơn. Hãy thử trực tuyến!
Nick Kennedy

Cảm ơn, tôi đã lưu thêm một từ nó.
Jonathan Allan

1

Perl 5 ( -p), 57 byte

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

TIO

  • sử dụng gần như cùng một biểu thức chính quy trừ bộ {0,3}định lượng đã được thay đổi bởi*
  • &!/(.)\1{3}/ để đảm bảo cùng một nhân vật không thể xảy ra 4 lần liên tiếp.
  • không thể golfed với -/(.)\1{3}/vì sẽ cung cấp -1cho IIIIVIví dụ

1

Python 2 , 81 byte

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

Hãy thử trực tuyến!

Chúng ta hãy xem phần cuối của biểu thức chính, khớp với các chữ số La Mã lên đến 9 (bao gồm cả chuỗi trống)

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

Điều này có hai lựa chọn thay thế bởi |:

  • V?I{,3}: Một tùy chọn Vtheo sau lên đến 3 I's. Này phù hợp với chuỗi rỗng I, II, III, V, VI, VII, VIII.
  • I[VX]: An Itheo sau bởi một Vhoặc X. Điều này phù hợp IVIX.

Điều tương tự với X,L,Ckhớp hàng chục, C,D,Mkhớp với hàng trăm và cuối cùng ^M{,3}cho phép tối đa 3 M(hàng nghìn) khi bắt đầu.

Tôi đã thử tạo mẫu cho mỗi bộ ba ký tự thay vì viết nó 3 lần, nhưng điều này dài hơn rất nhiều.


Không cần ^neo khi bắt đầu; matchđã ngụ ý nó khớp ở đầu chuỗi.
ShadowRanger

@ShadowRanger Cảm ơn, tôi đã xóa ^.
xnor

Mặc dù tôi nghĩ rằng bạn đã làm hỏng số đếm trong bản chỉnh sửa; nên là 83, không phải 81.
ShadowRanger

@ShadowRanger Số đếm là 81 vì f=không được bao gồm trong mã do các hàm anonynomous được cho phép. Nó chỉ dành cho TIO.
xnor

1
Ah, có ý nghĩa. Làm phiền không có cách nào để tổ chức nó để che giấu điều đó trong phần đầu trang hoặc chân trang, nhưng vâng, lambdas chưa được gán là hợp pháp, vì vậy các phương thức ràng buộc không được gán của regex cũng sẽ tốt.
ShadowRanger

1

Võng mạc , 56 51 byte

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

Cổng câu trả lời Perl 5 của @NahuelFouilleul , vì vậy hãy đảm bảo nâng cao anh ấy!

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

(.)\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 byte

ŽF¯L.XIå

-52 bytes

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

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

Xem 05AB1E mẹo này của tôi (phần Làm thế nào để nén các số nguyên lớn? ) Để hiểu tại sao ŽF¯3999.


Câu trả lời gốc 61 byte:

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

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

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)

Xem mẹo 05AB1E này của tôi (phần Làm thế nào để chuỗi nén không nằm trong từ điển? , Làm thế nào để nén các số nguyên lớn?Làm thế nào để liệt kê số nguyên nén? ) Để hiểu tại sao:

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

1
Tôi không chắc tại sao .Xkhông được ghi lại, nhưng tôi nghĩ nó sẽ hoạt động:3999L.XQO
Adnan

@Adnan Haha, -52 byte ngay tại đó. Hoàn toàn quên bạn thực sự đã nói với chúng tôi về việc thêm một số La Mã dựng sẵn. Sẽ yêu cầu @ Mr.Xcoder trong trò chuyện để thêm nó vào tài liệu. Có thiếu lệnh nào khác không? ;) PS: Đã lưu một byte khác bằng cách nén 3999. :)
Kevin Cruijssen

0

perl -MRegapi :: Common -pe, 34 byte

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

Phần &!/(.)\1{3}/này là cần thiết, vì Regexp::Commoncho phép bốn (nhưng không phải năm) của cùng một ký tự. Bằng cách đó, nó khớp với các số la mã được sử dụng trên các mặt đồng hồ, nơi IIIIthường được sử dụng cho 4.


0

Python 3 , 116 113 109 107 105 106 byte

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)

Hãy thử trực tuyến!

-1 byte nhờ ShadowRanger


2
Như tôi đã đề cập trong câu trả lời Py2, việc dẫn đầu ^ là không cần thiết vì matchchỉ khớp ở đầu chuỗi.
ShadowRanger

@ShadowRanger đã thêm các neo trong khi gỡ lỗi và sau đó không thử lại mà không có chúng. Bây giờ tôi sẽ nhớ điều đó - cảm ơn! :)
Noodle9

Chà, để rõ ràng, việc theo dõi $là cần thiết (chỉ fullmatchngụ ý neo ở cả hai đầu, và rõ ràng điều đó sẽ có giá cao hơn a $).
ShadowRanger

@ShadowRanger À! Điều đó giải thích tại sao tôi cần neo! Không nhận ra tôi chỉ cần neo cuối cùng. Cảm ơn một lần nữa.
Noodle9

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.