Ці жадібні римляни!


30

Давши суворо додатне ціле число, поверніть найкоротший можливий римський номер, використовуючи лише правило добавки. Вихід повинен складатися з нуля або більше кожного з символів MDCLXVIу цьому порядку. Тому число 14повинно бути XIIIIбільше, ніж XIV.

Числові значення символів M= 1000, D= 500, C= 100, L= 50, X= 10, V= 5, I= 1.

Приклади

3III

4 → IIII

9VIIII

42XXXXII

796DCCLXXXXVI

2017MMXVII

16807MMMMMMMMMMMMMMMMDCCCVII


1
Ви доброзичливий запитувач, щоб дозволити 4 -> IIIIце 9 -> VIIIIдобре замість IX?
Чарівний восьминога Урна


@MagicOctopusUrn VIIII- єдиний дозволений вихід для 9.
Adám

@ Adám просто вказував, що ви можете також додати це як приклад, тому що правило для 4 та 9 однакове.
Чарівний восьминіг Урна

Відповіді:


12

Звичайна англійська , 1059 1025 678 641 451 399 байт

Збережено 34 байти, видаливши пастку помилок. Потім врятував 384 байти, погравши в гольф. Потім збережено 190 байт, поєднавши операцію поділу з операцією додавання ("z") в нову операцію ("p"). Потім врятував 52 байти гольфу.

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.

Ось нерозроблена версія кінцевого коду, плюс помилка для помилки для від'ємного числа:

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
Зачекайте, це мова програмування?
Adám

3
@Adam - Так. Простий англійський компілює, і працює, і все. Вихідний код та IDE доступні на веб-
Jasper

1
Хоча займайтеся гольфом - адже це гольф з кодом, а не мовна вітрина.
Санчіз

2
Отже, це мова, якою ви користуєтесь, якщо не хочете, щоб ваша робота передавалася сторонніми, я її вважаю?
corsiKa

@corsiKa - LOL! Тільки якщо достатньо з нас починає використовувати його (і додаючи до його бібліотек), що він досягає критичної маси.
Джаспер

5

APL (Dyalog) , 25 22 байт

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

Спробуйте в Інтернеті!


Приємне, і в основному рішення, яке я мав на увазі. Однак ви можете використовувати репліку ( /) замість переформатування ( ), щоб ви могли вирізати кожне та зменшення катенатів ( ¨і ,/).
Адам

Крім того, ви можете перетворити в body tradfn і взяти input ( ) і використовувати commute ( ) для видалення паролів і compose ( ).
Адам

Дякую, але що ви маєте на увазі під своїм другим коментарем? Я не можу придумати спосіб зробити це без збільшення кількості байтів
TwiNight,


1
Це був би фрагмент, якщо ви не {}∇f∇
порахуєте

5

Сітківка , 57 42 байти

Перетворюється в одинарний, потім жадібно замінює пучки Is з вищими номіналами в порядку.

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

Спробуйте в Інтернеті

Збережено 15 байт завдяки Мартіну


Це дуже розумно.
Adám

7
Набагато коротше піти іншим шляхом: tio.run/##K0otycxL/…
Мартін Ендер

Не могли б ви взяти вклад не в одинаковому використанні Iяк одиниця?
Адам

2
@ Adám Враховуючи, що Retina тепер може легко обробляти цілі дані, я думаю, що це зробити дешево.
mbomb007

5

Python 2 , 64 байти

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

Спробуйте в Інтернеті!

Замість того, щоб створювати вихідний рядок із самого початку, жадібно беручи найбільшу роль, це створює його з кінця. Наприклад, число Is є n%5, тоді число Vs є n/5%2і так далі. Це змішане базове перетворення з послідовними співвідношеннями 5 і 2 чергуються.

Ось ітеративний еквівалент:

Python 2 , 68 байт

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

Спробуйте в Інтернеті!

MПотреба «s буде оброблятися окремо , так як будь-яке число з них може бути присутнім як немає більше цифр. Отже, після призначення інших значень місця, залишкове значення перетворюється в Ms.

Для порівняння, жадібна стратегія (69 байт):

Python 2 , 69 байт

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

Спробуйте в Інтернеті!

Поточне значення цифри dділиться або 2, або 5 для отримання наступної цифри. Значення d%3скажіть нам, яке: якщо d%3==1, розділити на 2; а якщо d%3==2, розділіть на 5.


4

Математика, 81 байт

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

Явно використання значень та отримання відповідних цифр, здається, на один байт довше:

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

1
Приємно !:FromRomanNumeral@r
DavidC

4

Excel, 236 193 161 байт

43 байти збережено завдяки @ BradC

На даний момент відповідь справді повністю належить @ BradC . Ще 32 байти збережено.

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

Відформатовано:

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

Ви заощадите, замінивши деякі CONCATENATEз &між кожним елементом, і QUOTIENTз INT(A/B).
БредК

Ще 2 заощадження: виявляється, REPTвже скорочується число, якщо це не ціле число , тому ви можете зберегти ще 30 байт, видаливши кожен INT(). Збережіть ще 2, замінивши обидва 1000на 1E3(хоча, схоже, Excel не хоче зберегти це таким чином, як тільки натисніть клавішу Enter).
БредК

Так, бачив 1E3поведінку. Відповідь оновлено.
Wernisch

3

Perl 5 , 66 байт

65 байт коду + -pпрапор.

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

Спробуйте в Інтернеті!

Не змінюючи кількість байтів, MDCLXVI=~/./gйого можна замінити на M,D,C,L,X,V,I; і --$|?2:5за $|--*3+2.

Набагато довше ( 99 байт ), є:

$_=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 байт

-7 байт завдяки Мартіну Ендеру

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

Спробуйте в Інтернеті!

Пояснення

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 байт

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

Суто твердий кодований потрійний вислів із використанням рекурсії.

Повна / відформатована версія:

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просто n.
CalculatorFeline

@CalculatorFeline Не в C #, не intможе бути неявно передано до а bool.
TheLethalCoder

Це прикро.
CalculatorFeline

@CalculatorFeline Так, C # занадто сильно набраний, щоб іноді це було власно.
TheLethalCoder

3

05AB1E , 29 26 25 байт

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

Спробуйте в Інтернеті!

Пояснення

¸                           # 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 байт

Збережено 6 байт завдяки @Neil за перенесення відповіді @ Йорга Гюльсермана

Збережено 6 байт завдяки @Shaggy

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

Тестові приклади:


1
Ви повинні мати можливість перемістити метод у n%=xмежах, repeatщоб зберегти кілька байт.
Кудлатий

1
FYI порт відповіді PHP складає всього 69 байт:n=>'MDCLXVI'.replace(/./g,(c,i)=>c.repeat(n/a,n%=a,a/=i%2?5:2),a=1e3)
Ніл

Дякую @Neil, я оновив пост. Видаляє важко закодований масив, який я хотів переглянути
Craig Ayre

2

/// , 50 байт

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

Спробуйте в Інтернеті!

Вводиться в одинаковому режимі, і я (ab) використовує поле нижнього колонтитулу на TIO для введення, тому виводу передує новий рядок.


2

Python 3 , 100 97 96 94 93 91 90 байт

  • збережені 4 + 2 байти: використання def; масив як параметр за замовчуванням зменшив простір відступу; видалено небажану декларацію змінної
  • @shooqie врятував 1 байт a%=стенограми
  • збережено 2 байти: переставлено і дужки у (a//i)видалено
  • @Wondercricket зберег 1 байт: перемістіть масив з параметра за замовчуванням у функцію, яку вилучили []за рахунок одного простору відступу, заощадивши таким чином 1 байт.
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

Спробуйте в Інтернеті!


1
a%=iє байт коротше :)
shooqie

1
Ви також можете зберегти байт, зберігаючи bяк змінну у межах функції. Це знімає необхідність дужок -b=1000,500,100,50,10,5,1
Wondercricket

2

Cubix , 69 74 80 байт

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

Спробуйте в Інтернеті!

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

Дивитися, як це працює

Мені вдалося трохи більше стиснути його, але все ще є пестливі недоліки, особливо на верхній частині обличчя.

  • 52"IVXLCDM"Uпокладіть на стек необхідні дільники та символи. 5 і 2 будуть використані для зменшення значення div / mod, а символи будуть відкинуті після використання.
  • UIN0/&0\&,/Uповертається на верхню поверхню і починає довгий тур, щоб отримати вхід і натиснути 1000 на стек. Виконується початковий поділ і повертається на rнаступний фрагмент. Це була сфера, на яку я дивився, щоб заощадити.
  • ,r%ws;rrпочаток циклу divmod. ціле ділення, повернути результат від мода, потім переставити верхню частину стека, щоб зменшити вхід, дільник потоку і ділити результат.
  • 3tus піднесіть поточний персонаж до верху і поміняйте його результатом ділення.
  • !vsoUs(0;Uце петля друку. в той час як результат діла більше 0, поміняйте місцями з виведенням символів, поміняйте назад, зменшенням, натисніть 0 і опустіть його. У режимі 0 переспрямуйте через поп-стек (видаліть результат ділення) та навколо куба.
  • \u;pwpsq,!@Urq;uз невеликим перенаправленням це виймає персонажа зі стека, підводить 5 і 2 до вершини, міняє їх і відсуває одну назад вниз. Решта використовується для зменшення дільника. Зупиніть, якщо він зменшиться до 0, інакше натисніть на 5 або 2 донизу і знову введіть цикл.

1

Математика, 130 байт

(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 байт

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

Спробуйте в Інтернеті!


1000може бути 1e3(якщо ви не заперечуєте, що це float, що не повинно бути проблемою)
CalculatorFeline

@CalculatorFeline це перетворить результат на a float, і ви не можете помножити рядок на поплавок: c
Rod


1

T-SQL, 164 байти

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

Розриви рядків додаються лише для читабельності.

Ця версія набагато довша (230 символів), але відчуває себе набагато більше "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

Створює таблицю m із усіма відображеннями значущих значень, а потім циклічно знаходить знаходження найбільшого значення <= числа, об'єднуючи відповідний символ.


1

Japt , 34 байти

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

Перевірте це в Інтернеті!

"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 байт

Рекурсивна функція.

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

Як?

Другий рекурсивний дзвінок f(n-a)справді повинен бути f(n-a,a). Опускаючи 2-й параметр, aі iповторно ініціалізуються (до 1000 і 0 відповідно) кожен раз, коли до кінцевого результату додається нова римська цифра. Це викликає більше рекурсії, ніж потрібно, але не змінює результат функції та економить 2 байти.

Тестові справи


1

J , 26 23 байти

3 байти збережено завдяки Adám.

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

Спробуйте в Інтернеті!

Подібно до відповіді APL в основному те саме.

'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

Не те, щоб я знав J, але чому #.invзамість цього #:?
Адам

@ Adám Ах, хороший момент. Я звичайно використовую #.invзамість цього #:, оскільки щось подібне 2 #: 4є 0, в той час як 2 #.inv 4це1 0 0
Conor O'Brien

Так, я роблю те ж саме в APL. Тепер ваше рішення справді еквівалентне рішенню APL.
Адам

#є /; ~є ; $є ; &є ; #:є . Єдина відмінність полягає в тому, що ви використовуєте нескінченність, _тоді як можете використовувати 0як відповідь APL.
Adám

@ Адам Ху, класно.
Conor O'Brien

1

Пакетна, 164 байти

@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

Здійснює введення даних STDIN.


1

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в таблиці перетворення, і я не можу насправді багато зробити з цього приводу ...


0

Java (OpenJDK 8) , 119 118 байт

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

Спробуйте в Інтернеті!

Збережено байт завдяки @TheLethalCoder


1
Чи можете ви оголосити vі iв першому циклі зберегти байт?
TheLethalCoder

@TheLethalCoder Так, звичайно. Спочатку я був зовсім іншою ідеєю, що це не пройшло мого внутрішнього огляду: p
Олів'є Грегоар

0

Вугілля деревне , 61 50 46 байт

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

Спробуйте в Інтернеті!

Пояснення:

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 байти збереглися завдяки Нілу, і я ще намагаюся розібратися, як діяти з другою частиною його коментаря.

1
Nνє на один байт коротший ANν, ¬‹на один байт коротший, ніж віднімання 1, і якщо ви використовуєте ÷(IntDivide) замість (Divide), то ви можете використовувати φяк стан зовнішньої петлі. Однак я думаю, що ви можете зменшити її до 40 байт, перейшовши MDCLXVIбезпосередньо натомість.
Ніл

@Neil, звичайно, нерозумно мене, намагаючись зрозуміти, чому немає "більшого або рівного" оператора, коли я міг би використовувати "не менше". Дуже розумна хитрість використання цілого ділення. Тепер дозвольте мені подумати над останньою частиною вашого коментаря ...
Чарлі

Я вдосконалив ідею циклу рядків і розмістив її як окрему відповідь разом з портом відповіді Python @ xnor, який виявився однакової довжини.
Ніл

0

C ++, 272 байт

#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 байт

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

Той самий алгоритм, що і раніше, просто використовуючи звичайні масиви c замість std :: map, частково надихнувшись відповіддю @ xnor та використовуючи рядок для зберігання літер.



0

Лист звичайний, 113 байт

Це анонімна функція, що повертає результат у вигляді рядка.

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

Безголосистий, з описовими назвами змінних та коментарями:

(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 має вбудований форматор римських цифр. На жаль, він не працює для номерів, більших за 3999.


0

Вугілля деревне , 34 байти

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

Спочатку ґрунтувався на відповіді @ CarlosAlego. Порт рішення Python @ xnor також становить 34 байти:

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

Редагувати: Порта іншого рішення Python @ xnor виявляється 33 байтом!

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

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Зауважте, що я використовував ⁺׳﹪φ³±¹замість того, ⁻׳﹪φ³¦¹що девербосифікатор наразі не вдається вставити роздільник.


1
Так, це більше схоже на грецьку, ніж римську.
Adám
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.