ตรงกับตัวเลขโรมัน


19

ท้าทาย

รับสตริงอินพุตบางตัวส่งคืนค่าความจริงถ้ามันแสดงถึงตัวเลขโรมันที่ถูกต้องระหว่าง 1 (= I) และ 3999 (= MMMCMXCIX) และค่าเท็จเป็นอย่างอื่น

รายละเอียด

  • อินพุตเป็นสตริงที่ไม่ว่างซึ่งประกอบด้วยอักขระIVXLCDMเท่านั้น
  • ตัวเลขโรมัน (ที่เราใช้ที่นี่ในการท้าทายนี้) ถูกกำหนดดังนี้:

เราใช้สัญลักษณ์ต่อไปนี้เท่านั้น:

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

การกําหนดซึ่งสตริงเลขโรมันที่ถูกต้องจริงก็อาจจะง่ายที่สุดในการให้กฎของการสนทนา: การเขียนจำนวนทศนิยมa3 a2 a1 a0(ซึ่งแต่ละai. เป็นหนึ่งในหลักดังนั้นสำหรับตัวอย่างเพื่อเป็นตัวแทนของ792เรามีa3=0, a2=7, a1=9, a0=2.) เป็นเลขโรมันเราย่อยสลายมัน เข้าสู่พลังของสิบ พลังที่แตกต่างกันของสิบสามารถเขียนได้ดังนี้:

      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

เริ่มต้นที่ด้านซ้ายด้วยตัวเลขที่สำคัญที่สุดของเราสามารถแปลงตัวเลขที่แต่ละหลักแสดงแยกจากกันและต่อเข้าด้วยกัน ดังนั้นสำหรับตัวอย่างจากด้านบนนี้จะมีลักษณะดังนี้:

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

ดังนั้นตัวเลขโรมันที่เป็น792 DCCXCIIนี่คือรายการตัวเลขโรมันทั้งหมดที่เกี่ยวข้องกับความท้าทายนี้: OEIS a006968.txt

ตัวอย่าง

Truthy

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

Falsey

MMIXVIII
IVX
IXV
MMMM
XXXVX
IVI
VIV

ระบบย่อยของความท้าทายที่แปลงนี้
Shaggy

ฉันยังไม่คิดว่าคุณสมบัตินี้เป็น "ชุดย่อย" เนื่องจากชุดของอินพุตที่ไม่ถูกต้องมีขนาดใหญ่กว่า ความท้าทายนี้ที่นี่หมายถึงตัวเลข "ดี" ที่กำหนดไว้ซึ่งใช้ใน OEIS A006968
ข้อบกพร่อง

2
ทำไมจึงMMMMไม่ถูกต้อง มีตัวอักษรสำหรับ 5000 ที่ควรใช้แทน M <letter> หรือไม่?
Skyler

ตรวจสอบรายละเอียดไม่มีจดหมายดังกล่าว I,V,X,L,C,D,Mสัญลักษณ์ที่ใช้เป็นเพียง
ข้อบกพร่อง

คำตอบ:


17

Verboseขนาด 1362 ไบต์

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

เอาต์พุตIสำหรับตัวเลขโรมันที่ถูกต้องในช่วงI-MMMCMXCIXและNULLA(0) หรือแจ้งให้ผู้ใช้ทราบว่าไม่ใช่ตัวเลขโรมันที่ถูกต้อง


12
ฉันไม่สามารถตัดสินใจได้ว่านี่เป็นเครื่องมือที่เหมาะสมสำหรับงานหรือไม่
Vaelus

5
นี่เป็นเครื่องมือที่เหมาะสมสำหรับงานใด ๆ หรือไม่?
omzrs

8

C # (Visual C # Interactive Compiler) , 79 109 ไบต์

ดูเหมือนว่าจะเป็นความท้าทายของ Regex ฉันแน่ใจว่าจะสามารถพบโซลูชันที่สั้นกว่านี้ ...

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

ลองออนไลน์!


คุณไม่สามารถร่น{0,3}ไป{,3}?
ข้อบกพร่อง

@flawr ดูเหมือนจะไม่จับอะไรเลยแล้ว
Innat3

1
อาขอโทษสิ่งเดียวที่ต้องการ{5,}ทำงาน {,5}แต่ไม่ได้
ข้อบกพร่อง

2
คุณสามารถเพิ่มมันเป็นธงคอมไพเลอร์แทนดังนั้นจึงเป็น72 ไบต์และภาษาควรเปลี่ยนเป็นC # (Visual C # Interactive คอมไพเลอร์) ที่มีธง/u:System.Text.RegularExpressions.Regexเช่นคำตอบนี้ :)
47420 Kevin

3
regex ^M?M?M?(C[MD]|D?C?C?C?)(X[CL]|L?X?X?X?)(I[XV]|V?I?I?I?)$สำรอง: ความยาวเท่ากัน แต่ดูแย่ลง (ซึ่งเป็นเป้าหมายใช่มั้ย)
ศูนย์รวมแห่งความไม่รู้

8

ภาษา Wolfram (Mathematica) , 35 ไบต์

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

ลองออนไลน์!

บันทึก 5 ไบต์ด้วย @attinat

ข้อ จำกัด[1,3999]unuckyateley ค่าใช้จ่าย 7 ไบต์ ...
นี่คือรหัสสำหรับหมายเลขโรมันใด ๆ

ภาษา Wolfram (Mathematica)ขนาด 28 ไบต์

Check[FromRomanNumeral@#,F]&

ลองออนไลน์!

โค้ดด้านบนใช้ได้กับทุกหมายเลขไม่ใช่แค่ [1,3999]


2
@ExpiredData "อินพุตเป็นสตริงที่ไม่ว่างซึ่งประกอบด้วยอักขระIVXLCDMเท่านั้น"
คณิตศาสตร์

35 ไบต์ Booleก็สั้น (โดยหนึ่งไบต์) กว่าการใช้Ifวิธีนี้
attinat

8

ชุดประกอบCP-1610 ( Intellivision ),  52 ... 48  47 DECLEs 1 = 59 ไบต์

ลองทำสิ่งนี้ในระบบที่ Perl ลงวันที่ล่วงหน้า 7 ปี :-)

นำตัวชี้ไปยัง null สายในR4 ตั้งค่าสถานะเป็นศูนย์หากอินพุตเป็นตัวเลขโรมันที่ถูกต้องหรือล้างค่าเป็นอย่างอื่น

                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

อย่างไร?

การแสดงออกปกติสามารถเขียนใหม่เป็น 4 กลุ่มที่มีโครงสร้างเดียวกันโดยมีเงื่อนไขว่า#เป็นอักขระที่ไม่ถูกต้องใด ๆ ที่รับประกันว่าจะไม่ปรากฏในอินพุตสตริง

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

ต่อท้ายครั้งแรกของกลุ่มเป็นหลักหลักของกลุ่มN-1ดังนั้นเราสามารถเก็บรูปแบบได้ด้วยการจับคู่เพียงอย่างเดียวNN - 1 ( main_digit , second_suffix )N1(main_digit,second_suffix)

รูทีนของเราพยายามแยกอักขระสตริงอินพุตตามอักขระตามรูปแบบเหล่านี้และในที่สุดตรวจสอบว่าถึงจุดสิ้นสุดของสตริงหรือไม่

เอาท์พุต

เอาท์พุต

สกรีนช็อตของjzIntv


1. CP-1610 opcode ถูกเข้ารหัสด้วยค่า 10 บิตหรือที่เรียกว่า 'DECLE' รูทีนนี้มีความยาว 47 DECLE เริ่มต้นที่ $ 4876 และสิ้นสุดที่ $ 48A4 (รวมอยู่ด้วย)


นี่จะไม่ใช่หนึ่งในไม่กี่แห่งที่มีเศษส่วนที่ถูกต้อง
ASCII เท่านั้นเท่านั้น

@ ASCII- อย่างเดียวที่ฉันเคยคิด แต่ฉันไม่รู้แน่ ดูความคิดเห็นของคำตอบนี้สำหรับข้อมูลเชิงลึกเกี่ยวกับเรื่องนี้
Arnauld

@ ASCII- เท่านั้นนอกจากนี้ฉันเพิ่งพบโพสต์นี้ในเมตาซึ่งมีแนวโน้มที่จะยืนยันว่าอาจดีที่สุดในการปัดเศษเป็นไบต์ทั้งหมด
Arnauld

อาดังนั้นมันแค่ 10 บิตเมื่อมันอยู่ใน RAM?
ASCII เท่านั้นเท่านั้น

โปรแกรมไม่เคยถูกเก็บไว้ใน RAM เฉพาะใน ROM ดังนั้นจึงขึ้นอยู่กับชิปหน่วยความจำที่ใช้ในตลับ CPU ถูกออกแบบมาเพื่อเข้าถึง ROM 10 บิตหรือ 16 บิต คำสั่ง "ROMW 10" บังคับให้คอมไพเลอร์สร้างรหัสในรูปแบบ 10 บิต
Arnauld

7

Java 8, 70 ไบต์

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 #ของ Port of @ Innat3ดังนั้นอย่าลืม upvote เขา!

ลองออนไลน์

คำอธิบาย:

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 ไบต์

ขอขอบคุณที่ @RobinRyder, @Giuseppe และ @MickyT สำหรับข้อเสนอแนะวิธีการใช้งานได้อย่างมีประสิทธิภาพ grep กับ R as.romanในตัวของ

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

ลองออนไลน์!


as.romanจะไม่ทำงานเนื่องจากจะใช้งานได้3899ด้วยเหตุผลบางอย่างเท่านั้น
จูเซปเป้

ฉันควรอ่านเอกสารให้ดีกว่านี้น่าจะเป็นเพราะ 4000 ไม่มีตัวแทนที่ชัดเจนในภาษาโรมันดังนั้นคนที่ทำ 3900 จะเป็นอย่างไรซึ่งคล้ายกับ 390 และตอนนี้ฉันเพิ่งพบปัญหากับ grep ที่ฉันต้อง ยึดรูปแบบ
CT Hall

@Giuseppe ได้รับการจัดการโดยใช้ regex เดียวกันกับคำตอบอื่น ๆ
CT Hall

2
66 bytes using as.roman: ก่อนอื่นให้เริ่มต้นMถ้ามีให้ตรวจสอบว่าผลลัพธ์นั้นมีอยู่as.roman(1:2999)หรือไม่ Mเรื่องนี้ต้องมีการจัดการพิเศษของกรณีที่ใส่เป็น
Robin Ryder

1
คำถามสุดท้ายของฉันคือผู้ที่ heck ตัดสินใจว่าromansจะเป็นประโยชน์ในการใส่ R ??? มันถูกเพิ่มเข้ามาใน 2.5.0 (เมษายน 2550) ...
Giuseppe


2

เยลลี่ ,  48 47 46  44 ไบต์

-1 ต้องขอบคุณ Nick Kennedy

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

IVXLCDM1139990

ลองออนไลน์! หรือดูการทดสอบในตัว

อย่างไร?

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

ดูเหมือนว่าจะมีพื้นที่ซ้ำซ้อนในบรรทัดแรก อีกไบต์ สามารถบันทึกไบต์อื่นได้โดยใช้บรรทัดแรกที่ง่ายกว่า ลองออนไลน์!
Nick Kennedy

ขอบคุณฉันบันทึกอีกหนึ่งอย่างจากมันแล้ว
Jonathan Allan

1

Perl 5 ( -p), 57 ไบต์

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

TIO

  • ใช้การแสดงออกปกติเกือบเหมือนกันยกเว้น{0,3}ตัวเปลี่ยนปริมาณถูกเปลี่ยนโดย*
  • &!/(.)\1{3}/ เพื่อให้แน่ใจว่าอักขระตัวเดียวกันไม่สามารถเกิดขึ้นได้ 4 ครั้งในแถว
  • ไม่สามารถแข็งแรงเล่นกอล์ฟด้วย-/(.)\1{3}/เพราะจะให้-1สำหรับIIIIVIตัวอย่างเช่น

1

Python 2 , 81 ไบต์

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

ลองออนไลน์!

ลองดูที่ส่วนสุดท้ายของ regex ซึ่งจับคู่ตัวเลขโรมันมากถึง 9 (รวมถึงสตริงว่าง)

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

สิ่งนี้มีสองทางเลือกคั่นด้วย|:

  • V?I{,3}: เลือกVตามมาด้วยถึง 3 I's นี้ตรงกับสตริงที่ว่างเปล่าI, II, III, V, VI, ,VIIVIII
  • I[VX]: มีIตามมาด้วยหรือV Xแมตช์นี้และIVIX

สิ่งเดียวกันกับการX,L,Cจับคู่หลักสิบและC,D,Mตรงกับหลักร้อยและในที่สุดก็^M{,3}อนุญาตให้มากถึง 3 M(พัน) ในตอนเริ่มต้น

ฉันพยายามสร้างเทมเพลตสำหรับแต่ละตัวละครสามตัวแทนที่จะเขียน 3 ครั้ง แต่นี่ก็นานกว่ามาก


ไม่จำเป็นต้องมี^สมอในตอนแรก matchแสดงถึงการจับคู่แล้วที่จุดเริ่มต้นของสตริง
ShadowRanger

@ShadowRanger ^ขอบคุณฉันออก
xnor

แม้ว่าฉันคิดว่าคุณทำให้การนับในการแก้ไขมีความสับสน ควรเป็น 83 ไม่ใช่ 81
ShadowRanger

@ShadowRanger การนับเป็น 81 เพราะf=ไม่รวมอยู่ในรหัสเนื่องจากอนุญาตให้ใช้ฟังก์ชันแบบไม่ระบุชื่อได้ มันเป็นเพียงสำหรับ TIO
xnor

1
อ่าเหมาะสมแล้ว น่ารำคาญไม่มีวิธีจัดระเบียบเพื่อซ่อนไว้ในหัวกระดาษหรือท้ายกระดาษ แต่ใช่ผู้รับที่ไม่ได้กำหนดlambdaนั้นถูกกฎหมายดังนั้นวิธีการผูกมัดของ regex ที่ไม่ได้กำหนดจึงควรจะดีเช่นกัน
ShadowRanger

1

เรติน่า56 56ไบต์

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

พอร์ตของ@NahuelFouilleul Perl 5 คำตอบดังนั้นอย่าลืมโหวตให้เขา!

ลองมันออนไลน์หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย:

(.)\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 ไบต์

ŽF¯L.XIå

-52 bytes

ลองมันออนไลน์หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย:

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

ดู 05AB1E นี้เคล็ดลับของฉัน (ส่วนวิธีการบีบอัดจำนวนเต็มขนาดใหญ่? )จะเข้าใจว่าทำไมเป็นŽF¯3999


คำตอบ 61 ไบต์ดั้งเดิม:

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

ลองมันออนไลน์หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย:

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)

ดูที่ส่วนปลายของฉัน 05AB1E นี้ (ส่วนวิธีการบีบอัดสตริงที่ไม่ได้เป็นส่วนหนึ่งของพจนานุกรม , จะบีบอัดจำนวนเต็มขนาดใหญ่ได้อย่างไรและวิธีบีบอัดรายการจำนวนเต็ม? )เพื่อทำความเข้าใจว่าทำไม:

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

1
ฉันไม่แน่ใจว่าทำไม.Xไม่มีการบันทึก แต่ฉันคิดว่าสิ่งนี้จะทำงาน:3999L.XQO
Adnan

@Adnan Haha, -52 ไบต์อยู่ที่นั่น ลืมไปแล้วว่าคุณบอกเราอย่างสมบูรณ์เกี่ยวกับการเพิ่มหมายเลขโรมันในตัว จะถาม @ Mr.Xcoder ในการแชทเพื่อเพิ่มลงในเอกสาร คำสั่งอื่น ๆ หายไปหรือไม่ ;) PS: 3999บันทึกไว้ไบต์อื่นโดยการบีบอัด :)
Kevin Cruijssen

0

perl -MRegexp :: Common -pe, 34 bytes

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

&!/(.)\1{3}/ส่วนหนึ่งเป็นสิ่งที่จำเป็นเพราะRegexp::Commonจะช่วยให้สี่ ( แต่ไม่ห้า) ของตัวอักษรเดียวกันในแถว ด้วยวิธีนี้จะจับคู่หมายเลขโรมันที่ใช้กับหน้าปัดนาฬิกาซึ่งIIIIมักใช้สำหรับ 4


0

Python 3 , 116 113 109 107 105 106 106 ไบต์

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)

ลองออนไลน์!

-1 ไบต์ด้วย ShadowRanger


2
ดังที่ฉันพูดถึงคำตอบ Py2 ผู้นำ^ ไม่จำเป็นเนื่องจากmatchมีเพียงการจับคู่ที่จุดเริ่มต้นของสตริงแล้ว
ShadowRanger

@ShadowRanger เพิ่มจุดยึดขณะดีบักแล้วไม่ลองอีกครั้งหากไม่มีพวกเขา ฉันจะจำได้ตอนนี้ - ขอบคุณ! :)
ก๋วยเตี๋ยว 9

เอาล่ะชัดเจนว่าการลาก$เป็นสิ่งที่จำเป็น ( fullmatchหมายถึงเพียงจุดยึดที่ปลายทั้งสองและแน่นอนว่าจะมีราคาสูงกว่า a $)
ShadowRanger

@ShadowRanger Ah! นั่นอธิบายว่าทำไมฉันถึงต้องการสมอ! ไม่ได้ตระหนักว่าฉันแค่ต้องการยึดเกาะท้ายเท่านั้น ขอบคุณอีกครั้ง.
ก๋วยเตี๋ยว 9

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.