욕심 많은 로마인!


30

엄격하게 양의 정수가 주어지면 부가 규칙 만 사용하여 가능한 가장 짧은 로마 숫자를 반환하십시오. 출력은 MDCLXVI순서대로 각 문자를 0 개 이상으로 구성해야합니다 . 따라서 숫자 14XIIII아닌을 제공해야합니다 XIV.

문자의 숫자 값은 M= 1000, D= 500, C= 100, L= 50, X= 10, V= 5, I= 1입니다.

3III

4 → IIII

9VIIII

42XXXXII

796DCCLXXXXVI

2017MMXVII

16807MMMMMMMMMMMMMMMMDCCCVII


1
당신은 허용하는 자비로운 질문자는 것 4 -> IIII입니다 9 -> VIIII뿐만 아니라 IX?
매직 문어 Urn


@MagicOctopusUrn VIIII은 9에 허용되는 유일한 출력입니다.
Adám

@ Adám은 4와 9의 규칙이 동일하기 때문에 예제를 추가하고 싶을 수도 있다고 지적했습니다.
매직 문어 Urn

답변:


12

일반 영어 , 1,059 1,025 678 641 451 399 바이트

오류 트랩을 제거하여 34 바이트를 절약했습니다. 그런 다음 골프로 384 바이트를 절약했습니다. 그런 다음 나누기 연산과 추가 연산 ( "z")을 새 연산 ( "p")으로 결합하여 190 바이트를 절약했습니다. 그런 다음 골프로 52 바이트를 절약했습니다.

A s is a string.
To p a r remainder a s a x string a n number:
If the x is "", exit.
Divide the r by the n giving a q quotient and the r.
Fill a t s with the x's first's target given the q.
Append the t to the s.
To convert a r number to a s:
p the r the s "M" 1000.
p the r the s "D" 500.
p the r the s "C" 100.
p the r the s "L" 50.
p the r the s "X" 10.
p the r the s "V" 5.
p the r the s "I" 1.

다음은 최종 코드의 ungolfed 버전과 음수에 대한 오류 트랩입니다.

A roman numeral is a string.

To process a remainder given a roman numeral and a letter string is a number:
  If the letter is "", exit.
  Divide the remainder by the number giving a quotient and the remainder.
  Fill a temp string with the letter's first's target given the quotient.
  Append the temp string to the roman numeral.

To convert a number to a roman numeral:
  If the number is negative, exit.
  Put the number in a remainder.
  Process the remainder given the roman numeral and "M" is 1000.
  Process the remainder given the roman numeral and "D" is  500.
  Process the remainder given the roman numeral and "C" is  100.
  Process the remainder given the roman numeral and "L" is   50.
  Process the remainder given the roman numeral and "X" is   10.
  Process the remainder given the roman numeral and "V" is    5.
  Process the remainder given the roman numeral and "I" is    1.

10
잠깐, 이것이 프로그래밍 언어입니까?
Adám

3
@ 아담-예. 일반 영어는 컴파일하고 실행하며 모든 것을 수행합니다. 소스 코드와 IDE는 github.com/Folds/english
Jasper

1
그래도 골프를 치십시오-결국 이것은 언어 쇼케이스가 아닌 코드 골프입니다.
Sanchises 2016 년

2
그래서 이것은 당신이 당신의 직업을 아웃소싱하고 싶지 않다면 사용하는 언어입니다.
corsiKa

@corsiKa-롤! 우리 중 많은 사람들이 그것을 사용하고 라이브러리에 추가하기 시작하면 임계 질량을 달성합니다.
재스퍼

5

APL (Dyalog) , 25 22 바이트

'MDCLXVI'/⍨(0,62 5)∘⊤

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


좋고 기본적으로 내가 생각한 해결책. 그러나 /모양 변경 ( ) 대신 복제 ( )를 사용 하여 각각 및 catenate-reduction ( ¨,/)을 잘라낼 수 있습니다 .
Adám

또한 tradfn 본문으로 변환하고 입력 ( )을 취하고 통근 ( )을 사용 하여 파렌 을 제거하고 작성 ( ) 할 수 있습니다.
Adám

고맙지 만 두 번째 의견은 무엇을 의미합니까? 바이트 수를 늘리지 않으면 서 그렇게하는 방법을 생각할 수 없다
TwiNight


1
함수를 세 거나 둘러싼 경우를 제외 하고는 스 니펫입니다.{}∇f∇
TwiNight

5

망막 , 57 42 바이트

단항으로 변환 한 다음 욕심 I많은 무리를 순서대로 높은 교단으로 바꿉니다 .

.*
$*I
I{5}
V
VV
X
X{5}
L
LL
C
C{5}
D
DD
M

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

Martin 덕분에 15 바이트 절약


매우 영리합니다.
Adám

7
그것은 다른 길을 갈 수있는 많은 짧은입니다 : tio.run/##K0otycxL/...
마틴 청산

I단위로 사용하여 단항 입력을 할 수 없습니까?
Adám

2
@ Adám Retina가 이제 정수 입력을 쉽게 처리 할 수 ​​있다고 생각하면 그렇게하는 것이 저렴하다고 생각합니다.
mbomb007

5

파이썬 2 , 64 바이트

f=lambda n,d=5,r='IVXLCD':r and f(n/d,7-d,r[1:])+n%d*r[0]or'M'*n

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

탐욕스럽게 가장 큰 부분을 가져 와서 처음부터 출력 문자열을 생성하는 대신 끝에서 출력 문자열을 생성합니다. 예를 들어, 수 I의는 n%5다음의 수는 V있습니다이야 ' n/5%2, 등등. 이것은 5와 2의 연속 비율로 혼합 된 기본 변환입니다.

반복되는 내용은 다음과 같습니다.

파이썬 2 , 68 바이트

n=input();s='';d=5
for c in'IVXLCD':s=n%d*c+s;n/=d;d^=7
print'M'*n+s

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

M더 큰 자리가 없습니다로 임의의 수의 존재가 될 수 있기 때문에 '의 필요성은 별도로 처리 할 수 있습니다. 따라서 다른 장소 값이 지정된 후에는 남은 값이로 변환됩니다 M.

욕심 많은 전략 (69 바이트) :

파이썬 2 , 69 바이트

f=lambda n,d=1000,r='MDCLXVI':r and n/d*r[0]+f(n%d,d/(d%3*3-1),r[1:])

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

현재 숫자 값 d은 2 또는 5로 나누어 다음 숫자를 생성합니다. 의 값은 d%3우리에게 어떤 하나의 경우 d%3==1, 분할에 의해 2; 이면 d%3==25로 나눕니다.


4

수학, 81 바이트

Table@@@Thread@{r=Characters@"MDCLXVI",#~NumberDecompose~FromRomanNumeral@r}<>""&

명시 적으로 값을 사용하고 해당 숫자를 도출하는 것이 1 바이트 더 긴 것 같습니다.

Table@@@Thread@{RomanNumeral[n={1000,500,100,50,10,5,1}],#~NumberDecompose~n}<>""&

1
좋은! :FromRomanNumeral@r
DavidC

4

엑셀 236 193 161 바이트

@ BradC 덕분에 43 바이트 절약

이 시점에서 답은 실제로 @ BradC에 속합니다 . 다른 32 바이트가 저장되었습니다.

=REPT("M",A1/1E3)&REPT("D",MOD(A1,1E3)/500)&REPT("C",MOD(A1,500)/100)&REPT("L",MOD(A1,100)/50)&REPT("X",MOD(A1,50)/10)&REPT("V",MOD(A1,10)/5)&REPT("I",MOD(A1,5))

형식화 :

=REPT("M",A1/1E3)
    &REPT("D",MOD(A1,1E3)/500)
    &REPT("C",MOD(A1,500)/100)
    &REPT("L",MOD(A1,100)/50)
    &REPT("X",MOD(A1,50)/10)
    &REPT("V",MOD(A1,10)/5)
    &REPT("I",MOD(A1,5))

당신은 대체하여 일부를 절약 할 수 CONCATENATE&각 요소 사이, 및 QUOTIENTINT(A/B).
BradC

2 더 절약 : 정수가 아닌 경우REPT 이미 숫자를 자르 므로 각을 제거하여 30 바이트를 더 절약 할 수 있습니다 INT(). 저장 2 개를 모두 교체하여 1000함께 1E3(Excel에서 사용자가 입력 한 히트 일단 그런 식으로 유지하려는 것 같지 않지만).
BradC

예, 1E3행동을 봤어요 답변이 업데이트되었습니다.
Wernisch

3

펄 5 , 66 바이트

65 바이트의 코드 + -p플래그.

$s=1e3;for$@(MDCLXVI=~/./g){$\.=$@x($_/$s);$_%=$s;$s/=--$|?2:5}}{

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

바이트 수를 변경하지 않고, MDCLXVI=~/./g에 의해 대체 될 수있다 M,D,C,L,X,V,I; 에 --$|?2:5의해 $|--*3+2.

훨씬 더 길다 ( 99 바이트 ).

$_=M x($_/1e3).D x($_%1e3/500).C x($_%500/100).L x($_%100/50).X x($_%50/10).V x($_%10/5).I x($_%5)

3

CJam , 35 28 바이트

Martin Ender 덕분에 -7 바이트

q~{5md\2md\}3*]W%"MDCLXVI".*

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

설명

q~         e# Read and eval input (push the input as an integer).
{          e# Open a block:
 5md\      e#  Divmod the top value by 5, and bring the quotient to the top.
 2md\      e#  Divmod that by 2, and bring the quotient to the top.
}3*        e# Run this block 3 times.
]W%        e# Wrap the stack in an array and reverse it. Now we've performed the mixed-base
           e# conversion.
"MDCLXVI"  e# Push this string.
.*         e# Element-wise repetition of each character by the numbers in the other array.
           e# Implicitly join and print.

3

C #, 127 바이트

f=n=>n>999?"M"+f(n-1000):n>499?"D"+f(n-500):n>99?"C"+f(n-100):n>49?"L"+f(n-50):n>9?"X"+f(n-10):n>4?"V"+f(n-5):n>0?"I"+f(n-1):""

재귀를 사용하여 순전히 하드 코딩 된 삼항 문.

풀 / 포맷 버전 :

using System;

class P
{
    static void Main()
    {
        Func<int, string> f = null;
        f = n => n > 999 ? "M" + f(n - 1000)
                         : n > 499 ? "D" + f(n - 500)
                                   : n > 99 ? "C" + f(n - 100)
                                            : n > 49 ? "L" + f(n - 50)
                                                     : n > 9 ? "X" + f(n - 10)
                                                             : n > 4 ? "V" + f(n - 5)
                                                                     : n > 0 ? "I" + f(n - 1)
                                                                             : "";

        Console.WriteLine(f(3));
        Console.WriteLine(f(4));
        Console.WriteLine(f(42));
        Console.WriteLine(f(796));
        Console.WriteLine(f(2017));
        Console.WriteLine(f(16807));

        Console.ReadLine();
    }
}

n>0그냥 n입니다.
CalculatorFeline

@CalculatorFeline C #에는 int없지만로 암시 적으로 캐스트 할 수 없습니다 bool.
TheLethalCoder

운이 없었어.
CalculatorFeline

@CalculatorFeline 예, C #은 때로는 너무 강하기 때문에 너무 강합니다.
TheLethalCoder 2016 년

3

05AB1E , 29 26 25 바이트

¸5n3×Rvćy‰ì}"MDCLXVI"Ss×J

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

설명

¸                           # wrap input in a list
 5n                         # push 5**2
   3×                       # repeat it 3 times
     Rv                     # for each digit y in its reverse
       ć                    # extract the head of the list 
                            # (div result of the previous iteration, initially input)
        y‰                  # divmod with y
          ì                 # prepend to the list
           }                # end loop
            "MDCLXVI"S      # push a list of roman numerals
                      s×    # repeat each a number of times corresponding to the result
                            # of the modulus operations
                        J   # join to string

3

자바 스크립트 (ES6), 81 75 69 바이트

@ Jörg Hülsermann의 답변을 포팅 한 @Neil 덕분에 6 바이트를 절약했습니다.

@Shaggy 덕분에 6 바이트 절약

n=>'MDCLXVI'.replace(/./g,(c,i)=>c.repeat(n/a,n%=a,a/=i%2?5:‌​2),a=1e3)

테스트 사례 :


1
몇 바이트를 절약하기 위해 메소드 n%=x내에서 이동할 수 있어야합니다 repeat.
얽히고 설킨

1
참고로 PHP 답변의 포트는 69 바이트에 불과합니다.n=>'MDCLXVI'.replace(/./g,(c,i)=>c.repeat(n/a,n%=a,a/=i%2?5:2),a=1e3)
Neil

@Neil에게 감사합니다. 게시물을 업데이트했습니다. 다시 방문하고 싶었던 하드 코딩 된 배열을 제거합니다
Craig Ayre


2

파이썬 3 , 100 97 96 94 93 91 90 바이트

  • 저장된 4 + 2 바이트 : 사용 def; 기본 매개 변수 인 array는 들여 쓰기 공간을 줄였습니다. 원하지 않는 변수 선언이 제거되었습니다.
  • @shooqie는 1 바이트 a%=속기를 저장했습니다
  • 2 바이트 저장 : 재정렬 및 ​​중괄호 (a//i)제거
  • @Wondercricket 저장 1 바이트 : 기본 매개 변수에서 []하나의 들여 쓰기 공간을 희생하여 제거 된 함수 내로 배열을 이동하여 1 바이트를 절약하십시오.
def f(a):
 b=1000,500,100,50,10,5,1
 for i in b:print(end=a//i*'MDCLXVI'[b.index(i)]);a%=i

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


1
a%=i바이트가 짧습니다 :)
shooqie

1
b함수 내에 변수로 저장하여 바이트를 저장할 수도 있습니다. 그것은 대괄호의 필요성을 제거합니다 –b=1000,500,100,50,10,5,1
Wondercricket

2

Cubix , 69 74 80 바이트

/.UI,..N&..0\0&/52"IVXLCDM"U,r%ws;rr3tu;pw..u;qrUosv!s.u\psq,!@Us(0;U

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

        / . U I
        , . . N
        & . . 0
        \ 0 & /
5 2 " I V X L C D M " U , r % w
s ; r r 3 t u ; p w . . u ; q r
U o s v ! s . u \ p s q , ! @ U
s ( 0 ; U . . . . . . . . . . .
        . . . .
        . . . .
        . . . .
        . . . .

그것을 지켜봐

나는 그것을 조금 더 압축 할 수 있었지만, 특히 윗면에 성가신 no-ops가 여전히 있습니다.

  • 52"IVXLCDM"U필요한 제수와 문자를 스택에 넣습니다. 5와 2는 div / mod 값을 줄이는 데 사용되며 문자는 사용 후 폐기됩니다.
  • UIN0/&0\&,/UU는 윗면을 향하고 긴 여행을 시작하여 입력을 얻고 1000을 스택에 밀어 넣습니다. 초기 분할이 완료되고 r다음 스 니펫의 U가 켜집니다 . 이것은 내가 저축을하기 위해보고있는 지역이었다.
  • ,r%ws;rrdivmod 루프의 시작. 정수 나누기, 결과 떨어져 모드를 회전 한 다음 스택 상단을 다시 정렬하여 입력, 전류 제수 및 나누기 결과를 줄입니다.
  • 3tus 현재 문자를 맨 위로 가져와 나누기 결과로 바꿉니다.
  • !vsoUs(0;U이것이 인쇄 루프입니다. div 결과가 0보다 큰 동안 문자 출력으로 바꾸고, 다시 바꾸고, 감소시키고, 0을 밀어 내십시오. 0으로 설정하면 팝 스택 위로 (분할 결과 제거) 큐브 주변으로 리디렉션됩니다.
  • \u;pwpsq,!@Urq;u약간의 리디렉션으로 스택에서 캐릭터를 제거하고 5와 2를 맨 위로 가져 와서 스왑하고 다시 아래로 밀어냅니다. 나머지는 제수를 줄이는 데 사용됩니다. 0으로 줄이면 중단하고, 그렇지 않으면 5 또는 2를 맨 아래로 밀고 루프를 다시 입력하십시오.

1

Mathematica, 130 bytes

(f=#~NumberDecompose~{1000,500,100,50,10,5,1};""<>{Flatten@Table[Table[{"M","D","C","L","X","V","I"}[[i]],f[[i]]],{i,Length@f}]})&

1

Python 2, 109 90 bytes

lambda n,r=[1000,500,100,50,10,5,1]:''.join(n%a/b*c for a,b,c in zip([n+1]+r,r,'MDCLXVI'))

Try it online!


1000 can be 1e3 (if you don't mind it being a float which shouldn't be a problem)
CalculatorFeline

@CalculatorFeline it would turn the result into a float, and you can't multiply a string by a float :c
Rod


1

T-SQL, 164 bytes

SELECT REPLICATE('M',n/1000)+IIF(n%1000>499,'D','')
      +REPLICATE('C',n%500/100)+IIF(n%100>49,'L','')
      +REPLICATE('X',n%50/10)+IIF(n%10>4,'V','')
      +REPLICATE('I',n%5)
FROM t

Line breaks added for readability only.

This version is a lot longer (230 characters), but feels much more "SQL-like":

DECLARE @ INT,@r varchar(99)=''SELECT @=n FROM t
SELECT'I's,1v INTO m
INSERT m VALUES('V',5),('X',10),('L',50),('C',100),('D',500),('M',1000)
L:
    SELECT @-=v,@r+=s 
    FROM m WHERE v=(SELECT MAX(v)FROM m WHERE v<=@)
IF @>0GOTO L
SELECT @r

Makes a table m with all the char-value mappings, and then loops through finding the largest value <= the number, concatenating the matching character.


1

Japt, 34 bytes

"IVXLCD"£%(U/=Y=v *3+2Y)îXÃw i'MpU

Test it online!

"IVXLCD"£    %(U/=Y=v  *3+2Y )îXÃ w i'MpU
"IVXLCD"mXY{U%(U/=Y=Yv *3+2,Y)îX} w i'MpU : Ungolfed
                                          : Implicit: U = input number
"IVXLCD"mXY{                    }         : Map each char X and its index Y in this string to:
                  Y=Yv *3+2               :   Set Y to 5 for even indexes, 2 for odd.
               U/=                        :   Divide U by this amount.
            U%(            ,Y)            :   Modulate the old value of U by 5.
                              îX          :   Repeat the character that many times.
                                          : This returns e.g. "IIVCCCD" for 16807.
                                  w       : Reverse the entire string.
                                    i'MpU : Prepend U copies of 'M' (remember U is now the input / 1000).
                                          : Implicit: output result of last expression

1

JavaScript (ES6), 65 bytes

A recursive function.

f=(n,a=(i=0,1e3))=>n?a>n?f(n,a/=i++&1?5:2):'MDCLXVI'[i]+f(n-a):''

How?

The second recursive call f(n-a) really should be f(n-a,a). By omitting the 2nd parameter, a and i are reinitialized (to 1000 and 0 respectively) each time a new Roman digit is appended to the final result. This causes more recursion than needed but doesn't alter the outcome of the function and saves 2 bytes.

Test cases


1

J, 26 23 bytes

3 bytes saved thanks to Adám.

'MDCLXVI'#~(_,6$2 5)&#:

Try it online!

Similar to the APL answer basically the same thing.

'MDCLXVI'#~(_,6$2 5)&#:
           (       )&#:   mixed base conversion from decimal
              6$2 5       2 5 2 5 2 5
            _,            infinity 2 5 2 5 2 5
                          this gives us e.g. `0 0 0 0 1 0 4` for input `14`
'MDCLXVI'#~               shape each according to the number of times on the right
                          this is greedy roman numeral base conversion

Not that I know J, but why #.inv instead of #:?
Adám

@Adám Ah, good point. I customarily use #.inv instead of #:, since something like 2 #: 4 is 0, whilst 2 #.inv 4 is 1 0 0
Conor O'Brien

Yeah, I do the same thing in APL. Now your solution is truly equivalent to the APL solution.
Adám

# is /; ~ is ; $ is ; & is ; #: is . The only difference is that you use infinity _ while you could use 0 like the APL answer.
Adám

@Adám Huh, cool.
Conor O'Brien

1

Batch, 164 bytes

@set/pn=
@set s=
@for %%a in (1000.M 500.D 100.C 50.L 10.X 5.V 1.I)do @call:c %%~na %%~xa
@echo %s:.=%
@exit/b
:c
@if %n% geq %1 set s=%s%%2&set/an-=%1&goto c

Takes input on STDIN.


1

Oracle SQL, 456 bytes

select listagg((select listagg(l)within group(order by 1)from dual start with trunc((n-nvl(n-mod(n,p),0))/v)>0 connect by level<=trunc((n-nvl(n-mod(n,p),0))/v)))within group(order by v desc)from (select 2849n from dual)cross join(select 1000v,null p,'m'l from dual union select 500,1000,'d'from dual union select 100,500,'c'from dual union select 50,100,'l'from dual union select 10,50,'x'from dual union select 5,10,'v'from dual union select 1,5,'i'from dual)

Outputs:

mmdcccxxxxviiii

Please note the actual size of the line is 460bytes, because it includes the input number (2849).

Ungolfed:

select listagg(
            (select listagg(l, '') within group(order by 1) 
             from dual 
             start with trunc((n-nvl(p*trunc(n/p),0))/v) > 0 
             connect by level <= trunc((n-nvl(p*trunc(n/p),0))/v) )
        ) within group(order by v desc)
from (select 2348 n
    from dual
) cross join (
    select 1000v, null p, 'm' l from dual union 
    select 500, 1000, 'd' from dual union
    select 100, 500, 'c' from dual union
    select 50, 100, 'l' from dual union
    select 10, 50, 'x' from dual union
    select 5, 10, 'v' from dual union
    select 1, 5, 'i' from dual     
)

How it works: I calculate how many of each letter I need, by calculating the most I can get to with the higher value one (infinity for M), and then doing an integer division between the current letter's value and the result of that.

E.g. 2348, how many Cs do I need? trunc((2348-mod(2348,500))/100) = 3.

Then, I listagg that letter together 3 times (exploiting CONNECT BY to generate the 3 rows I need). Finally, I listagg everything together.

Kinda bulky, but most of it is the select from duals in the conversion table and I can't really do much about that...


0

Java (OpenJDK 8), 119 118 bytes

n->{String s="";for(int v[]={1,5,10,50,100,500,1000},i=7;i-->0;)for(;n>=v[i];n-=v[i])s+="IVXLCDM".charAt(i);return s;}

Try it online!

Saved a byte thanks to @TheLethalCoder


1
Can you declare v and i in the first for loop to save a byte?
TheLethalCoder

@TheLethalCoder Yes, most certainly. I was on a totally other idea at first that this didn't pass my internal review :p
Olivier Grégoire

0

Charcoal, 61 50 46 bytes

NνA⁰χWφ«W¬‹νφ«§MDCLXVIχA⁻νφν»A⁺¹χχA÷φ⎇﹪χ²¦²¦⁵φ

Try it online!

Explanation:

Nν                   Take input as number and assign it to ν
A⁰χ                  Let χ=0
Wφ«                  While φ>0 (φ has a predefined value of 1000)
    W¬‹νφ«               While v>=φ 
        §MDCLXVIχ             Take the char from string "MDCLXVI" at position χ
        A⁻νφν»               Let ν=ν-φ
    A⁺¹χχ                Increment χ
    A÷φ⎇﹪χ²¦²¦⁵φ        If χ is odd, divide φ by 5, else divide φ by 2
  • 4 bytes saved thanks to Neil, while I am still trying to figure out how to proceed with the second part of his comment.

1
Nν is one byte shorter than ANν, ¬‹ is one byte shorter than subtracting 1, and if you use ÷ (IntDivide) instead of (Divide) then you can use φ as the outer loop condition. However, I think you can get it down to 40 bytes by looping over MDCLXVI directly instead.
Neil

@Neil of course, silly me, trying to understand why there is no "greater or equal" operator when I could use "not less". Very clever trick the use of the integer division. Now allow me some time to think about the last part of your comment...
Charlie

I improved my string loop idea and posted it as a seprate answer along with a port of @xnor's Python answer, which turned out to be the same length.
Neil

0

C++, 272 Bytes

#include <cstdio>
#include <map>
std::map<int,char> m = {{1000,'M'},{500,'D'},{100,'C'},{50,'L'},{10,'X'},{5,'V'},{1,'I'}};
int main(){unsigned long x;scanf("%d",&x);for(auto i=m.rbegin();i!=m.rend();++i)while(x>=i->first){printf("%c", i->second);x=x-i->first;}return 0;}

0

C, 183 Bytes

#include <stdio.h>
int v[]={1000,500,100,50,10,5,1};
char*c="MDCLXVI";
int main(){int x;scanf("%d",&x);for(int i=0;i<sizeof v/sizeof(int);i++)for(;x>=v[i];x-=v[i])putc(c[i],stdout);}

Same algorithm as before, just using plain c arrays instead of an std::map, partially inspired by @xnor's answer and using a string to store the letters.



0

Common Lisp, 113 bytes

This is an anonymous function, returning the result as a string.

(lambda(value)(setf(values a b)(floor v 1000))(concatenate 'string(format()"~v,,,v<~>"a #\M)(format nil"~@:r"b)))

Ungolfed, with descriptive variable names and comments:

(defun format-roman (value)
  ;; Get "value integer-divided by 1000" and "value mod 1000"
  (setf (values n_thousands remainder) (floor value 1000))
  (concatenate 'string
               ;; Pad the empty string n_thousands times, using "M" as the 
               ;; padding character
               (format () "~v,,,v<~>" n_thousands #\M)
               ;; Format the remainder using "old-style" Roman numerals, i.e. 
               ;; numerals with "IIII" instead of "IV"
               (format nil "~@:r" remainder)))

CL has built-in Roman numeral formatter. Sadly it doesn't work for numbers larger than 3999.


0

Charcoal, 34 bytes

NςA²ξFMDCLXVI«×ι÷ςφA﹪ςφςA÷φξφA÷χξξ

Originally based on @CarlosAlego's answer. A port of @xnor's Python solution is also 34 bytes:

NθA⁵ξFIVXLCD«←×ι﹪θξA÷θξθA÷χξξ»←×Mθ

Edit: A port of @xnor's other Python solution turns out to be 33 bytes!

NθFMDCLXVI«×ι÷θφA﹪θφθA÷φ⁺׳﹪φ³±¹φ

Try it online! Link is to verbose version of code. Note that I've used ⁺׳﹪φ³±¹ instead of ⁻׳﹪φ³¦¹ because the deverbosifier is currently failing to insert the separator.


1
Huh, that looks more Greek than Roman.
Adám
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.