¡Esos romanos codiciosos!

30

Dado un entero estrictamente positivo, devuelve el número romano más corto posible usando solo la regla aditiva. La salida debe consistir en cero o más de cada uno de los caracteres MDCLXVIen ese orden. Por 14lo tanto, el número debe dar en XIIIIlugar de XIV.

Los valores numéricos de los caracteres son M= 1000, D= 500, C= 100, L= 50, X= 10, V= 5, I= 1.

Ejemplos

3III

4 → IIII

9VIIII

42XXXXII

796DCCLXXXXVI

2017MMXVII

16807MMMMMMMMMMMMMMMMDCCCVII

Adán
fuente
1
¿Eres un interrogador benévolo que permitir 4 -> IIIIes 9 -> VIIIItambién en lugar de IX?
Magic Octopus Urn
@MagicOctopusUrn VIIIIes la única salida permitida para 9.
Adám
@ Adám solo estaba señalando que es posible que desee agregar eso como ejemplo también porque la regla para 4 y 9 es la misma.
Magic Octopus Urn
1
Relacionado
Arnauld

Respuestas:

12

Inglés simple , 1059 1025 678 641 451 399 bytes

Se guardaron 34 bytes al eliminar una trampa de error. Luego ahorró 384 bytes jugando al golf. Luego guardó 190 bytes combinando la operación de división con la operación de agregar ("z") en una nueva operación ("p"). Luego ahorró 52 bytes jugando al golf.

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.

Aquí está la versión no codificada del código final, más una trampa de error para un número negativo:

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.
Jaspe
fuente
10
Espera, ¿es este un lenguaje de programación?
Adám
3
@ Adam - Sí. Inglés sencillo compila, y corre, y todo. El código fuente y el IDE están disponibles en github.com/Folds/english
Jasper
1
Sin embargo, juegue al golf: después de todo, este es el golf de código, no un escaparate de idiomas.
Sanchises
2
Entonces, ¿este es el lenguaje que usa si no quiere que su trabajo sea subcontratado?
corsiKa
@corsiKa - LOL! Solo si suficientes de nosotros comenzamos a usarlo (y a agregarlo a sus bibliotecas) que logre una masa crítica.
Jasper
5

APL (Dyalog) , 25 22 bytes

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

Pruébalo en línea!

TwiNight
fuente
Agradable, y básicamente la solución que tenía en mente. Sin embargo, puede usar replicate ( /) en lugar de reshape ( ) para que pueda cortar cada uno y la reducción de catenado ( ¨y ,/).
Adám
Además, puede convertir a tradfn body y tomar input ( ) y usar commute ( ) para eliminar los parens y compose ( ).
Adám
Gracias, pero ¿qué quieres decir con tu segundo comentario? No se me ocurre una manera de hacerlo sin aumentar el número de bytes
TwiNight
1
Eso sería un fragmento a menos que cuentes la función que la rodea {}o la ∇f∇rodea
TwiNight
5

Retina , 57 42 bytes

Se convierte en unario, luego reemplaza codiciosamente los racimos de Is con las denominaciones más altas en orden.

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

Pruébalo en línea

Guardado 15 bytes gracias a Martin

mbomb007
fuente
Eso es muy inteligente.
Adám
77
Es mucho más corto ir para otro lado: tio.run/##K0otycxL/…
Martin Ender
¿No podrías tomar una entrada en unario usando Icomo unidad?
Adám
2
@ Adám Considerando que Retina ahora puede manejar fácilmente la entrada de enteros, creo que es un poco barato hacerlo.
mbomb007
5

Python 2 , 64 bytes

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

Pruébalo en línea!

En lugar de crear la cadena de salida desde el principio tomando con avidez la parte más grande, esto la crea desde el final. Por ejemplo, el número de I's es n%5, luego el número de V' s es n/5%2, y así sucesivamente. Esta es una conversión de base mixta con relaciones sucesivas de 5 y 2 alternadas.

Aquí hay un equivalente iterativo:

Python 2 , 68 bytes

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

Pruébalo en línea!

Los M's deben manejarse por separado porque cualquier número de ellos podría estar presente ya que no hay un dígito más grande. Entonces, después de que se hayan asignado los otros valores de lugar, el valor restante se convierte a M's.

A modo de comparación, una estrategia codiciosa (69 bytes):

Python 2 , 69 bytes

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

Pruébalo en línea!

El valor del dígito actual dse divide entre 2 o 5 para producir el siguiente dígito. El valor de d%3decirnos cuál: si d%3==1, dividir por 2; y si d%3==2, dividir por 5.

xnor
fuente
4

Mathematica, 81 bytes

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

Usar explícitamente los valores y derivar los números correspondientes parece ser un byte más largo:

Table@@@Thread@{RomanNumeral[n={1000,500,100,50,10,5,1}],#~NumberDecompose~n}<>""&
Martin Ender
fuente
1
Nice !:FromRomanNumeral@r
DavidC
4

Excel, 236 193 161 bytes

43 bytes guardados gracias a @ BradC

En este punto, la respuesta realmente pertenece totalmente a @ BradC . Otros 32 bytes guardados.

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

Formateado:

=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))
Wernisch
fuente
Ahorrará algo reemplazando CONCATENATEcon &entre cada elemento y QUOTIENTcon INT(A/B).
BradC
2 ahorros más: resulta que REPTya trunca el número si no es un entero , por lo que puede guardar 30 bytes más al eliminar cada uno INT(). Ahorre 2 más reemplazando ambos 1000con 1E3(aunque Excel no parece querer mantenerlo de esa manera una vez que presiona enter).
BradC
Sí, vi el 1E3comportamiento. Respuesta actualizada
Wernisch
3

Perl 5 , 66 bytes

65 bytes de código + -pbandera.

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

Pruébalo en línea!

Sin cambiar el conteo de bytes, MDCLXVI=~/./gpuede ser reemplazado por M,D,C,L,X,V,I; y --$|?2:5por $|--*3+2.

Mucho más largo ( 99 bytes ), hay:

$_=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)
Dada
fuente
3

CJam , 35 28 bytes

-7 bytes gracias a Martin Ender

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

Pruébalo en línea!

Explicación

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.
Gato de negocios
fuente
3

C #, 127 bytes

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):""

Una declaración ternaria puramente codificada usando recursión.

Versión completa / formateada:

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();
    }
}
TheLethalCoder
fuente
n>0es justo n.
CalculatorFeline
@CalculatorFeline No en C #, intno se puede convertir implícitamente a a bool.
TheLethalCoder
Eso es lamentable.
CalculatorFeline
@CalculatorFeline Sí, a veces C # está muy tipeado para su propio bien.
TheLethalCoder
3

05AB1E , 29 26 25 bytes

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

Pruébalo en línea!

Explicación

¸                           # 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
Emigna
fuente
3

JavaScript (ES6), 81 75 69 Bytes

Guardado 6 bytes gracias a @Neil por portar la respuesta de @ Jörg Hülsermann

Guardado 6 bytes gracias a @Shaggy

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

Casos de prueba:

Craig Ayre
fuente
1
Debería poder mover n%=xdentro del repeatmétodo para guardar algunos bytes.
Shaggy
1
Para su información, un puerto de la respuesta PHP tiene solo 69 bytes:n=>'MDCLXVI'.replace(/./g,(c,i)=>c.repeat(n/a,n%=a,a/=i%2?5:2),a=1e3)
Neil
Gracias @Neil, he actualizado la publicación. Elimina la matriz codificada que quería volver a visitar
Craig Ayre
2

/// , 50 bytes

/1/I//IIIII/V//VV/X//XXXXX/L//LL/C//CCCCC/D//DD/M/

Pruébalo en línea!

Toma la entrada en unario, y estoy (ab) usando el campo de pie de página en TIO para la entrada, por lo que la salida está precedida por una nueva línea.

Steenbergh
fuente
2

Python 3 , 100 97 96 94 93 91 90 bytes

  • guardado 4 + 2 bytes: uso de def; array como parámetro predeterminado redujo un espacio de sangría; declaración de variable no deseada eliminada
  • @shooqie guardó 1 byte de a%=taquigrafía
  • guardado 2 bytes: reorganizado y llaves en (a//i)eliminado
  • @Wondercricket guardó 1 byte: mueve la matriz del parámetro predeterminado a la función que se eliminó []a costa de un espacio de sangría, ahorrando así 1 byte.
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

Pruébalo en línea!

officialaimm
fuente
1
a%=ies un byte más corto :)
shooqie
1
También puede guardar un byte almacenándolo bcomo una variable dentro de la función. Que elimina la necesidad de soportes -b=1000,500,100,50,10,5,1
Wondercricket
2

Cubix , 69 74 80 bytes

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

Pruébalo en línea!

        / . 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 . . . . . . . . . . .
        . . . .
        . . . .
        . . . .
        . . . .

Míralo correr

Me las he arreglado para comprimirlo un poco más, pero todavía hay algunos molestos no-ops, especialmente en la cara superior.

  • 52"IVXLCDM"Upon los divisores y personajes necesarios en la pila. Los 5 y 2 se usarán para reducir el valor div / mod y los caracteres se descartarán después de su uso.
  • UIN0/&0\&,/UGira en U hacia la cara superior y comienza un largo recorrido para obtener la entrada y empujar 1000 en la pila. Se realiza una división inicial y un cambio de sentido hacia rel siguiente fragmento. Esta era un área que estaba buscando para hacer algunos ahorros.
  • ,r%ws;rrcomienzo del bucle divmod. división entera, gire el resultado lejos mod, luego reorganice la parte superior de la pila para reducir la entrada, el divisor actual y el resultado de división.
  • 3tus lleva el personaje actual a la parte superior e intercambia con el resultado de división
  • !vsoUs(0;UEste es el bucle de impresión. mientras el resultado div es más de 0, intercambie con salida de caracteres, intercambie hacia atrás, disminuya, presione un 0 y suéltelo. En 0 redirigir sobre la pila emergente (eliminar el resultado de división) y alrededor del cubo.
  • \u;pwpsq,!@Urq;ucon un poco de redireccionamiento, esto elimina al personaje de la pila, lleva los 5 y 2 a la parte superior, los intercambia y empuja uno hacia abajo. El resto se usa para reducir el divisor. Deténgase si se reduce a 0; de lo contrario, presione el 5 o el 2 hacia abajo y vuelva a ingresar al bucle.
MickyT
fuente
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}]})&
J42161217
fuente
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'))

Pruébalo en línea!

Barra
fuente
1000puede ser 1e3(si no te importa que sea un flotador que no debería ser un problema)
CalculatorFeline
@CalculatorFeline convertiría el resultado en a float, y no puede multiplicar una cadena por un flotador: 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

Saltos de línea agregados solo para facilitar la lectura.

Esta versión es mucho más larga (230 caracteres), pero se siente mucho más como "SQL":

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

Realiza una tabla m con todas las asignaciones de valores de caracteres y luego realiza un bucle para encontrar el valor más grande <= el número, concatenando el carácter coincidente.

BradC
fuente
1

Japt , 34 bytes

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

¡Pruébelo en línea!

"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
ETHproducciones
fuente
1

JavaScript (ES6), 65 bytes

Una función recursiva.

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

¿Cómo?

La segunda llamada recursiva f(n-a)realmente debería ser f(n-a,a). Al omitir el segundo parámetro, ay ise reinicializan (a 1000 y 0 respectivamente) cada vez que se agrega un nuevo dígito romano al resultado final. Esto causa más recursividad de la necesaria pero no altera el resultado de la función y ahorra 2 bytes.

Casos de prueba

Arnauld
fuente
1

J , 26 23 bytes

3 bytes guardados gracias a Adám.

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

Pruébalo en línea!

Similar a la respuesta APL básicamente lo mismo.

'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
Conor O'Brien
fuente
No es que conozca a J, pero ¿por qué en #.invlugar de #:?
Adám
@ Adám Ah, buen punto. Usualmente uso en #.invlugar de #:, ya que algo así 2 #: 4es 0, mientras que 2 #.inv 4es1 0 0
Conor O'Brien
Sí, hago lo mismo en APL. Ahora su solución es realmente equivalente a la solución APL.
Adám
#es /; ~es ; $es ; &es ; #:es . La única diferencia es que usa infinito _mientras que podría usar 0como la respuesta APL.
Adám
@ Adám Huh, genial.
Conor O'Brien
1

Lote, 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

Toma entrada en STDIN.

Neil
fuente
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)

Salidas:

mmdcccxxxxviiii

Tenga en cuenta que el tamaño real de la línea es de 460 bytes, ya que incluye el número de entrada (2849).

Sin golf:

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     
)

Cómo funciona: calculo la cantidad de cada letra que necesito, calculando lo máximo que puedo obtener con el valor más alto uno (infinito para M), y luego haciendo una división entera entre el valor de la letra actual y el resultado de eso.

Por ejemplo, 2348, ¿cuántos Cs necesito? trunc((2348-mod(2348,500))/100)= 3.

Luego, escribo listaggesa carta 3 veces (explotando CONNECT BYpara generar las 3 filas que necesito) Finalmente, listaggtodo junto.

Un poco voluminoso, pero la mayor parte es el select from duals en la tabla de conversión y realmente no puedo hacer mucho al respecto ...

Demonblack
fuente
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;}

Pruébalo en línea!

Guardado un byte gracias a @TheLethalCoder

Olivier Grégoire
fuente
1
¿Se puede declarar vy ien el primer bucle for guardar un byte?
TheLethalCoder
@TheLethalCoder Sí, sin duda. Al principio tenía una idea totalmente diferente de que esto no pasó mi revisión interna: p
Olivier Grégoire
0

Carbón , 61 50 46 bytes

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

Pruébalo en línea!

Explicación:

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 guardados gracias a Neil, mientras todavía estoy tratando de descubrir cómo proceder con la segunda parte de su comentario.
Charlie
fuente
1
Nνes un byte más corto que ANν, ¬‹es un byte más corto que restar 1, y si usa ÷(IntDivide) en lugar de (Divide), puede usarlo φcomo la condición del bucle externo. Sin embargo, creo que puede reducirlo a 40 bytes haciendo un bucle MDCLXVIdirectamente en su lugar.
Neil
@Neil, por supuesto, tonto, tratando de entender por qué no hay un operador "mayor o igual" cuando podría usar "no menos". Truco muy inteligente el uso de la división entera. Ahora permíteme un poco de tiempo para pensar en la última parte de tu comentario ...
Charlie
Mejoré mi idea del bucle de cadena y la publiqué como una respuesta separada junto con un puerto de la respuesta Python de @ xnor, que resultó ser de la misma longitud.
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;}
HSchmale
fuente
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);}

El mismo algoritmo que antes, solo usando matrices c simples en lugar de un mapa std ::, parcialmente inspirado por la respuesta de @ xnor y usando una cadena para almacenar las letras.

HSchmale
fuente
98 bytes
techo
0

Lisp común, 113 bytes

Esta es una función anónima, que devuelve el resultado como una cadena.

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

Sin golf, con nombres de variables descriptivas y comentarios:

(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 tiene formateador de números romanos incorporado. Lamentablemente, no funciona para números superiores a 3999.

Shadowtalker
fuente
0

Carbón , 34 bytes

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

Originalmente basado en la respuesta de @ CarlosAlego. Un puerto de la solución Python de @ xnor también tiene 34 bytes:

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

Editar: ¡Un puerto de la otra solución de Python de @ xnor resulta ser 33 bytes!

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

Pruébalo en línea! El enlace es a la versión detallada del código. Tenga en cuenta que lo he usado en ⁺׳﹪φ³±¹lugar de ⁻׳﹪φ³¦¹porque el desverbosificador actualmente no puede insertar el separador.

Neil
fuente
1
Huh, eso parece más griego que romano.
Adám