Сборка CP-1610 ( Intellivision ), 52 ... 48 47 DECLEs 1 = 59 байт
Давайте попробуем это на системе, которая предшествует Perl на хорошие 7 лет. :-)
Принимает указатель на завершающуюся нулем строку в R4 . Устанавливает флаг Zero, если ввод является действительным римским числом, или очищает его в противном случае.
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
NN−1(main_digit,second_suffix) .
Наша подпрограмма пытается проанализировать входную строку символ за символом в соответствии с этими шаблонами и в конечном итоге проверяет, достигнут ли конец строки.
Выход
скриншот jzIntv
1. Код операции CP-1610 кодируется 10-битным значением, известным как «DECLE». Эта процедура составляет 47 DECLE, начиная с 4876 долларов и заканчивая 48A4 (в комплекте).