로마 숫자로 변환하세요!


13

당신의 임무는 주어진 양의 정수 를 아라비아 숫자에서 로마 숫자 로 변환하는 것 입니다.

4000까지 세면 상황이 어려워집니다.

로마인은이 기호를 곱하기 위해 기호 위에 줄을 추가하여이 작업을 수행했습니다 1 000. 그러나 ASCII에서는 오버 라인을 정확하게 표시 할 수 없습니다. 또한 기호에을 곱하는 이중 겹침이 있고 기호 1 000 000에을 곱하기 위해 삼중 겹침 1 000 000 000등이 있습니다.

따라서 괄호 를 사용 하여 개요를 대체 하기로 결정했습니다 .

기호는 괄호 안에 개별적으로 배치 할 수 있습니다 . 예를 들어, (VI)(V)(I)은 모두의 유효한 표현입니다 6 000. (V)M또한 6000의 유효한 표현입니다.

(I)를 나타내는 유효한 방법 1 000입니다.

테스트 케이스

Input: 1
Output: I
Input: 2
Output: II
Input: 3
Output: III
Input: 4
Output: IV
Input: 15
Output: XV
Input: 40
Output: XL
Input: 60
Output: LX
Input: 67
Output: LXVII
Input: 400
Output: CD
Input: 666
Output: DCLXVI
Input: 3000
Output: MMM
Input: 3999
Output: MMMCMXCIX
Input: 4000
Output: M(V)
Input: 4999
Output: M(V)CMXCIX
Input: 6000
Output: (VI)
Input: 6000000
Output: ((VI))
Input: 6006000
Output: ((VI)VI)
Input: 6666666666
Output: (((VI)DCLXVI)DCLXVI)DCLXVI

채점

이것은 입니다. 바이트 단위의 최단 코드가 이깁니다.


1
이것이 중복이 아닌 이유에 대한 정당성은 스펙을 혼란스럽게 만듭니다. IMO가 없으면 더 좋을 것입니다.
Mego

타당성을 어디에 추가합니까?
Leaky Nun

1
그만둬 누군가 중복 여부에 대해 의문이 있으면 의견이나 채팅으로 토론하십시오.
Mego

@ 메고 완료. :-)
Leaky Nun

(IV)4000의 허용 표현은?
Neil

답변:


9

수학, 67 바이트

Fold["("<>#<>")"<>#2&,RomanNumeral[#~IntegerDigits~1000]/."N"->""]&

M입력을 기준 1000으로 변환하고로 각 숫자를 개별적으로 변환하여 모든 문제를 방지합니다 RomanNumeral. 그런 다음 (...)왼쪽에서 삽입 하여 접습니다 .

불행히도 Mathematica는 0을 나타내 N므로 우리는 그것들을 제거해야합니다.


1
모든 것을위한 내장이있는 수학 수학> :(
OldBunny2800

1
@ OldBunny2800 그래도 골프 언어 중 하나라도 이기지 못했다면 놀랐을 것입니다.
Martin Ender

@ OldBunny2800 그리고 그것을 얻으려면 진짜 돈이 든다. 그 나쁜.
Outgolfer Erik

@ MartinBüttner 나는 단순히 RomanNumeral그것을 할 수 있다고 생각 했습니까?
Leaky Nun

1
@KennyLau는 출력 MMMM을 위해 4000만에 사양에 작업을 시작, 5000(그리고 당신을 위해 같은 문제 수 4000000등). 그럼에도 불구하고 괄호 대신 오버 바를 사용합니다. 당신이 그것으로 괜찮다면, 도전 사양에서 그렇게 말해야합니다.
Martin Ender

7

자바 스크립트 (ES6), 136 바이트

f=n=>n<4e3?"M1000CM900D500CD400C100XC90L50XL40X10IX9V5IV4I1".replace(/(\D+)(\d+)/g,(_,r,d)=>r.repeat(n/d,n%=d)):`(${f(n/1e3)})`+f(n%1e3)

4000 미만의 숫자의 경우 로마 "문자"목록과 10 진수 값을 사용하여 각 로마 "문자"를 가능한 한 여러 번 반복합니다. 그렇지 않으면 재귀 적으로 1000으로 나누기와 모듈로에서 답을 얻습니다. 다행히도 repeat잘리지 않으므로 직접 할 필요가 없습니다.


3

커먼 리스프, 108

(defun p(n)(if(> n 0)(if(< n 4000)(format()"~@R"n)(format()"(~A)~@[~A~]"(p(floor n 1000))(p(mod n 1000))))))

언 골프

(defun p(n)
  (if (> n 0)
      (if (< n 4000)

          ;; Built-in Roman formatter (between 1 and 3999)
          (format () "~@R" n)

          ;; Divide N by 1000, as 1000*Q + R.
          ;; First print (p Q) in parentheses (recursively)
          ;; Then, if it is not NIL, the remainder R.
          (format () "(~A)~@[~A~]"
                  (p (floor n 1000))
                  (p (mod n 1000))))))

테스트

두 가지 테스트는 문제의 결과와 다른 결과를 제공합니다.

(loop for (in out) in '((1 "I")
                        (2 "II")
                        (3 "III")
                        (4 "IV")
                        (15 "XV")
                        (40 "XL")
                        (60 "LX")
                        (67 "LXVII")
                        (400 "CD")
                        (666 "DCLXVI")
                        (3000 "MMM")
                        (3999 "MMMCMXCIX")
                        (4000 "M(V)")
                        (4999 "M(V)CMXCIX")
                        (6000 "(VI)")
                        (6000000 "((VI))")
                        (6006000 "((VI)VI)")
                        (6666666666 "(((VI)DCLXVI)DCLXVI)DCLXVI"))
   for computed = (p in)
   unless (string= out computed)
   collect (list in out computed))

=> ((4000 "M(V)" "(IV)")
    (4999 "M(V)CMXCIX" "(IV)CMXCIX"))

2

R, 134

m=1000;x=scan();while(x[1]>=m)x=c(floor(x[1]/m),x[1]%%m,x[-1]);cat(rep("(",length(x)),sep="");cat(as.character(as.roman(x)),sep=")")

가장 좋은 옵션은 아니지만 아이디어는 이것과 비슷해야한다고 생각합니다.


1

파이썬, 188 194

공백을 제거하여 -6 바이트

이 도전은 내가 처음 프로그래밍을 배우던 시절로 돌아 왔습니다 ...

def f(x,s=zip("M CM D CD C XC L XL X IX V IV I".split(),[1e3,900,500,400,100,90,50,40,10,9,5,4,1])):
 r=""if x<4e3else"("+f(x/1e3)+")";x%=1e3
 for a,b in s:
    while x>=b:r+=a;x-=b
 return r

가장 짧은 해결책은 아니지만이 문제를 재미있게 골랐습니다.

사용해보십시오!


1

루비, 137 (134) 130 바이트

문자열을 반환하는 재귀 함수 가능한 경우 숫자 인코딩을 조금 더 낮추려고하지만 어떻게 해야할지 모르겠습니다.

@, 그것은 실제로 @Neil의 ES6 답변의 직접적인 포트입니다.

f=->x{(x<t=1e3)?"CM900D500CD400C100XC90L50XL40X10IX9V5IV4I1".gsub(/(\D+)(\d+)/){v=$2.to_i;s=x/v;x%=v;$1*s}:"(#{f[x/t]})#{f[x%t]}"}

1

루비, 185161144 바이트

r=->i{i>(t=1e3)? "(#{r[i/t]})"+r[i%t]:(s=?I*i;"IVXXLCCDM".scan(/(.)(.)(.)/){|x,y,z|{x*5=>y,x*4=>x+y,y*2=>z,y+x+y=>x+z}.map{|x,y|s.gsub!x,y}};s)}

원래 게시물 이후 1 년 동안 골프에 대해 배운 것 같습니다.

소중한 의견에 대해 Value Ink에 감사드립니다.


gsub문자열을 첫 번째 인수로 사용할 수 있으므로 s.gsub! x,y자동으로 정규식 패턴으로 대체 할 필요 가 없습니다. 그 외에는 a배열을 한 번만 사용하여 each_slice호출에 직접 넣기 때문에 배열 할당을 취소 할 수 있습니다.
가치 잉크

"IVXXLCCDM".scan(/(.)(.)(.)/){|x,b,c|...작동
Value Ink

또한 스테이 비 람다가 관련 될 때마다 r[x]기능적으로 동일합니다r.(x)
Value Ink

@ValueInk 감사합니다. 이 r[x]트릭은 루비의 내 모든 futer 재귀 골프에 유용 할 것입니다!
MegaTom

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.