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


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

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.

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!


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


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.


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}<>""&

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

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)

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.

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

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

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:


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.


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!


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.

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

Experimente online!


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.


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

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


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

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.


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


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


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.

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

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.



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.


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.


1
Huh, isso parece mais grego do que romano.
Adám 28/06
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.