Romen rakamı dönüştürücü işlevi


14

Romen rakamları dizesini tamsayıya dönüştürmek için en kısa fonksiyonu oluşturun .

Her harf için kurallar Wikipedia sayfasında bulunabilir . 1000'in üzerindeki harfler, daha yüksek değerlerini belirtmek için etraflarına parantez yerleştirilecektir.

Gereksinimler:

  • Romen rakamları 1'den 500.000'e dönüştürülmelidir
  • Bir dakikadan kısa sürede tamamlanmalıdır
  • Avantaj sağlayabilecek yerleşik işlevleri kullanmaz (Örn: Romen rakamlarını tamsayılara dönüştüren bir işlev)
  • Bir işlevdir

İşlevin kesirleri desteklemesi gerekmez. Geçersiz girişler 0 sayısını döndürmelidir.

En kısa fonksiyon kazanır. Beraberlik durumunda en çok oyu alan kazanır.

Test Durumları

Giriş

III

Çıktı

3


Giriş

IIII

Çıktı

0


Giriş

XVI

Çıktı

16


Giriş

(C)(D)(L)MMI

Çıktı

452001

2
Bir şey eksik olmadıkça (C)(D)(L)MMI452.001 olur. Değerini nasıl aldın? Ayrıca, bunun "uygunsuz" formları (ör. ICYerine XCIX) desteklemesi mi gerekiyor?
Anon.

Bana uygun olmayan, yasadışı anlamına gelir ve bu nedenle 0'a dönmelidir.
Martin York

@Anon: Sayı, orijinal üçüncü test senaryosunu değiştirdiğimden gelen bir yanlış yazıydı. Geçersiz girdi olarak kabul edileceğinden, uygunsuz formları desteklemesi gerekmez.
Kevin Brown

1
Standart uygulama (ve bu sorunun kopyasının spesifikasyonu) geçersiz girdinin tanımlanmamış davranış olması içindir. Bu soru dört yaşında olduğu ve sadece bir cevabı olduğu için gereksinimleri değiştirmeli miyiz?
lirtosiast

1
@KevinBrown Parantez içindeki harfler için kaynak veya açıklama görmüyorum. Bence codegolf.stackexchange.com/q/16254/43319 ile eşleşecek şekilde özellikleri değiştirmelisiniz ve o zaman cevaplar buradan geçirilebilir.
ADAM

Yanıtlar:


6

C ++: 914855 karakter

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

Daha fazla sıkıştırılabilir.

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

Biraz daha hoş format: 1582 karakter

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

Makro fonksiyonlar ve tanımları arasında boşluk olması gerektiğini düşünmüyorum.
Zacharý

4

Javascript, 317 karakter

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

Açıklama:

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

Hata tespiti olmadan sadece 180 karakterdir

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

Bu aynı şekilde çalışır, ancak işte daha iyi biçimlendirme:

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'))
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.