Những người La Mã tham lam!


30

Cho một số nguyên dương hoàn toàn, trả về số La Mã ngắn nhất có thể chỉ bằng quy tắc cộng. Đầu ra phải bao gồm 0 hoặc nhiều hơn mỗi ký tự MDCLXVItheo thứ tự đó. Con số 14do đó phải đưa ra XIIIIchứ không phải XIV.

Giá trị số của các ký tự là M= 1000, D= 500, C= 100, L= 50, X= 10, V= 5, I= 1.

Ví dụ

3III

4 → IIII

9VIIII

42XXXXII

796DCCLXXXXVI

2017MMXVII

16807MMMMMMMMMMMMMMMMDCCCVII


1
Bạn có phải là một người hỏi nhân từ để cho phép 4 -> IIII9 -> VIIIItốt thay vì IX?
Bạch tuộc ma thuật Urn


@MagicOctopusUrn VIIIIlà đầu ra được phép duy nhất cho 9.
Adám

@ Adám chỉ nêu ra rằng bạn có thể muốn thêm nó làm ví dụ vì quy tắc cho 4 và 9 là như nhau.
Bạch tuộc ma thuật Urn

Câu trả lời:


12

Tiếng Anh đơn giản , 1059 1025 678 641 451 399 byte

Đã lưu 34 byte bằng cách loại bỏ một bẫy lỗi. Sau đó lưu 384 byte bằng cách chơi golf. Sau đó, đã lưu 190 byte bằng cách kết hợp hoạt động phân chia với hoạt động chắp thêm ("z") vào một hoạt động mới ("p"). Sau đó lưu 52 byte bằng cách chơi 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.

Đây là phiên bản không mã hóa của mã cuối cùng, cộng với bẫy lỗi cho số âm:

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
Đợi đã, đây có phải là ngôn ngữ lập trình không?
Adám

3
@Adam - Vâng. Đồng bằng tiếng Anh biên dịch, và chạy, và tất cả mọi thứ. Mã nguồn và IDE có sẵn tại github.com/Folds/english
Jasper

1
Chơi golf mặc dù - sau tất cả, đây là golf mã, không phải là một ngôn ngữ giới thiệu.
Sanchise

2
Vì vậy, đây là ngôn ngữ bạn sử dụng nếu bạn không muốn công việc của mình thuê ngoài?
corsiKa

@corsiKa - LOL! Chỉ khi đủ chúng ta bắt đầu sử dụng nó (và thêm vào thư viện của nó) thì nó mới đạt được khối lượng quan trọng.
Jasper

5

APL (Dyalog) , 25 22 byte

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

Hãy thử trực tuyến!


Đẹp, và về cơ bản là giải pháp tôi có trong tâm trí. Tuy nhiên, bạn có thể sử dụng bản sao ( /) thay vì định hình lại ( ) để bạn có thể cắt bỏ từng phần và giảm catenate ( ¨,/).
Adám

Ngoài ra, bạn có thể chuyển đổi sang cơ thể tradfn và lấy input ( ) và sử dụng commute ( ) để loại bỏ các parens và compose ( ).
Adám

Cảm ơn, nhưng ý nghĩa thứ hai của bạn là gì? Tôi không thể nghĩ ra cách nào để làm điều đó mà không tăng số byte
TwiNight


1
Đó sẽ là một đoạn trừ khi bạn đếm {}hoặc ∇f∇xung quanh chức năng
TwiNight

5

Võng mạc , 57 42 byte

Chuyển đổi thành unary, sau đó tham lam thay thế các bó Is với mệnh giá cao hơn theo thứ tự.

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

Dùng thử trực tuyến

Đã lưu 15 byte nhờ Martin


Điều đó rất thông minh.
Adám

7
Đi ngắn hơn rất nhiều để đi theo con đường khác: tio.run/##K0otycxL/ Khăn
Martin Ender

Bạn không thể lấy đầu vào trong unary bằng cách sử dụng Inhư đơn vị?
Adám

2
@ Adám Xem xét rằng Retina bây giờ có thể dễ dàng xử lý đầu vào số nguyên, tôi nghĩ rằng đó là loại rẻ tiền để làm điều đó.
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

Hãy thử trực tuyến!

Thay vì tạo chuỗi đầu ra từ đầu bằng cách tham lam lấy phần lớn nhất, điều này tạo ra chuỗi từ cuối. Chẳng hạn, số lượng In%5, sau đó là sốV là là n/5%2, và vân vân. Đây là chuyển đổi cơ sở hỗn hợp với tỷ lệ liên tiếp là 5 và 2 xen kẽ.

Đây là một tương đương lặp lại:

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

Hãy thử trực tuyến!

Các Mnhu cầu 's được xử lý riêng vì bất kỳ số trong số họ có thể có mặt như không có chữ số lớn hơn. Vì vậy, sau khi các giá trị địa điểm khác đã được chỉ định, giá trị còn lại được chuyển đổi thànhM 's.

Để so sánh, một chiến lược tham lam (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:])

Hãy thử trực tuyến!

Giá trị chữ số hiện tại dđược chia cho 2 hoặc 5 để tạo ra chữ số tiếp theo. Giá trị d%3cho chúng ta biết cái nào: if d%3==1, chia cho 2; và nếu d%3==2, chia cho 5.


4

Toán học, 81 byte

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

Hoàn toàn sử dụng các giá trị và lấy các chữ số tương ứng dường như dài hơn một byte:

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

1
Nice!:FromRomanNumeral@r
DavidC

4

Excel, 236 193 161 byte

43 byte được lưu nhờ @ BradC

Tại thời điểm này, câu trả lời thực sự hoàn toàn thuộc về @ BradC . 32 byte khác được lưu.

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

Định dạng:

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

Bạn sẽ tiết kiệm một số bằng cách thay thế CONCATENATEbằng &giữa mỗi yếu tố và QUOTIENTvới INT(A/B).
BradC

Thêm 2 khoản tiết kiệm: hóa ra REPTđã cắt bớt số nếu đó không phải là số nguyên , vì vậy bạn có thể lưu thêm 30 byte bằng cách xóa từng byte INT(). Tiết kiệm thêm 2 bằng cách thay thế cả hai 1000bằng 1E3(mặc dù Excel dường như không muốn giữ nguyên như vậy một khi bạn nhấn enter).
BradC

Vâng, đã thấy 1E3hành vi. Trả lời cập nhật.
Wernisch

3

Perl 5 , 66 byte

65 byte mã + -pcờ.

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

Hãy thử trực tuyến!

Không thay đổi số byte, MDCLXVI=~/./gcó thể được thay thế bằng M,D,C,L,X,V,I; và --$|?2:5bởi $|--*3+2.

Dài hơn nhiều ( 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 nhờ Martin Ender

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

Hãy thử trực tuyến!

Giải trình

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

Một tuyên bố ternary mã hóa hoàn toàn cứng sử dụng đệ quy.

Phiên bản đầy đủ / được định dạng:

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>0chỉ là n.
Máy

@CalculatorFeline Không có trong C #, intkhông thể ngầm định chuyển sang a bool.
TheLethalCoder

Thật không may.
Máy

@CalculatorFeline Vâng, đôi khi C # được gõ quá mạnh vì nó tốt.
TheLethalCoder

3

05AB1E , 29 26 25 byte

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

Hãy thử trực tuyến!

Giải trình

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

Đã lưu 6 byte nhờ @Neil để chuyển câu trả lời của @ Jörg Hülsermann

Đã lưu 6 byte nhờ @Shaggy

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

Các trường hợp thử nghiệm:


1
Bạn sẽ có thể di chuyển n%=xbên trong repeatphương thức để lưu một vài byte.
Xù xì

1
FYI một cổng của câu trả lời PHP chỉ là 69 byte:n=>'MDCLXVI'.replace(/./g,(c,i)=>c.repeat(n/a,n%=a,a/=i%2?5:2),a=1e3)
Neil

Cảm ơn @Neil, tôi đã cập nhật bài viết. Xóa mảng mã hóa cứng mà tôi muốn xem lại
Craig Ayre

2

/// , 50 byte

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

Hãy thử trực tuyến!

Đưa đầu vào vào unary và tôi (ab) sử dụng trường chân trang trên TIO cho đầu vào để đầu ra được đi trước bởi một dòng mới.


2

Python 3 , 100 97 96 94 93 91 90 byte

  • đã lưu 4 + 2 byte: sử dụng def ; mảng như tham số mặc định giảm không gian thụt lề; khai báo biến không mong muốn
  • @shooqie lưu 1 tốc a%=ký tốc ký
  • đã lưu 2 byte: sắp xếp lại và niềng răng trong (a//i)đã bị xóa
  • @Wondercricket đã lưu 1 byte: di chuyển mảng từ tham số mặc định sang bên trong hàm đã loại bỏ []với chi phí của một không gian thụt đầu dòng, do đó tiết kiệm được 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

Hãy thử trực tuyến!


1
a%=ilà một byte ngắn hơn :)
shooqie

1
Bạn cũng có thể lưu một byte bằng cách lưu trữ bdưới dạng một biến trong hàm. Điều đó loại bỏ sự cần thiết của dấu ngoặc -b=1000,500,100,50,10,5,1
Wondercricket

2

Khối , 69 74 80 byte

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

Hãy thử trực tuyến!

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

Xem nó chạy

Tôi đã cố gắng nén nó thêm một chút, nhưng vẫn còn một số no-op phiền phức, đặc biệt là ở mặt trên.

  • 52"IVXLCDM"Uđặt các ước và ký tự cần thiết trên ngăn xếp. 5 và 2 sẽ được sử dụng để giảm giá trị div / mod và các ký tự sẽ bị loại bỏ sau khi sử dụng.
  • UIN0/&0\&,/Uu-quay lên mặt trên và bắt đầu một chuyến tham quan dài để lấy đầu vào và đẩy 1000 lên ngăn xếp. Một phân chia ban đầu được thực hiện và chuyển sang phần rcủa đoạn tiếp theo. Đây là một lĩnh vực tôi đang tìm kiếm để tiết kiệm.
  • ,r%ws;rrbắt đầu vòng lặp divmod. chia số nguyên, xoay mod kết quả đi, sau đó sắp xếp lại đỉnh ngăn xếp để giảm đầu vào, ước số hiện tại và kết quả chia.
  • 3tus đưa nhân vật hiện tại lên đầu và trao đổi nó với kết quả chia.
  • !vsoUs(0;Uđây là vòng lặp in trong khi kết quả div lớn hơn 0, trao đổi với đầu ra ký tự, hoán đổi lại, giảm dần, đẩy 0 và thả nó. Trên 0 chuyển hướng trên ngăn xếp pop (loại bỏ kết quả phân chia) và xung quanh khối.
  • \u;pwpsq,!@Urq;uvới một chút chuyển hướng, điều này sẽ loại bỏ nhân vật khỏi ngăn xếp, đưa 5 và 2 lên trên cùng, hoán đổi chúng và đẩy một người xuống. Phần còn lại được sử dụng để giảm ước số. Dừng lại nếu nó giảm xuống 0, nếu không thì đẩy 5 hoặc 2 xuống dưới cùng và nhập lại vòng lặp.

1

Toán học, 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'))

Hãy thử trực tuyến!


1000có thể là 1e3(nếu bạn không bận tâm nó là một cái phao không phải là vấn đề)
CalculatorFeline

@CalculatorFeline nó sẽ biến kết quả thành một floatvà bạn không thể nhân một chuỗi bằng một số 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

Ngắt dòng được thêm vào để chỉ đọc.

Phiên bản này dài hơn rất nhiều (230 ký tự), nhưng cảm thấy "giống SQL" hơn nhiều:

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

Tạo một bảng m với tất cả các ánh xạ giá trị char và sau đó lặp lại thông qua việc tìm giá trị lớn nhất <= số, nối các ký tự khớp.


1

Japt , 34 byte

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

Kiểm tra nó trực tuyến!

"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

Một hàm đệ quy.

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

Làm sao?

Cuộc gọi đệ quy thứ hai f(n-a)thực sự nên được f(n-a,a). Bằng cách bỏ qua tham số thứ 2 aiđược khởi tạo lại (lần lượt là 1000 và 0) mỗi lần một chữ số La Mã mới được thêm vào kết quả cuối cùng. Điều này gây ra đệ quy nhiều hơn mức cần thiết nhưng không làm thay đổi kết quả của hàm và tiết kiệm 2 byte.

Các trường hợp thử nghiệm


1

J , 26 23 byte

3 byte được lưu nhờ Adám.

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

Hãy thử trực tuyến!

Tương tự như câu trả lời APL về cơ bản điều tương tự.

'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

Không phải tôi biết J, nhưng tại sao #.invthay vì #:?
Adám

@ Adám Ah, điểm tốt. Tôi có thói sử dụng #.invthay vì #:, vì cái gì đó như 2 #: 40, trong khi 2 #.inv 41 0 0
Conor O'Brien

Vâng, tôi làm điều tương tự trong APL. Bây giờ giải pháp của bạn thực sự tương đương với giải pháp APL.
Adám

#/; ~; $; &; #:. Sự khác biệt duy nhất là bạn sử dụng vô hạn _trong khi bạn có thể sử dụng 0như câu trả lời APL.
Adám

@ Adám Huh, tuyệt.
Conor O'Brien

1

Mẻ, 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

Đưa đầu vào vào 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)

Đầu ra:

mmdcccxxxxviiii

Xin lưu ý kích thước thực tế của dòng là 460byte, vì nó bao gồm số đầu vào (2849).

Ung dung:

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     
)

Cách thức hoạt động: Tôi tính toán tôi cần bao nhiêu chữ cái, bằng cách tính toán nhiều nhất tôi có thể nhận được với giá trị cao hơn (vô cùng cho M), và sau đó thực hiện phép chia số nguyên giữa giá trị của chữ cái hiện tại và kết quả của chữ cái đó.

Ví dụ 2348, Ctôi cần bao nhiêu s? trunc((2348-mod(2348,500))/100)= 3.

Sau đó, tôi listaggviết thư đó 3 lần (khai thác CONNECT BYđể tạo 3 hàng tôi cần). Cuối cùng tôilistagg mọi thứ cùng nhau.

Hơi cồng kềnh, nhưng hầu hết là select from duals trong bảng chuyển đổi và tôi thực sự không thể làm gì nhiều về điều đó ...


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

Hãy thử trực tuyến!

Đã lưu một byte nhờ @TheLethalCoder


1
Bạn có thể khai báo vitrong vòng lặp đầu tiên để lưu một byte không?
TheLethalCoder

@TheLethalCoder Vâng, chắc chắn nhất. Lúc đầu tôi đã có một ý tưởng hoàn toàn khác rằng điều này không vượt qua đánh giá nội bộ của tôi: p
Olivier Grégoire

0

Than , 61 50 46 byte

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

Hãy thử trực tuyến!

Giải trình:

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 được lưu nhờ Neil, trong khi tôi vẫn đang cố gắng tìm ra cách tiến hành phần thứ hai trong bình luận của anh ấy.

1
Nνngắn hơn một byte so với ANν, ngắn hơn ¬‹một byte so với trừ 1 và nếu bạn sử dụng ÷(IntDivide) thay vì (Chia) thì bạn có thể sử dụng φlàm điều kiện vòng lặp bên ngoài. Tuy nhiên, tôi nghĩ rằng bạn có thể giảm xuống còn 40 byte bằng cách lặp lại MDCLXVItrực tiếp.
Neil

@Neil tất nhiên, ngớ ngẩn với tôi, cố gắng hiểu tại sao không có toán tử "lớn hơn hoặc bằng" khi tôi có thể sử dụng "không ít hơn". Thủ thuật rất thông minh sử dụng phép chia số nguyên. Bây giờ hãy cho tôi một chút thời gian để suy nghĩ về phần cuối cùng của bình luận của bạn ...
Charlie

I improved my string loop idea and posted it as a seprate answer along with a port of @xnor's Python answer, which turned out to be the same length.
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);}

Thuật toán tương tự như trước đây, chỉ sử dụng mảng c đơn giản thay vì std :: map, lấy cảm hứng một phần từ câu trả lời của @ xnor và sử dụng chuỗi để lưu trữ các chữ cái.



0

Lisp thông thường, 113 byte

Đây là một hàm ẩn danh, trả về kết quả dưới dạng chuỗi.

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

Ungolfed, với các tên và bình luận biến mô tả:

(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 đã tích hợp định dạng số La Mã. Đáng buồn thay, nó không hoạt động đối với các số lớn hơn 3999.


0

Than , 34 byte

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

Ban đầu dựa trên câu trả lời của @ CarlosAlego. Một cổng của giải pháp Python của @ xnor cũng là 34 byte:

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

Chỉnh sửa: Một cổng của giải pháp Python khác của @ xnor hóa ra là 33 byte!

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Lưu ý rằng tôi đã sử dụng ⁺׳﹪φ³±¹thay ⁻׳﹪φ³¦¹vì vì deverbosifier hiện không thể chèn dải phân cách.


1
Huh, that looks more Greek than Roman.
Adám
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.