Phân đoạn số La Mã


10

Viết chương trình hoặc hàm chấp nhận một số nguyên trong phạm vi 1..3999 làm đầu vào và trả về số lượng phân đoạn dòng cần thiết để thể hiện số nguyên đó bằng các chữ số La Mã tiêu chuẩn (vì vậy bạn sẽ sử dụng XL nhưng không sử dụng VM). Ví dụ:

   1 -> 1
   4 -> 3
   5 -> 2
   9 -> 3
  10 -> 2
  40 -> 4
  50 -> 2
  90 -> 3
 100 -> 1
 400 -> 3
 500 -> 2
 900 -> 5
1000 -> 4

Nội dung chuyển đổi số La Mã được cho phép, nhưng bạn có thể giải quyết vấn đề mà không cần đến chúng bằng cách trừ đi số lượng lớn nhất còn lại từ danh sách trên. Ví dụ: 1234 = 4 + 1 + 1 + 2 + 2 + 2 + 3 = 15.

Đây là , vì vậy chương trình ngắn nhất sẽ thắng.


Tại sao 10 phân đoạn hai dòng thay vì bốn? Khi viết X, thông thường bạn chỉ viết hai dòng, nhưng không phải giao điểm của các dòng tạo thành bốn phân đoạn?
Alex A.

@AlexA. Định nghĩa của phân đoạn dòng thường là một cái gì đó như: "Tập hợp các điểm theo con đường ngắn nhất giữa hai điểm". Dường như không có bất kỳ lý do nào để cắt X dựa trên điều này, bạn chỉ cần hai bộ điểm cuối để xác định nó. (Giả sử người La Mã chủ yếu viết về hình học euclid, tôi đoán vậy)
FryAmTheEggman 17/03/2016

@FryAmTheEggman Hừ được rồi. Tốt để biết, cảm ơn.
Alex A.

Câu trả lời:


2

Pyth, 92 76 70 byte

KsMc."/9hæ²z³Þ§ªW×Oû[Tnè,O¤"\/WQ=Q-Q=Nef!>TQ%2K aY@KhxKN;sY

Hãy thử nó ở đây!

Cảm ơn @FryAmTheEggman về một số đề xuất đóng gói chuỗi đã tiết kiệm cho tôi một số byte!

Tôi vẫn đang tự hỏi nếu có một cách toán học để mã hóa danh sách này. Sẽ cố gắng để tìm ra một cái gì đó.

Giải trình

Điều này sử dụng thuật toán nhất định. Kchứa danh sách đã cho với các số và số lượng các phân đoạn dòng xen kẽ. Danh sách này được xây dựng bằng cách tách một chuỗi được đóng gói, được giải mã 0/0/1/1/4/3/5/2/9/3/10/2/40/4/50/2/90/3/100/1/400/3/500/2/900/5/1000/4, bật /và ánh xạ từng phần tử thành một số nguyên.

KsMc. "..." \ / WQ = QQ = Nef!> TQ% 2K aY @ KhxKN; sY # Q = đầu vào

   c. "..." \ / # tách chuỗi trên /
KsM # ánh xạ mọi số vào int và gán cho K
            WQ # trong khi Q! = 0
                     f% 2K # chỉ lấy mỗi phần tử thứ 2 của K và bộ lọc với T
                      !> TQ # T <= Q
                  = Ne # Lấy phần tử cuối cùng của nó và gán nó cho N
              = QQ # Q = Q - N
                                   chỉ số xKN # của lần xuất hiện đầu tiên của N trong K
                                  h # tăng chỉ số đó vì chúng tôi muốn các phân đoạn dòng
                              aA @ K # lấy đoạn đường từ chỉ mục đó và nối nó vào Y
                                      ; sY # kết thúc vòng lặp và in tổng của tất cả các phân đoạn dòng trong Y

3

C, 148 129 ký tự

d,x,n[]={1000,900,500,400,100,90,50,40,10,9,5,4,1,4,5,2,3,1,3,2,4,2,3,2,3,1};f(c){while(d+=(c/n[x])*n[x+13],c%=n[x++]);return d;}

Mã golf đầu tiên của tôi: ^). Vì các câu hỏi trạng thái tôi có thể sử dụng một hàm, tôi đã thay đổi chính thành một hàm để cắt bớt một số ký tự (quan trọng nhất: truyền c làm tham số thay vì scanf)

giải nén

d,x,n[]={1000,900,500,400,100,90,50,40,10,9,5,4,1,4,5,2,3,1,3,2,4,2,3,2,3,1};
f(c){
  while(d+=(c/n[x])*n[x+13],
        c%=n[x++]);
  return d;
}

2

Toán học, 80 72 byte

Tr[Characters[#~IntegerString~"Roman"]/.{"I"|"C"->1,"M"->4,_String->2}]&

Hàm ẩn danh chỉ chuyển đổi số thành chữ số La Mã, thay thế từng ký tự bằng số phân đoạn của nó và lấy tổng số.


2

Võng mạc, 128 byte

. +
$ *
1 {1000}
t '
1 {900}
td
1 {500}
d
1 {400}
t
1 {100}
'
1 {90}
t
1 {50}
d
1 {40}
t '
1 {10}
d
1 {9}
t
1 {5}
d
1 {4}
t
1
'
t
d '
d
''
'+
$ .0

Thay thế đơn giản cho đến khi không còn gì để thay thế. Sau đó, dấu nháy đơn được tính và đó là số phân đoạn dòng của chúng tôi.

Nếu đầu vào và đầu ra trong unary được cho phép, đó là 115 byte (mặc dù ai sẽ muốn gõ 1234 cái?).

Hãy thử trực tuyến!
Hãy thử trực tuyến! (IO đơn phương)


2

Python 3, 95 byte

def f(a,b=0):
 for e in'᝴ᔝ஺ॣəȟĮô>9 ':e=ord(e);d=e//6;b+=a//d*(e%6);a%=d
 return b

Chuỗi Unicode bao gồm các điểm mã:

6004 5405 3002 2403 601 543 302 244 62 57 32 27 7

Nếu bạn biến chuỗi đó thành một byte theo nghĩa đen, bạn có thể bỏ quae=ord(e);
xsot 20/03/2016

Tôi không nghĩ rằng nó hoạt động trong trường hợp của tôi. Tôi cần một chuỗi Unicode :( tức là tôi đang lặp qua các điểm mã trong chuỗi đó, không phải qua các byte.
Lynn

1
Ồ, tôi hiểu rồi. Bạn có nhớ cung cấp một kết xuất hex của chuỗi? Nó không được hiển thị đúng trên điện thoại của tôi.
xsot

1

Java, 152 byte

Bởi vì, bạn biết đấy, Java.

n->{int c=0;int[]r={999,4,899,5,499,2,399,3,99,1,89,3,49,2,39,4,9,2,8,3,4,2,3,3,0,1};for(int i=0;i<26;i+=2)while(n>r[i]){n-=r[i]+1;c+=r[i+1];}return c;}

Thực hiện nghĩa đen đơn giản của các thuật toán nhất định. Mảng đóng gói thông tin biến đổi: các chỉ mục chẵn ít hơn một chữ số La Mã và các chỉ số lẻ là số đếm cho chữ số đó.

Đây là một lambda nhận và trả về một int/ Integer. Điều này bao gồm IntUnaryOperatorhoặc UnaryOperator<Integer>.


1

JavaScript (ES6), 79 byte

n=>"0123323453"[[,a,b,c,d]=1e4+n+'',d]-(-"0246424683"[c]-"0123323455"[b])+a*4

Các chuỗi đại diện cho số lượng phân đoạn dòng cho các đơn vị, hàng chục và hàng trăm chữ số. (Hàng ngàn chỉ đơn giản là bốn lần hàng ngàn chữ số.) Phương pháp này dường như ngắn hơn các tùy chọn khác như thuật toán được đề xuất trong câu hỏi.

Chỉnh sửa: Đã lưu 2 byte nhờ @ user81655.


Đây là một thuật toán tuyệt vời. Sắp xếp lại các phôi cũng có thể tiết kiệm 2 byte:n=>"0123323453"[[,a,b,c,d]=1e4+n+'',d]-(-"0246424683"[c]-"0123323455"[b])+a*4
user81655

@ user81655 Ồ, thật tuyệt: chỉ cần thay đổi +s thành -s cho phép tôi loại bỏ hàng đầu +, nhưng sau đó việc nhóm lại lưu một byte khác.
Neil
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.