Aqueles romanos gananciosos!

30

Dado um número inteiro estritamente positivo, retorne o menor número romano possível usando apenas a regra aditiva. A saída deve consistir em zero ou mais de cada um dos caracteres MDCLXVInessa ordem. O número 14deve, portanto, dar XIIIIe não XIV.

Os valores numéricos dos caracteres são M= 1000, D= 500, C= 100, L= 50, X= 10, V= 5, I= 1.

Exemplos

3III

4 → IIII

9VIIII

42XXXXII

796DCCLXXXXVI

2017MMXVII

16807MMMMMMMMMMMMMMMMDCCCVII

Adão
fonte
1
Você é um questionador benevolente para permitir 4 -> IIIIé 9 -> VIIIIassim em vez de IX?
Magic Octopus Urn
@MagicOctopusUrn VIIIIé a única saída permitida para o 9. #
Adám
@ Adám estava apenas apontando que você pode adicionar isso também como exemplo, porque a regra para 4 e 9 é a mesma.
Magic Octopus Urn
1
Relacionado
Arnauld

Respostas:

12

Inglês simples , 1059 1025 678 641 451 399 bytes

Salva 34 bytes removendo uma interceptação de erro. Em seguida, salvou 384 bytes jogando golfe. Em seguida, salvou 190 bytes combinando a operação de divisão com a operação de acréscimo ("z") em uma nova operação ("p"). Em seguida, salvou 52 bytes jogando golfe.

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.

Aqui está a versão não destruída do código final, além de uma interceptação de erro para um 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
fonte
10
Espere, isso é uma linguagem de programação?
Adám
3
@ Adam - Sim. Inglês simples compila, executa e tudo mais. O código-fonte e IDE estão disponíveis em github.com/Folds/english
Jasper
1
No entanto, faça golfe - afinal, isso é código de golfe, não uma demonstração de idioma.
Sanchises
2
Então esse é o idioma que você usa se não quer que seu trabalho seja terceirizado, eu aceito?
corsiKa
@corsiKa - LOL! Somente se um número suficiente de pessoas começar a usá-lo (e aumentar suas bibliotecas) é que ele atinge massa crítica.
Jasper
5

APL (Dyalog) , 25 22 bytes

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

Experimente online!

TwiNight
fonte
Bom, e basicamente a solução que eu tinha em mente. No entanto, você pode usar replicate ( /) em vez de reformular ( ) para cortar a redução de cada e a catenata ( ¨e ,/).
Adám
Além disso, você pode converter para o corpo tradfn e receber input ( ) e usar commute ( ) para remover as parênteses e compor ( ).
Adám 27/06/17
Obrigado, mas o que você quer dizer com seu segundo comentário? Eu não consigo pensar em uma maneira de fazer isso sem aumentar a contagem de byte
TwiNight
1
Experimente online!
Adám 27/06/17
1
Isso seria um trecho menos que você conte a {}ou ∇f∇em torno da função
TwiNight
5

Retina , 57 42 bytes

Converte em unário e, em seguida, avidamente substitui grupos de Is pelas denominações mais altas em ordem.

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

Experimente online

Economizou 15 bytes graças a Martin

mbomb007
fonte
Isso é muito inteligente.
Adám
7
É muito mais curto para ir por outro caminho: tio.run/##K0otycxL/...
Martin Ender
Você não pode receber informações unárias usando Icomo unidade?
Adám 27/06
2
@ Adám Considerando que o Retina agora pode lidar facilmente com entradas inteiras, acho que é meio barato fazer isso.
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

Experimente online!

Em vez de criar a sequência de saída desde o início, ganhando avidamente a maior parte, isso a cria a partir do final. Por exemplo, o número de I's é n%5, então o número de V' s é n/5%2, e assim por diante. Isso é conversão de base mista com proporções sucessivas de 5 e 2 alternadas.

Aqui está um 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

Experimente online!

Eles Mprecisam ser manuseados separadamente, pois qualquer número deles pode estar presente, pois não há um dígito maior. Portanto, depois que os outros valores de local foram atribuídos, o valor restante é convertido emM 's.

Para comparação, uma estratégia gananciosa (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:])

Experimente online!

O valor atual do dígito dé dividido por 2 ou 5 para produzir o próximo dígito. O valor de d%3nos diz qual: se d%3==1, dividir por 2; e se d%3==2, divida por 5.

xnor
fonte
4

Mathematica, 81 bytes

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

O uso explícito dos valores e a derivação dos números correspondentes parecem ter um byte a mais:

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

Excel, 236 193 161 bytes

43 bytes salvos graças a @ BradC

Neste ponto, a resposta realmente pertence totalmente ao @ BradC . Outros 32 bytes salvos.

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

Formatado:

=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
fonte
Você economizará alguns substituindo CONCATENATEpor &entre cada elemento e QUOTIENTpor INT(A/B).
BradC
Mais 2 economias: o resultado REPTtrunca o número, se não for um número inteiro , para que você possa salvar mais 30 bytes removendo cada um INT(). Economize mais 2 substituindo ambos 1000por 1E3(embora o Excel pareça não querer mantê-lo assim quando você pressionar enter).
BradC
Sim, vi o 1E3comportamento. Resposta atualizada.
Wernisch
3

Perl 5 , 66 bytes

65 bytes de código + -psinalizador.

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

Experimente online!

Sem alterar a contagem de bytes, MDCLXVI=~/./gpode ser substituído por M,D,C,L,X,V,I; e --$|?2:5por $|--*3+2.

Muito mais tempo ( 99 bytes ), existe:

$_=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
fonte
3

CJam , 35 28 bytes

-7 bytes graças a Martin Ender

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

Experimente online!

Explicação

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 negócios
fonte
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):""

Uma declaração ternária puramente codificada usando recursão.

Versão completa / formatada:

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
fonte
n>0é justo n.
CalculatorFeline
@CalculatorFeline Não em C #, um intnão pode ser implicitamente convertido em a bool.
TheLethalCoder
Isso é lamentável.
CalculatorFeline
@CalculatorFeline Sim, o C # é muito fortemente digitado para ser útil às vezes.
TheLethalCoder
3

05AB1E , 29 26 25 bytes

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

Experimente online!

Explicação

¸                           # 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
fonte
3

JavaScript (ES6), 81 75 69 bytes

Guardado 6 bytes graças a @Neil por portar a resposta de @ Jörg Hülsermann

Guardado 6 bytes graças a @Shaggy

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

Casos de teste:

Craig Ayre
fonte
1
Você deve poder mover n%=xo repeatmétodo dentro para economizar alguns bytes.
Shaggy
1
Para sua informação, uma porta da resposta do PHP é de apenas 69 bytes:n=>'MDCLXVI'.replace(/./g,(c,i)=>c.repeat(n/a,n%=a,a/=i%2?5:2),a=1e3)
Neil
Obrigado @Neil, atualizei o post. Remove a matriz codificado que eu estava querendo voltar
Craig Ayre
2

/// , 50 bytes

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

Experimente online!

Recebe entrada em unário, e eu estou (ab) usando o campo rodapé no TIO para entrada, para que a saída seja precedida por uma nova linha.

steenbergh
fonte
2

Python 3 , 100 97 96 94 93 91 90 bytes

  • salvos 4 + 2 bytes: uso de def ; matriz como parâmetro padrão reduziu um espaço de indentação; declaração de variável indesejada removida
  • @shooqie salvou 1 byte a%= taquigrafia
  • salvou 2 bytes: reorganizados e chaves (a//i) foram removidos
  • @Wondercricket salvou 1 byte: mova a matriz do parâmetro padrão para a função que foi removida []ao custo de um espaço de recuo, economizando 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

Experimente online!

officialaimm
fonte
1
a%=ié um byte mais curto :)
shooqie
1
Você também pode salvar um byte armazenando bcomo uma variável dentro da função. Isso elimina a necessidade de suportes -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

Experimente online!

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

Assista a corrida

Consegui compactá-lo um pouco mais, mas ainda existem algumas no-ops, especialmente na face superior.

  • 52"IVXLCDM"Ucoloque os divisores e caracteres necessários na pilha. Os 5 e 2 serão usados ​​para reduzir o valor div / mod e os caracteres serão descartados após o uso.
  • UIN0/&0\&,/Uvira-se para a face superior e inicia um longo tour para obter a entrada e pressione 1000 na pilha. Uma divisão inicial é feita e uma inversão de marcha para ro próximo trecho. Esta era uma área que eu estava olhando para fazer algumas economias.
  • ,r%ws;rrinício do loop divmod. divisor inteiro, gire o resultado para fora do mod e reorganize o topo da pilha para reduzir a entrada, o divisor de corrente e o resultado da divisão.
  • 3tus traga o caractere atual para o topo e troque-o pelo resultado da divisão.
  • !vsoUs(0;Uesse é o loop de impressão. enquanto o resultado div for maior que 0, troque com saída de caractere, troque de volta, diminua, pressione 0 e solte-o. Em 0, redirecione sobre a pilha pop (remova o resultado da divisão) e ao redor do cubo.
  • \u;pwpsq,!@Urq;ucom um pouco de redirecionamento, isso remove o personagem da pilha, coloca os 5 e 2 no topo, troca-os e empurra um de volta. O restante é usado para reduzir o divisor. Pare se reduzir para 0, caso contrário, empurre os 5 ou 2 para baixo e insira novamente o loop.
MickyT
fonte
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
fonte
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'))

Experimente online!

Cajado
fonte
1000pode ser 1e3(se você não se importa que seja uma bóia que não deve ser um problema)
CalculatorFeline
@CalculatorFeline seria transformar o resultado em um float, e você não pode multiplicar uma string por um 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

Quebras de linha adicionadas apenas para facilitar a leitura.

Esta versão é muito mais longa (230 caracteres), mas parece muito mais "semelhante a 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

Cria uma tabela m com todos os mapeamentos de valor de char e, em seguida, procura o maior valor <= o número, concatenando o caractere correspondente.

BradC
fonte
1

Japonês , 34 bytes

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

Teste 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
ETHproductions
fonte
1

JavaScript (ES6), 65 bytes

Uma função recursiva.

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

Quão?

A segunda chamada recursiva f(n-a)realmente deveria ser f(n-a,a). Ao omitir o 2º parâmetro, aei são reinicializados (para 1000 e 0 respectivamente) cada vez que um novo dígito romano é anexado ao resultado final. Isso causa mais recursão do que o necessário, mas não altera o resultado da função e economiza 2 bytes.

Casos de teste

Arnauld
fonte
1

J , 26 23 bytes

3 bytes salvos graças a Adám.

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

Experimente online!

Semelhante à resposta do APL basicamente a mesma coisa.

'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
fonte
Não que eu conheça J, mas por que em #.invvez de #:?
Adám 27/06
@ Adám Ah, bom ponto. Eu costumo usar, em #.invvez de #:, uma vez que algo como 2 #: 4é 0, enquanto 2 #.inv 4é1 0 0
Conor O'Brien
Sim, eu faço a mesma coisa no APL. Agora sua solução é realmente equivalente à solução APL.
Adám
#é /; ~é ; $é ; &é ; #:é . A única diferença é que você usa o infinito _enquanto pode usar 0como a resposta da APL.
Adám 27/06/17
@ Adám Huh, legal.
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

Recebe entrada em STDIN.

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

Saídas:

mmdcccxxxxviiii

Observe que o tamanho real da linha é 460 bytes, porque inclui o número de entrada (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     
)

Como funciona: calculo quantas letras de cada letra preciso, calculando o máximo possível com o valor mais alto (infinito para M) e, em seguida, fazendo uma divisão inteira entre o valor da letra atual e o resultado disso.

Por exemplo, 2348, quantos Cs eu preciso? trunc((2348-mod(2348,500))/100)= 3

Então, eu listaggletra juntos três vezes (explorando CONNECT BYpara gerar as três linhas necessárias). Finalmente eulistagg tudo junto.

Meio volumoso, mas a maioria está select from dualna tabela de conversão e não posso fazer muito sobre isso ...

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

Experimente online!

Guardou um byte graças a @TheLethalCoder

Olivier Grégoire
fonte
1
Você pode declarar ve, ino primeiro loop for, salvar um byte?
TheLethalCoder
@TheLethalCoder Sim, com certeza. No começo, eu tinha uma idéia totalmente diferente de que isso não passou na minha análise interna: p
Olivier Grégoire
0

Carvão , 61 50 46 bytes

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

Experimente online!

Explicação:

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 salvos graças a Neil, enquanto eu ainda estou tentando descobrir como proceder com a segunda parte de seu comentário.
Charlie
fonte
1
Nνé um byte menor que ANν, ¬‹é um byte menor que subtraindo 1 e, se você usar ÷(IntDivide) em vez de (Divide), poderá usar φcomo condição de loop externo. No entanto, acho que você pode reduzi-lo a 40 bytes fazendo um loop MDCLXVIdireto diretamente.
Neil
@ Neil, é claro, bobo, tentando entender por que não existe um operador "maior ou igual" quando eu poderia usar "não menos". Truque muito inteligente do uso da divisão inteira. Agora, permita-me algum tempo para pensar sobre a última parte do seu comentário ...
Charlie
Aprimorei minha idéia de loop de strings e a publiquei como uma resposta separada, juntamente com uma porta da resposta Python do @ xnor, que acabou sendo do mesmo tamanho.
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
fonte
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);}

O mesmo algoritmo de antes, apenas usando matrizes c simples em vez de um std :: map, parcialmente inspirado na resposta do @ xnor e usando uma string para armazenar as letras.

HSchmale
fonte
98 bytes
ceilingcat 11/11
0

Lisp comum, 113 bytes

Esta é uma função anônima, retornando o resultado como uma sequência.

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

Ungolfed, com nomes descritivos de variáveis ​​e comentários:

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

O CL possui um formatador de numeral romano interno. Infelizmente, ele não funciona para números maiores que 3999.

shadowtalker
fonte
0

Carvão , 34 bytes

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

Originalmente baseado na resposta de @ CarlosAlego. Uma porta da solução Python do @ xnor também tem 34 bytes:

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

Edit: Uma porta da outra solução Python do @ xnor é de 33 bytes!

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

Experimente online! Link é a versão detalhada do código. Observe que eu usei, em ⁺׳﹪φ³±¹vez de, ⁻׳﹪φ³¦¹porque o deverbosifier atualmente não está inserindo o separador.

Neil
fonte
1
Huh, isso parece mais grego do que romano.
Adám 28/06