Chức năng chuyển đổi số La Mã


13

Tạo hàm ngắn nhất để chuyển đổi một chuỗi các chữ số La Mã thành một số nguyên.

Các quy tắc cho mỗi chữ cái có thể được tìm thấy tại trang Wikipedia . Chữ cái trên 1.000 sẽ có dấu ngoặc đơn đặt xung quanh chúng để báo hiệu giá trị cao hơn của chúng.

Yêu cầu:

  • Phải chuyển đổi chữ số La Mã từ 1 đến 500.000
  • Phải hoàn thành trong vòng chưa đầy một phút
  • Không sử dụng các hàm dựng sẵn có thể mang lại lợi thế (Ví dụ: Hàm chuyển đổi số La Mã thành số nguyên)
  • Là một chức năng

Hàm không cần hỗ trợ phân số. Bất kỳ đầu vào không hợp lệ sẽ trả về số 0.

Chức năng ngắn nhất sẽ thắng. Trong trường hợp hòa, người nào có nhiều phiếu nhất sẽ thắng.

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

Đầu vào

III

Đầu ra

3


Đầu vào

IIII

Đầu ra

0


Đầu vào

XVI

Đầu ra

16


Đầu vào

(C)(D)(L)MMI

Đầu ra

452001

2
Trừ khi tôi thiếu một cái gì đó, (C)(D)(L)MMIsẽ là 452.001. Làm thế nào bạn có được giá trị của bạn? Ngoài ra, điều này có cần hỗ trợ các hình thức "không phù hợp" (ví dụ ICthay vì XCIX) không?
Anon.

Không đúng với tôi có nghĩa là bất hợp pháp và do đó sẽ trả về 0.
Martin York

@Anon: Số là một loại nhầm từ khi tôi thay đổi trường hợp thử nghiệm thứ ba ban đầu. Nó không cần phải hỗ trợ các hình thức không phù hợp, vì nó sẽ được coi là đầu vào không hợp lệ.
Kevin Brown

1
Thực hành tiêu chuẩn (và thông số kỹ thuật trùng lặp của câu hỏi này) dành cho đầu vào không hợp lệ là hành vi không xác định. Vì câu hỏi này đã bốn tuổi và chỉ có một câu trả lời, chúng ta có nên thay đổi yêu cầu không?
lirtosiast

1
@KevinBrown Tôi không thấy nguồn hoặc giải thích cho các chữ cái được ngoặc đơn. Tôi nghĩ bạn nên thay đổi thông số để khớp với codegolf.stackexchange.com/q/16254/43319 và sau đó các câu trả lời từ đó có thể được di chuyển ở đây.
Adám

Câu trả lời:


6

C ++: 914 855 ký tự

#include<map>
#include<string>
#include<iostream>
#include<sstream>
#define I istream
#define T(C) if(C)throw int(1);
#define X(c,v,f,m) D[c]=v;P[c]=D[f];M[c]=m;
#define S second
using namespace std;typedef map<char,int>R;R D,P,M;struct U{U():t(0),l(0),a(0){}int t,l,a;operator int(){return t+l;}I&d(I&s){char c,b;s>>c;if(c=='('){s>>c>>b;T(b!=')')c+=32;}if(s){R::iterator f=D.find(c);T(f==D.end())if(P[c]==l){l=f->S-l;a=0;}else{T(l&&(f->S>l))a=l==f->S?a+1:1;T(a>M[c])t+=l;l=f->S;}}return s;}};I&operator>>(I&s,U&d){return d.d(s);}int main(){D[' ']=-1;X(73,1,32,3)X(86,5,73,1)X(88,10,73,3)X(76,50,88,1)X(67,100,88,3)X(68,500,67,1)X(77,1000,67,3)X(118,5000,77,1)X(120,10000,77,3)X(108,50000,120,1)X(99,100000,120,3)X(100,500000,99,1)X(109,1000000,99,3)string w;while(cin>>w){try{stringstream s(w);U c;while(s>>c);cout<<c<<"\n";}catch(int x){cout<<"0\n";}}}

Nó có thể được nén thêm.

> ./a.exe
III
3
IIII
0
XVI
16
(C)(D)(L)MMI
452001

Định dạng đẹp hơn một chút: 1582 char

#include<map>
#include<string>
#include<iostream>
#include<sstream>
#define I istream
#define T(C) if(C)throw int(1);
#define X(c,v,f,m) D[c]=v;P[c]=D[f];M[c]=m;
#define S second
using namespace std;

typedef map<char,int>      R;

R     D,P,M;

struct U
{
    U(): t(0), l(0), a(0) {}

    int  t,l,a;

    operator int()
    {
        return t + l;
    }
    I& d(I& s)
    {
        char c,b;
        s >> c;
        if (c == '(')
        {
            s >> c >> b;
            T(b != ')')
            c = tolower(c);
        }
        if (s)
        {
            R::iterator f = D.find(c);
            T(f == D.end())

            if (P[c] == l)
            {
                l = f->S - l;
                a = 0;
            }
            else
            {
                T(l&&(f->S > l))
                a=l==f->S?a+1:1;
                T(a>M[c])
                t   += l;
                l     = f->S;
            }
        }

        return s;
    }

};

I& operator>>(I& s,U& d)
{
    return d.d(s);
}

int main()
{
    D[' ']=-1;
    X(73,1,32,3)
    X(86,5,73,1)
    X(88,10,73,3)
    X(76,50,88,1)
    X(67,100,88,3)
    X(68,500,67,1)
    X(77,1000,67,3)
    X(118,5000,77,1)
    X(120,10000,77,3)
    X(108,50000,120,1)
    X(99,100000,120,3)
    X(100,500000,99,1)
    X(109,1000000,99,3)

    string w;
    while(cin >> w)
    {
        try
        {
            stringstream s(w);
            U    c;
            while(s >> c);
            cout << c << "\n";
        }
        catch(int x)
        {
            cout << "0\n";
        }
    }
}

Tôi không nghĩ bạn cần một khoảng trống giữa các hàm macro và định nghĩa của chúng.
Zacharý

4

Javascript, 317 ký tự

function f(s){for(r=/\(?(.\)?)/g,t=e=0;a=r.exec(s);l=a[0].length,d='IXCMVLD'.indexOf(a[1][0]),e=e||d<0||l==2||d*4+l==3,t+='+'+(d>3?5:1)*Math.pow(10,d%4+3*(l>1)));t=t&&t.replace(/1(0*).(10|5)\1(?!0)/g,'$2$1-1$1');return e||/[^0](0*)\+(10|5)\1/.test(t)||/(\+10*)\1{3}(?!-)/.test(t)||/-(10*)\+\1(?!-)/.test(t)?0:eval(t)}

Giải thích:

function f(s){
      // iterate over every character grabbing parens along the way
  for(r=/\(?(.\)?)/g,t=e=0;a=r.exec(s);    
        // get a numerical value for each numeral and join together in a string
    l=a[0].length,
    d='IXCMVLD'.indexOf(a[1][0]),
    e=e||d<0||l==2||d*4+l==3,    // find invalid characters, and parens
    t+='+'+(d>3?5:1)*Math.pow(10,d%4+3*(l>1))
  );
      // reorder and subtract to fix IV, IX and the like
  t=t&&t.replace(/1(0*).(10|5)\1(?!0)/g,'$2$1-1$1');
  return e||
    /[^0](0*)\+(10|5)\1/.test(t)|| // find VV,IIV,IC,...
    /(\+10*)\1{3}(?!-)/.test(t)||  // find IIII,... but not XXXIX
    /-(10*)\+\1(?!-)/.test(t)      // find IVI,... but not XCIX
      ?0:eval(t)
}

Nếu không phát hiện lỗi thì chỉ có 180 ký tự

function g(s){for(r=/\(?(.\)?)/g,t=0;a=r.exec(s);d='IXCMVLD'.indexOf(a[1][0]),t+='+'+(d>3?5:1)+'0'.repeat(d%4+3*(a[1].length>1)));return eval(t.replace(/(1(0*).(10|5)\2)/g,'-$1'))}

Điều này hoạt động theo cùng một cách, nhưng ở đây là định dạng tốt hơn:

function g(s){
  for(r=/\(?(.\)?)/g,t=0;a=r.exec(s);
    d='IXCMVLD'.indexOf(a[1][0]),
    t+='+'+(d>3?5:1)+'0'.repeat(d%4+3*(a[1].length>1))
  );
  return eval(t.replace(/(1(0*).(10|5)\2)/g,'-$1'))
}
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.