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)
Ausgänge:
mmdcccxxxxviiii
Bitte beachten Sie, dass die tatsächliche Größe der Zeile 460 Byte beträgt, da sie die Eingabenummer (2849) enthält.
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
)
Wie es funktioniert: Ich berechne, wie viele von jedem Buchstaben ich brauche, indem ich mit dem höheren Wert eins (unendlich für M) das Maximum errechne und dann eine ganzzahlige Division zwischen dem Wert des aktuellen Buchstabens und dem Ergebnis desselben durchführe.
ZB 2348, wie viele C
s brauche ich? trunc((2348-mod(2348,500))/100)
= 3.
Dann habe ich listagg
diesen Brief 3 mal zusammen (ausnutzen CONNECT BY
, um die 3 Zeilen zu generieren, die ich brauche). Zum Schluss hab ich listagg
alles zusammen.
Ein bisschen sperrig, aber das meiste ist das select from dual
s in der Umrechnungstabelle und ich kann nicht wirklich viel dagegen tun ...
4 -> IIII
ist9 -> VIIII
auch stattIX
?