로마에있을 때 로마인처럼 카운트? 수 없습니다. D, L 및

배경

이 과제는 다음 다이어그램을 게시 한이 웹 사이트에서 영감을 얻은 것입니다 .

여기에 이미지 설명을 입력하십시오

이 다이어그램은 250 미만의 가장 긴 로마 숫자 표현이 188의 표현이므로 9 개의 숫자가 필요하다는 것을 보여줍니다.

도전

가장 로마 숫자를 표현하기 위해 사용되는 표준 기호는 다음과 같다 : { I, V, X, L, C, D, M}, 문자 ‘수치는 어디 M= 1000, D= 500, C= 100, L= 50, X= 10, V= 5 I= 1.

이 과제에서 목표는 양의 정수 n이 주어지면 n 개의 표준 심볼 을 연결하여 구성 할 수있는 유효한 로마 숫자 표현의 수를 계산하는 것 입니다.

그런 다음 프로그램에서이 계산 결과를 출력해야합니다!

입력 : 양의 정수 n .

출력 : 길이 n 의 유효한 로마 숫자 표현의 수 .

로마 숫자 표현 규칙

로마 숫자는 원래 “첨가”쌍만 있었으며 숫자는 항상 내림차순으로 작성되었으며 모든 숫자 값의 합은 숫자 값이었습니다.

나중에, 빼기 쌍화에서 더 작은 것을 더 크게 빼기 위해 더 큰 숫자 앞에 더 큰 숫자를 배치하는 것은 로마 숫자 표현을 단축하는 흔한 일이되었습니다. 다음과 같은 잘못된 식과 같이 빼기 쌍을 연결할 수 없습니다 IXL.

다음은 가산 및 감산 페어링에 대한 최신 규칙입니다.

  1. 빼기 쌍의 일부에서 선행 숫자로 하나의 I, X 및 C 만 사용할 수 있습니다.
  2. 빼기 쌍으로 V 또는 X 앞에만 배치 할 수 있습니다.
  3. X는 빼기 쌍에서 L 또는 C 앞에만 배치 할 수 있습니다.
  4. C는 빼기 쌍에서 D 또는 M 앞에만 배치 할 수 있습니다.
  5. 빼기 쌍 이외의 숫자는 내림차순이어야합니다 (즉, 각 빼기 쌍의 선행 숫자를 삭제하면 숫자가 내림차순 임).
  6. M, C 및 X는 더 작은 단위로 같거나 초과 할 수 없습니다.
  7. D, L 및 V는 각각 한 번만 나타날 수 있습니다.
  8. M 만 4 번 이상 반복 할 수 있습니다.

추가 사항

  • 우리는 막대 표기법을 사용하지 않을 것입니다 . 오히려, 우리는 단순히 숫자를 표현하기 위해 더 많은 M을 추가 할 것 입니다.

  • 이것이 로마 숫자에 대해 따를 유일한 규칙입니다. 즉,와 같은 이상한 표현 IVI도 시스템에서 유효한 것으로 간주됩니다.

  • 또한 일부 숫자는 여러 개의 표현식을 가지므로 길이 n의 표현식을 갖는 숫자의 수는 계산하지 않습니다 . 대신, 우리는 단지 유효한 표현의 수를 세고 있습니다.

테스트 사례

17

231

3105

위의 내용을 직접 확인 했으므로 테스트 사례를 다시 확인하고 가능한 경우 추가하십시오.

승리 기준

이것은 도전이므로 재미있게 보내십시오! 적어도 1에서 9까지의 입력을 처리 할 수있는 솔루션 만 허용합니다. 더 이상 보너스입니다!

편집하다

주석 작성자의 요청에 따라 아래 또는이 pastebin 링크에서 n = 3으로 계산 한 105 콤보를 찾으십시오.

III IVI IXI IXV IXX VII XII XIV XIX XVI XXI XXV XXX XLI XLV XLX XCI XCV XCX XCL XCC LII LIV LIX LVI LXI LXV LXX CII CIV CIX CVI CXI CXV CXX CXL CXC CLI CLV CLX CCI CCV CCX CCL CDCC CD CD CDC CD CD CDC CD CDC CD CDC CD CDC CD CD CDC CD CDC CD CDC CD CDC CD CDC CD CDC CD CMI CMV CMX CML CMC CMD CMM DII DIV DIX DVI DXI DXV DXX DXL DXC DLI DLV DLX DCI DCV DCX DCL DCC MII MIV MIX MVI MXI MXV MXX MXL MXC MLI MLV MLX MCI MCV MCX MCL MCC MCD MCM MDI MDV MDX MDL MDC MMX MML MMC MMD MMM

편집 2 :

Jonathan Allan이 제공 한 다음 골프 공 코드를 사용 하여 결과를 확인하십시오.

편집 3 :

이 과제의 모든 오류에 대해 사과드립니다. 다음에 더 나은 일을하도록하겠습니다!



답변

망막 , 111 바이트

~(`.+
*$(CM)CDXCXCXCXLIXIXIXIVII
.(.)
.+¶$$&$¶$$&$1$¶$$&$&¶L`.{0,$+}\b¶D`¶
¶$
¶.+¶$$&$¶$$&I¶L`[A-Z]{$+}\b¶D`¶.+

온라인으로 사용해보십시오! 난 당신이 하나의 감산 각각 사용할 수 있다는 것을 의미하는 1을 지배 오해 이것은 완전한 재 작성 I, XC. 설명 : 스크립트의 첫 번째 부분은 입력을 한 CM쌍 의 문자열로 확장 한 후 다른 가능한 빼기 쌍으로 확장합니다. 각 쌍은 선택 사항이며 각 쌍의 첫 문자도 쌍 내에서 선택 사항입니다. 그런 다음 세 번째 단계에서는 쌍 목록을 Retina 명령 목록으로 확장하여 입력을 받고 쌍에서 두 번째 또는 두 문자 옵션을 사용하여 세 개의 사본을 만든 다음 결과를 자르고 중복 제거합니다. 마지막 단계에서는 최종 작업을 수행하기위한 코드를 추가합니다. 먼저 입력을 확장하여 최종 작업을 추가합니다.I그런 다음 잘못된 길이의 결과를 필터링 한 다음 결과를 중복 제거하고 결과를 계산합니다. 결과 Retina 스크립트가 평가됩니다.

참고 : 이론 상으로는 4 번째 줄 끝에서 15 바이트를 저장할 수 있지만이 경우에도 스크립트가 TIO에서 시연하기에는 너무 느립니다 n=1.


답변

파이썬 2 , 177168162 바이트

import re,itertools as q
f=lambda n:sum(None!=re.match("^M*(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$",(''.join(m)))for m in q.product('MDCLXVI',repeat=n))

온라인으로 사용해보십시오!

나는 아주 새롭고, 이것을 도와주세요! 이것은 실제 로마 숫자를 확인합니다. 정규식은IVI

@Dead Possum 덕분에 -9 바이트 !

-6 바이트@ovs 덕분에


답변

자바 스크립트 (ES7), 133 바이트

편집 : Jonathan Allan의 코드 에서 반환 한 결과와 일치하도록 수정되었으며 OP에 의해 참조 구현으로 제공되었습니다.


n=>[...Array(m=k=7**n)].reduce(s=>s+/^1*5?4{0,3}3?2{0,3}6?0{0,3}$/.test((--k+m).toString(7).replace(/0[62]|2[34]|4[51]/g,s=>s[1])),0)

온라인으로 사용해보십시오!

방법?

N

1

[...Array(m = k = 7 ** n)].reduce(s => … (--k + m).toString(7) …, 0)

이제부터 각 숫자는 로마 숫자 기호로 해석됩니다.

0I,1M,2X,3L,4C,5D,6V

2) 유효한 모든 빼기 쌍을 다음 ABB같이 바꿉니다 .

.replace(/0[62]|2[34]|4[51]/g, s => s[1]))  // in the code
.replace(/I[VX]|X[LC]|C[DM]/g, s => s[1]))  // with Roman symbols

예 :

  • XLIXIV 된다 LXV
  • XIIV하게 XIV이탈, I다음 테스트가 실패 할 것이다을
  • IC또한 잘못된 잎, 이는 변경되지 I자리에

3) 나머지 기호의 순서가 올바른지 확인하고 허용 된 횟수보다 여러 번 표시되지 않습니다.

/^1*5?4{0,3}3?2{0,3}6?0{0,3}$/.test(…)  // in the code
/^M*D?C{0,3}L?X{0,3}V?I{0,3}$/.test(…)  // with Roman symbols


답변

C, 150 123 바이트

설명을 충분히 읽지 않았으므로 표준 로마 숫자가 생성됩니다 (예 :식이 IVI계산되지 않음). 나는 그것에 노력을 기울 였기 때문에 어쨌든 나을 것이라고 생각했다.

#define F(X) for(X=10;X--;)
x[]={0,1,2,3,2,1,2,3,4,2};f(i,o,a,b,c){for(i++;i--;)F(a)F(b)F(c)o+=i==x[a]+x[b]+x[c];return o;}

원본 (150 바이트) :

#define F(X) for(X=10;X--;)
i,o,a,b,c,x[]={0,1,2,3,2,1,2,3,4,2};main(){scanf("%i",&i);for(i++;i--;)F(a)F(b)F(c)o+=i==x[a]+x[b]+x[c];printf("%i\n",o);}


답변