Khi ở Rome, tính như người La Mã làm gì?


20

Lý lịch

Thử thách này được lấy cảm hứng từ trang web này , đã xuất bản sơ đồ sau:

nhập mô tả hình ảnh ở đây

Biểu đồ này cho chúng ta thấy biểu thức số La Mã dài nhất dưới 250 là biểu thức 188, yêu cầu 9 chữ số để thể hiện.

Thử thách

Các biểu tượng chuẩn được sử dụng để diễn tả Chữ số La Mã nhất là sau: { I, V, X, L, C, D, M}, trong đó giá trị số của nhân vật là M= 1000, D= 500, C= 100, L= 50, X= 10, V= 5, I= 1.

Trong thử thách này, mục tiêu của bạn là, được đưa ra một số nguyên dương n , tính toán số lượng biểu diễn Số La Mã hợp lệ có thể được tạo thông qua n nối các ký hiệu chuẩn.

Sau đó, chương trình của bạn phải xuất kết quả của tính toán này!

Đầu vào : Một số nguyên dương n .

Đầu ra : Số biểu thức chữ số La Mã hợp lệ có độ dài n .

Quy tắc biểu thức số La Mã

Chữ số La Mã ban đầu chỉ có ghép nối "phụ gia", nghĩa là các chữ số luôn được viết theo thứ tự giảm dần và tổng các giá trị của tất cả các chữ số là giá trị của số.

Sau này, ghép cặp trừ, việc sử dụng đặt một chữ số nhỏ hơn trước một số lớn hơn để trừ số nhỏ hơn từ số lớn hơn, trở nên phổ biến để rút ngắn các biểu thức Số La Mã. Các cặp trừ có thể được xâu chuỗi, như trong biểu thức không hợp lệ sau : IXL.

Sau đây là các quy tắc hiện đại cho ghép cặp cộng và trừ.

  1. Chỉ có một I, X và C có thể được sử dụng làm chữ số hàng đầu trong một phần của cặp trừ.
  2. Tôi chỉ có thể được đặt trước V hoặc X trong một cặp trừ.
  3. X chỉ có thể được đặt trước L hoặc C trong một cặp trừ.
  4. C chỉ có thể được đặt trước D hoặc M trong một cặp trừ.
  5. Khác với các cặp trừ, các chữ số phải theo thứ tự giảm dần (có nghĩa là nếu bạn bỏ số đầu của mỗi cặp trừ, thì các chữ số sẽ theo thứ tự giảm dần).
  6. M, C và X không thể bằng hoặc vượt quá các mệnh giá nhỏ hơn.
  7. Mỗi D, L và V chỉ có thể xuất hiện một lần.
  8. Chỉ M có thể được lặp lại 4 lần trở lên.

Ghi chú thêm

  • Chúng tôi sẽ không sử dụng ký hiệu thanh ; thay vào đó, chúng tôi chỉ đơn giản sẽ thêm nhiều M s để thể hiện bất kỳ số nào.

  • Đây là những quy tắc duy nhất mà chúng tôi sẽ tuân theo cho các chữ số La Mã của chúng tôi. Điều đó có nghĩa là các biểu thức lẻ, chẳng hạn như IVI, cũng sẽ được coi là hợp lệ trong hệ thống của chúng tôi.

  • Cũng nên nhớ rằng chúng ta không đếm số lượng các biểu thức có độ dài n , vì một số số có nhiều biểu thức. Thay vào đó, chúng tôi chỉ đếm số lượng biểu thức hợp lệ.

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

17

231

3105

Tôi đã kiểm tra ở trên bằng tay, vì vậy hãy đảm bảo kiểm tra kỹ các trường hợp kiểm tra và thêm nhiều hơn nếu bạn có thể!

Tiêu chí chiến thắng

Đây là một thử thách , vì vậy hãy vui vẻ! Tôi sẽ chỉ chấp nhận các giải pháp có thể xử lý ít nhất đầu vào từ 1 đến 9. Bất kỳ phần thưởng nào nữa là tiền thưởng!

Chỉnh sửa

Theo yêu cầu của người bình luận, tìm bên dưới hoặc tại liên kết pastebin này, 105 combo tôi đã tính cho n = 3

III IVI IXI IXV IXX VII XII XIV XIX XVI XXI XXV XXX XLI XLV XLX XCI XCV XCX XCL XCC LII LIV LIX LVI LXI LXV LXX CII CIV CIX CVI CXI CXV CXX CXL CMI CMV CMX CML CMC CMD CMM DII DIV DIX DVI DXI DXV DXX DXL DXC DLI DLV DLX DCI DCV DCX DCL DCC MII MIV MIX MVI MXI MXV MXX MXL MXC MLI MLV MLX MCI MMX MML MMC MMD MMM

Chỉnh sửa 2:

Sử dụng các phi golfed sau đang , như biếu không của Jonathan Allan để kiểm tra kết quả của bạn.

Chỉnh sửa 3:

Tôi xin lỗi vì tất cả các lỗi trong thử thách này. Tôi sẽ đảm bảo thực hiện công việc tốt hơn vào lần tới!


Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
Mego

Câu trả lời:


3

Võng mạc , 111 byte

~(`.+
*$(CM)CDXCXCXCXLIXIXIXIVII
.(.)
.+¶$$&$¶$$&$1$¶$$&$&¶L`.{0,$+}\b¶D`¶
¶$
¶.+¶$$&$¶$$&I¶L`[A-Z]{$+}\b¶D`¶.+

Hãy thử trực tuyến! Đây là một bản viết lại hoàn chỉnh khi tôi hiểu sai quy tắc 1. có nghĩa là bạn chỉ có thể sử dụng một phép trừ I, XC. Giải thích: Phần đầu tiên của tập lệnh mở rộng đầu vào thành một chuỗi các CMcặp theo sau là các cặp trừ khác có thể có. Mỗi cặp là tùy chọn và ký tự đầu tiên của mỗi cặp cũng là tùy chọn trong cặp. Giai đoạn thứ ba sau đó mở rộng danh sách các cặp thành một danh sách các lệnh Retina lấy đầu vào và tạo ba bản sao với tùy chọn thứ hai hoặc cả hai ký tự từ cặp, sau đó cắt và sao chép kết quả. Giai đoạn cuối cùng sau đó nối thêm mã để thực hiện các tác vụ cuối cùng: đầu tiên là mở rộng đầu vào để có thể thêm một kết thúcI, sau đó để lọc ra kết quả có độ dài sai, sau đó để nhân đôi kết quả và cuối cùng là tính kết quả. Kịch bản Retina kết quả sau đó được đánh giá.

Lưu ý: Về lý thuyết, 15 byte có thể được lưu từ cuối dòng thứ 4 nhưng điều này làm cho tập lệnh quá chậm để thể hiện trên TIO ngay cả đối với n=1.


@Jonathan ALLan Ah, sau đó bạn bao gồm nhiều cặp trừ với cùng một chữ số hàng đầu, đó là sai.
Neil

2
@Jonathan ALLan Viết lại mới, trùng hợp cho cùng một số byte chính xác!
Neil

5

Python 2 , 177 168 162 byte

import re,itertools as q
f=lambda n:sum(None!=re.match("^M*(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$",(''.join(m)))for m in q.product('MDCLXVI',repeat=n))

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

Tôi khá mới, giúp tôi chơi gôn này! Điều này kiểm tra các chữ số La Mã thực tế, regex cần được điều chỉnh để giải thích cho các trường hợp kỳ lạ nhưIVI

-9 byte nhờ @Dead Possum!

-6 byte nhờ @ovs


Vâng tôi nghĩ rằng trường hợp n = 3 có thể sai trong ví dụ. Ban đầu tôi nhận được 93 với^M*(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$
Easton Bornemeier


1
@Jonathan ALLan Tôi đã dành khoảng hai ngày để hỏi về stackexchange Math để đảm bảo các quy tắc này có ý nghĩa. Đoán tôi đã không làm đủ :(
Don Nghìn

1
@RushabhMehta Đây là một thử thách được định dạng rất tốt và thú vị để lập trình, đừng cảm thấy tồi tệ về một sắc thái không may trong nitty-gritty của định nghĩa số La Mã. Đó là thách thức của bạn, chỉ định nó khi bạn thấy phù hợp. theo nghĩa khác, nó hoàn toàn khả thi
Easton Bornemeier

1
Điều này dường như không đưa ra câu trả lời đúng cho 3. 93thay vì105
Jo King

3

JavaScript (ES7), 133 byte

Chỉnh sửa : Đã sửa lỗi để khớp với kết quả được trả về bởi mã của Jonathan Allan , được đưa ra dưới dạng triển khai tham chiếu của OP.


n=>[...Array(m=k=7**n)].reduce(s=>s+/^1*5?4{0,3}3?2{0,3}6?0{0,3}$/.test((--k+m).toString(7).replace(/0[62]|2[34]|4[51]/g,s=>s[1])),0)

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

Làm sao?

N1

[...Array(m = k = 7 ** n)].reduce(s => … (--k + m).toString(7) …, 0)

Từ giờ trở đi, mỗi chữ số sẽ được hiểu là ký hiệu chữ số La Mã:

0I,1M,2X,3L,4C,5D,6V

2) Chúng tôi thay thế tất cả các cặp trừ hợp lệ của biểu mẫu ABbằng B:

.replace(/0[62]|2[34]|4[51]/g, s => s[1]))  // in the code
.replace(/I[VX]|X[LC]|C[DM]/g, s => s[1]))  // with Roman symbols

Ví dụ:

  • XLIXIV trở thành LXV
  • XIIVtrở thành XIV, để lại một Iđiều đó sẽ làm cho bài kiểm tra tiếp theo thất bại
  • ICvẫn không thay đổi, mà còn để lại một không hợp lệ Itại chỗ

3) Chúng tôi kiểm tra các ký hiệu còn lại theo đúng thứ tự và không xuất hiện nhiều lần hơn mức cho phép:

/^1*5?4{0,3}3?2{0,3}6?0{0,3}$/.test(…)  // in the code
/^M*D?C{0,3}L?X{0,3}V?I{0,3}$/.test(…)  // with Roman symbols

Chúa ơi, tôi không mong đợi điều này sẽ được thực hiện dưới 200 byte bằng các ngôn ngữ không bí truyền! Tâm giải thích làm thế nào điều này hoạt động?
Don Ngàn

Tuy nhiên, tôi đã nhận thấy rằng điều này không hoạt động cho * n *> 4 trên TIO, điều này hơi đáng tiếc.
Don Ngàn

@RushabhMehta Tôi đã thêm một phiên bản không đệ quy để kiểm tra các giá trị cao hơn. Tôi sẽ thêm một lời giải thích khi tôi chơi golf này.
Arnauld

0

C, 150 123 byte

Tôi đã không đọc mô tả đủ chặt chẽ, vì vậy điều này tạo ra số chữ số La Mã tiêu chuẩn (trong đó các biểu thức như IVIkhông được tính). Vì tôi đã bỏ ra một số nỗ lực cho nó, tôi nghĩ dù sao tôi cũng sẽ chia sẻ.

#define F(X) for(X=10;X--;)
x[]={0,1,2,3,2,1,2,3,4,2};f(i,o,a,b,c){for(i++;i--;)F(a)F(b)F(c)o+=i==x[a]+x[b]+x[c];return o;}

Bản gốc (150 byte):

#define F(X) for(X=10;X--;)
i,o,a,b,c,x[]={0,1,2,3,2,1,2,3,4,2};main(){scanf("%i",&i);for(i++;i--;)F(a)F(b)F(c)o+=i==x[a]+x[b]+x[c];printf("%i\n",o);}

1
Bạn chỉ được phép gửi bài nộp hợp lệ.
Okx

@CurtisBechtel Bạn có thể giữ giải pháp ở đây tôi cho rằng, nhưng tôi sẽ cố gắng sửa đổi nó để đáp ứng các quy tắc của thử thách.
Don Ngàn

1
Tôi nghĩ bạn có thể xóa khoảng cách giữa F(X)for(X=10;X--;)
Zacharý
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.