Oracle SQL, 456 байт
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)
Виходи:
mmdcccxxxxviiii
Зверніть увагу, що фактичний розмір рядка становить 460 байт, оскільки він включає вхідний номер (2849).
Безголовки:
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
)
Як це працює: я обчислюю кількість кожної літери, яка мені потрібна, обчислюючи найбільшу кількість, яку я можу отримати, з більшим значенням одиниці (нескінченність для М), а потім роблю ціле ділення між значенням поточної літери та результатом цього.
Наприклад, 2348, скільки C
мені потрібно? trunc((2348-mod(2348,500))/100)
= 3.
Потім я listagg
цей лист разом 3 рази (використовую CONNECT BY
для створення 3 потрібних рядків). Нарешті, яlistagg
все разом.
Якийсь об'ємний, але більшість із них знаходиться select from dual
в таблиці перетворення, і я не можу насправді багато зробити з цього приводу ...
4 -> IIII
це9 -> VIIII
добре замістьIX
?