Quei golosi romani!


30

Dato un numero intero strettamente positivo, restituisce il numero romano più breve possibile usando solo la regola dell'additivo. L'output deve essere composto da zero o più di ciascuno dei caratteri MDCLXVIin quell'ordine. Il numero 14deve quindi dare XIIIIpiuttosto che XIV.

I valori numerici dei caratteri sono M= 1000, D= 500, C= 100, L= 50, X= 10, V= 5, I= 1.

Esempi

3III

4 → IIII

9VIIII

42XXXXII

796DCCLXXXXVI

2017MMXVII

16807MMMMMMMMMMMMMMMMDCCCVII


1
Sei un interrogatore benevolo per consentire 4 -> IIIIè 9 -> VIIIIanche invece di IX?
Magic Octopus Urn,


@MagicOctopusUrn VIIIIè l'unica uscita consentita per 9.
Adám,

@Adám stava solo sottolineando che potresti voler aggiungere anche questo come esempio perché le regole per 4 e 9 sono le stesse.
Magic Octopus Urn,

Risposte:


12

Inglese semplice , 1059 1025 678 641 451 399 byte

Salvato 34 byte rimuovendo una trap di errore. Quindi salvato 384 byte giocando a golf. Quindi salvato 190 byte combinando l'operazione di divisione con l'operazione di accodamento ("z") in una nuova operazione ("p"). Quindi salvato 52 byte giocando a 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.

Ecco la versione non modificata del codice finale, oltre a una trap di errore per un numero 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
Aspetta, è un linguaggio di programmazione?
Adám,

3
@Adam - Sì. Compilazioni e corre in inglese semplice e tutto il resto. Il codice sorgente e l'IDE sono disponibili su github.com/Folds/english
Jasper il

1
Fai il golf però - dopo tutto, questo è il golf del codice, non una vetrina linguistica.
Sanchises,

2
Quindi questa è la lingua che usi se non vuoi che il tuo lavoro in outsourcing lo prenda?
corsiKa,

@corsiKa - LOL! Solo se un numero sufficiente di noi inizia a usarlo (e ad aggiungerlo alle sue librerie) per raggiungere la massa critica.
Jasper,

5

APL (Dyalog) , 25 22 byte

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

Provalo online!


Bello, e sostanzialmente la soluzione che avevo in mente. Tuttavia, puoi usare replicate ( /) invece di reshape ( ) in modo da poter tagliare ciascuna e la riduzione della catenata ( ¨e ,/).
Adám,

Inoltre, puoi convertire in tradfn body e prendere input ( ) e usare commute ( ) per rimuovere le parentesi e compose ( ).
Adám,

Grazie, ma cosa intendi con il tuo secondo commento? Non riesco a pensare a un modo per farlo senza aumentare il conteggio dei byte
TwiNight il


1
Sarebbe uno snippet a meno che non conti la funzione circostante {}o ∇f∇che la circonda
TwiNight,

5

Retina , 57 42 byte

Converte in unario, quindi sostituisce avidamente gruppi di Is con le denominazioni più alte in ordine.

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

Provalo online

Risparmiato 15 byte grazie a Martin


È molto intelligente.
Adám,

7
È molto più breve andare nell'altra direzione: tio.run/##K0otycxL/…
Martin Ender

Non potresti prendere input in unario usando Icome unità?
Adám,

2
@ Adám Considerando che Retina ora può facilmente gestire l'input di numeri interi, penso che sia un po 'economico farlo.
mbomb007,

5

Python 2 , 64 byte

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

Provalo online!

Piuttosto che creare la stringa di output dall'inizio prendendo avidamente la maggior parte, questo la crea dalla fine. Ad esempio, il numero di Iè n%5, quindi il numero di Vè n/5%2e così via. Questa è una conversione di base mista con rapporti successivi di 5 e 2 alternati.

Ecco un equivalente iterativo:

Python 2 , 68 byte

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

Provalo online!

È Mnecessario gestirle separatamente perché un numero qualsiasi di esse potrebbe essere presente in quanto non esiste una cifra più grande. Quindi, dopo aver assegnato gli altri valori di luogo, il valore rimanente viene convertito in M"s".

Per confronto, una strategia avida (69 byte):

Python 2 , 69 byte

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

Provalo online!

Il valore della cifra corrente dviene diviso per 2 o 5 per produrre la cifra successiva. Il valore di d%3dicci quale: se d%3==1, dividi per 2; e se d%3==2, dividi per 5.


4

Mathematica, 81 byte

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

L'uso esplicito dei valori e la derivazione dei numeri corrispondenti sembra essere più lungo di un byte:

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

1
Bello !:FromRomanNumeral@r
DavidC,

4

Excel, 236 193 161 byte

43 byte salvati grazie a @ BradC

A questo punto, la risposta appartiene davvero totalmente a @ BradC . Altri 32 byte salvati.

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

formattato:

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

Ne risparmierai alcuni sostituendoli CONCATENATEcon &tra ciascun elemento e QUOTIENTcon INT(A/B).
BradC,

2 ulteriori risparmi: risulta che troncaREPT già il numero se non è un numero intero , quindi è possibile salvare altri 30 byte rimuovendoli ciascuno INT(). Risparmia altri 2 sostituendoli entrambi 1000con 1E3(anche se Excel non sembra voler mantenerlo in questo modo una volta che premi Invio).
BradC,

Sì, ho visto il 1E3comportamento. Risposta aggiornata
Wernisch,

3

Perl 5 , 66 byte

65 byte di codice + -pflag.

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

Provalo online!

Senza modificare il conteggio dei byte, MDCLXVI=~/./gpuò essere sostituito da M,D,C,L,X,V,I; e --$|?2:5di $|--*3+2.

Molto più lungo ( 99 byte ), c'è:

$_=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 byte

-7 byte grazie a Martin Ender

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

Provalo online!

Spiegazione

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 byte

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 dichiarazione ternaria puramente codificata usando la ricorsione.

Versione completa / formattata:

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è giusto n.
Calcolatrice

@CalculatorFeline Non in C #, intnon è possibile eseguire il cast implicito di a bool.
TheLethalCoder

È un peccato.
Calcolatrice

@CalculatorFeline Sì, C # è tipizzato troppo fortemente per il suo bene a volte.
TheLethalCoder

3

05AB1E , 29 26 25 byte

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

Provalo online!

Spiegazione

¸                           # 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 byte

6 byte salvati grazie a @Neil per il porting della risposta di Jörg Hülsermann

6 byte salvati grazie a @Shaggy

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

Casi test:


1
Dovresti essere in grado di spostare n%=xall'interno del repeatmetodo per salvare alcuni byte.
Shaggy,

1
Cordiali saluti un porto della risposta PHP è solo 69 byte:n=>'MDCLXVI'.replace(/./g,(c,i)=>c.repeat(n/a,n%=a,a/=i%2?5:2),a=1e3)
Neil

Grazie @Neil, ho aggiornato il post. Rimuove l'array hard coded che volevo rivisitare
Craig Ayre,

2

/// , 50 byte

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

Provalo online!

Prende l'input in unario e sto (ab) usando il campo footer su TIO per l'input, quindi l'output è preceduto da una nuova riga.


2

Python 3 , 100 97 96 94 93 91 90 byte

  • 4 + 2 byte salvati: utilizzo di def; l'array come parametro predefinito ha ridotto uno spazio di rientro; dichiarazione di variabile indesiderata rimossa
  • @shooqie salvati 1 byte a%=stenografia
  • salvato 2 byte: riorganizzato e le parentesi graffe (a//i)sono state rimosse
  • @Wondercricket ha salvato 1 byte: sposta l'array dal parametro predefinito all'interno della funzione che è stata rimossa []al costo di uno spazio di rientro, risparmiando così 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

Provalo online!


1
a%=iè un byte più breve :)
shooqie,

1
È inoltre possibile salvare un byte memorizzandolo bcome variabile all'interno della funzione. Ciò elimina la necessità delle parentesi -b=1000,500,100,50,10,5,1
Wondercricket,

2

Cubix , 69 74 80 byte

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

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

Guardalo in esecuzione

Sono riuscito a comprimerlo un po 'di più, ma ci sono ancora alcune fastidiose no-op, specialmente sulla faccia superiore.

  • 52"IVXLCDM"Umettere in pila i divisori e i personaggi necessari. 5 e 2 verranno utilizzati per ridurre il valore div / mod e i caratteri verranno eliminati dopo l'uso.
  • UIN0/&0\&,/Uu-gira sulla faccia superiore e inizia un lungo tour per ottenere l'input e spingere 1000 nello stack. Viene eseguita una divisione iniziale e un'inversione a U rdel snippet successivo. Questa era un'area che stavo guardando per risparmiare.
  • ,r%ws;rrinizio del loop divmod. divisione intera, ruota il risultato via mod, quindi riorganizza la parte superiore dello stack per ridurre l'input, il divisore corrente e dividere il risultato.
  • 3tus porta il personaggio attuale in alto e scambialo con il risultato di divisione.
  • !vsoUs(0;Uquesto è il ciclo di stampa. mentre il risultato div è maggiore di 0, scambia con output di caratteri, scambia indietro, decrementa, premi uno 0 e rilascialo. Su 0 reindirizzare sullo stack pop (rimuovere il risultato di divisione) e attorno al cubo.
  • \u;pwpsq,!@Urq;ucon un po 'di reindirizzamento, questo rimuove il personaggio dalla pila, porta i 5 e 2 in cima, li scambia e li spinge indietro. Il rimanente viene utilizzato per ridurre il divisore. Arrestare se si riduce a 0, altrimenti spingere 5 o 2 in basso e rientrare nel loop.

1

Mathematica, 130 byte

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

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

Provalo online!


1000può essere 1e3(se non ti dispiace che sia un float che non dovrebbe essere un problema)
CalculatorFeline

@CalculatorFeline trasformerebbe il risultato in a float, e non puoi moltiplicare una stringa per un float: c
Rod


1

T-SQL, 164 byte

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

Le interruzioni di riga sono state aggiunte solo per la leggibilità.

Questa versione è molto più lunga (230 caratteri), ma sembra molto più "simile 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

Crea una tabella m con tutte le mappature del valore del char, quindi passa in rassegna la ricerca del valore più grande <= il numero, concatenando il carattere corrispondente.


1

Japt , 34 byte

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

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

Una funzione ricorsiva.

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

Come?

La seconda chiamata ricorsiva f(n-a)dovrebbe essere davvero f(n-a,a). Omettendo il secondo parametro ae ivengono reinizializzati (rispettivamente a 1000 e 0) ogni volta che una nuova cifra romana viene aggiunta al risultato finale. Ciò provoca più ricorsione del necessario ma non altera l'esito della funzione e consente di risparmiare 2 byte.

Casi test


1

J , 26 23 byte

3 byte salvati grazie ad Adám.

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

Provalo online!

Simile alla risposta APL sostanzialmente la stessa cosa.

'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

Non che conosca J, ma perché #.invinvece di #:?
Adám,

@ Adám Ah, buon punto. Di solito lo uso #.invinvece di #:, poiché qualcosa del genere 2 #: 4è 0, mentre 2 #.inv 4è1 0 0
Conor O'Brien il

Sì, faccio la stessa cosa in APL. Ora la tua soluzione è veramente equivalente alla soluzione APL.
Adám,

#è /; ~è ; $è ; &è ; #:lo è . L'unica differenza è che usi l'infinito _mentre potresti usare 0come la risposta APL.
Adám,

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

1

Lotto, 164 byte

@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

Accetta input su STDIN.


1

Oracle SQL, 456 byte

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)

Uscite:

mmdcccxxxxviiii

Si noti che la dimensione effettiva della linea è 460 byte, poiché include il numero di input (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     
)

Come funziona: calcolo il numero di ciascuna lettera di cui ho bisogno, calcolando il massimo che posso ottenere con il valore più alto uno (infinito per M) e quindi facendo una divisione intera tra il valore della lettera corrente e il risultato di quello.

Ad esempio 2348, quanti C s ho bisogno? trunc((2348-mod(2348,500))/100)= 3.

Quindi, listaggquella lettera insieme 3 volte (sfruttandoCONNECT BY per generare le 3 file di cui ho bisogno). Alla fine, ho listaggtutto insieme.

Un po 'ingombrante, ma la maggior parte è la select from duals nella tabella di conversione e non posso davvero fare molto al riguardo ...


0

Java (OpenJDK 8) , 119 118 byte

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

Provalo online!

Salvataggio di un byte grazie a @TheLethalCoder


1
Puoi dichiarare ve inel primo per loop salvare un byte?
TheLethalCoder il

@TheLethalCoder Sì, sicuramente. All'inizio avevo un'idea totalmente diversa che questo non avesse superato la mia recensione interna: p
Olivier Grégoire,

0

Carbone , 61 50 46 byte

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

Provalo online!

Spiegazione:

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 byte salvati grazie a Neil, mentre sto ancora cercando di capire come procedere con la seconda parte del suo commento.

1
Nνè un byte più corto di ANν, ¬‹è un byte più corto della sottrazione di 1 e se si utilizza ÷(IntDivide) anziché (Divide), è possibile utilizzare φcome condizione del loop esterno. Tuttavia, penso che sia possibile ridurlo a 40 byte eseguendo il ciclo MDCLXVIdirettamente invece.
Neil,

@Neil ovviamente, sciocco, cercando di capire perché non esiste un operatore "maggiore o uguale" quando potrei usare "non meno". Inganno molto intelligente l'uso della divisione intera. Ora lasciami un po 'di tempo per pensare all'ultima parte del tuo commento ...
Charlie,

Ho migliorato la mia idea del loop di stringhe e l'ho pubblicata come risposta separata insieme a una porta della risposta Python di @ xnor, che si è rivelata della stessa lunghezza.
Neil,

0

C ++, 272 byte

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

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

Stesso algoritmo di prima, usando semplicemente matrici c invece di una std :: map, parzialmente ispirata alla risposta di @ xnor e usando una stringa per memorizzare le lettere.



0

Lisp comune, 113 byte

Questa è una funzione anonima, che restituisce il risultato come una stringa.

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

Non golfato, con nomi e commenti variabili descrittivi:

(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 ha un formattatore per numeri romani incorporato. Purtroppo non funziona per numeri superiori a 3999.


0

Carbone , 34 byte

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

Originariamente basato sulla risposta di @ CarlosAlego. Una porta della soluzione Python di @ xnor è anche di 34 byte:

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

Modifica: una porta dell'altra soluzione Python di @ xnor risulta essere di 33 byte!

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Si noti che ho usato ⁺׳﹪φ³±¹invece ⁻׳﹪φ³¦¹perché il deverbosifier non riesce attualmente a inserire il separatore.


1
Eh, sembra più greco che romano.
Adám,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.