İngilizce sayısal hesap makinesi


16

Meydan okuma

Girdiyi sözel formda alan (bir denklem konuşabileceği gibi) ve aynı zamanda sözlü formda (bir numara konuşabileceği gibi) çıktı alan bir hesap makinesi yazın.

kurallar

Hesap makinesi şunları yapabilmelidir:

  • toplama, çıkarma, çarpma ve bölme
  • negatif bir milyon ile bir milyon arasındaki işlenenleri ele almak
  • negatif bir milyar ile bir milyar arasında çıktıları ele almak
  • ondalık basamakları girdisinde tutabilir ve çıktısına doğru şekilde yerleştirebilir
  • ondalık çıktıyı yüzlerce yere taşıyın, gerektiğinde yuvarlayın

Kesirli sonuçlar veren tüm işlemler en yakın yüzüncü yere yuvarlanmalıdır (çıktı biçimlendirmesiyle aynı).

Giriş yanlış biçimlendirildiği veya 0'a bölündüğü için programın başarısız olmasına neden olduğunda "E" çıkışı (hata için) ile rapor edin; temelde, program kötü girdiye çökmemelidir, çünkü bu berbat bir hesap makinesi olacaktır.

Hesap makinesine izin verilir , ancak gerekli değildir işlenenler veya çıktılar sınırlarından çıktığında hataları raporlaması . Bu sorunu basitleştirmek içindir, ancak benimle aynı fikirde değilseniz, hataları bildirmeden daha büyük işlenenleri ve çıktıları doğru şekilde işleyebilen bir hesap makinesi yapmaktan çekinmeyin.

Bir işlemin işleneninin işlenenler için tanımlanan sınırları aşması durumunda "E" çıktısı alın.

Çıktının çıktılar için tanımlanan sınırları aşması durumunda "E" çıktısı

İngiliz ve Amerikan İngilizcesi seçimi gibi programın büyük / küçük harfe duyarlılığı ve boşlukları golfçüye bırakması. 1

Yukarıda açıklanan işlevselliği zaten uygulamış olan bir dil veya kitaplık kullanarak hesap makinesinin uygulanmasını atlayan programlar zafer için uygun olmayacaktır.

kazanan

En az karakter içeren program kazanır.

Örnekler

Giriş: iki artı iki
Çıkış: dört

Girdi: yirmi bir nokta beş eksi bir nokta beş
Çıktı: yirmi

Giriş: bir eksi iki
Çıkış: negatif bir

Girdi: beş kez beş
Çıktı: yirmi beş

Girdi: yirmi beş bölü beş
Çıktı: beş

Girdi: iki artı iki eksi beş kez beş bölme negatif sıfır noktası beş
Çıktı: on

Girdi bir milyon kez bin
Çıktı: bir milyar

Girdi: bir milyon kez bin artı bir
Çıktı: E

Girdi: iki milyon artı bir milyon
Çıktı: E

Girdi: bir milyon artı bir milyon artı bir milyon
Çıktı: E


2
Kullandığınız değerlendirme sırası nedir? Normalde, two plus two minus five times five divided by negative zero point five-> 2 + 2 - 5 * 5 / -0.5-> 54.
marinus

1
@marinus kesinlikle soldan sağa görünüyor. Kaydolduğunuz için teşekkürler
John Dvorak

1
girişte veya çıkışta başarısız olmak zorunda mıyız ? Ayrıca, 1e6 sınırı veya 1e9 sınırı ara sonuçlar için de geçerli mi? one million oneone billion one
John Dvorak

2
@JanDvorak Doğru çıktıyı verebildiğiniz sürece hiçbir şeyde (girdi, çıktı, aracı sonuçlar) başarısız olmanın gerekli olmadığını söyleyeceğim; başarısızlığın amacı insanların dürüst olmasını kolaylaştırmaktı.
konuk

1
Ondalık basamakları destekleme hakkında konuşuyorsunuz, ancak bunların nasıl ele alınacağını gerektiği gibi belirtmiyorsunuz. Doğru çıktı ne için olurdu one hundred divided by three point nought? (Ayrıca, son örneğin çıktısı neden Edaha ziyade three million?)
Peter Taylor

Yanıtlar:


6

Her şeyden önce, bu tamamen ucuz ve spesifikasyonlar için tam değil.

--disable-web-securitykrom üzerinde bayrak gerektirir , +22

Javascript 509 + 22 = 531

x=new XMLHttpRequest;y=Object.keys(x);b=alert;q="querySelectorAll";s="send";x[y[3]]="document";x.open("GET","http://www.wolframalpha.com/input/?i="+escape(prompt()));x[y[10]]=function(c){4===x.readyState&&(w=[].filter.call(x.response[q](".pod h2"),function(a){return"ame:"==a.innerText.slice(-4)})[0].parentElement,(k=w[q]("a")[0])&&"Words only"==k.innerText?(x.open("GET",k.href),x.send()):alert(JSON.parse([].pop.call(x[y[2]][q]("script")).innerHTML.match(/d_0.00\.push\((.+?)\)/)[1]).stringified))};x[s]()

Spesifikasyonun birincisi örnek çıktıdır
Giriş two plus two minus five times five divided by negative zero point fiveçıkışları

resim açıklamasını buraya girin

Başka bir dava iyi ele alınmalıdır (şimdi), bu henüz olduğu gibi oldukça ungolfed, sadece düzeltilmesini istedim.

input: two plus two
output: four

input: twenty-one point five minus one point five
output: twenty

input: one minus two
output: negative one

input: five times five
output: twenty-five

input: twenty-five divided by five
output: five

input: two plus two minus five times five divided by negative zero point five
output: fifty-four

input: one million times one thousand
output: one billion

input: one million times one thousand plus one
output: one billion, one

input: two million plus one million:
output: three million

input: one million plus one million plus one million
output: three million

Oh, ve eğer gerçekten test edecekseniz, tüm Wolfram Alpha sayfasını iki defa yüklediği için birkaç saniye sürebilir.

Yine de geliştirilecek çok şey olabilir.


Bunun eğlenceli bir cevap olduğunu inkar edemem, ancak çok kötü olmasına rağmen doğru formatta çıktı sağlamıyor. Son iki örneğin de çıktısının yanlış olduğunu unutmayın. Tabii ki, bu cevabın ne kadar meşru olduğu sorusu da var ... Önceden var olan başka bir programı sorgulayamayacağınızı açıkça belirtmeme rağmen, İngilizce'den sayıya çevirinin olduğu fikrini aktarmak istedim. , hesaplama ve sayıdan İngilizceye çeviri golfçü tarafından uygulanmalıdır. Yine de kuralların gerçek yorumunu geçiyor, ben vereceğim. :)
konuk

@guest =) Tamamen, sana katılıyorum =) Kurallara uymak, eğlenceli bir cevap, gerçek bir kod kodağından çok. Çıktıları düzeltme ve yeni bir sürüm gönderme sürecindeyim. Wolfram Alpha yalnızca görüntüleri kullanır, b64 kodlu bir veri özelliği olarak saklandığını anlamaya biraz zaman ayırdı.
C5H8NNaO4

@guest, güncelledi. Umarım çıktılar şimdi iyi =)
C5H8NNaO4

Mathematica'da bunu yaparsanız, doğru sayı ondalık basamakları vermek için çıktıyı kontrol edebilirsiniz ve böylece (N'nin kesirler için yapacağı şey budur): screenshot

Bu bir popülerlik yarışması olmasa da, hile ile yaratıcı olmak için +1 .
nyuszika7h

4

Python, 982

from re import*
S=split
U=sub
a=S(' ',U('_','teen ','zero one two three four five six seven eight nine ten eleven twelve thir_four_fif_six_seven_eigh_nine_')+U('_','ty ','twen_thir_for_fif_six_seven_eigh_nine_'))
b=range(20)+range(20,99,10)
d=dict(zip(a,b))
D=dict(zip(b,a))
p='point'
v='negative'
def f(s):
 s=S('[ -]',s);n=0.;m=10**(p in s and(s.index(p)-len(s)))
 for x in s[::-1]:m*=10*(m<1)+100*('hu'in x)+1e3*('ho'in x)+1e6*('m'in x)or 1;n+=(x in d)and m*d[x]
 return n-2*n*(v in s)
def F(n):
 l=[v]*(n<0);x=abs(n)
 for i in(9,6,3,0):z=int(x/10**i);h=z%100;g=(z>99)*[D[z/100],'hundred']+(h>0)*[h in D and D[h]or D[h-z%10]+'-'+D[z%10]];l+=g and g+[[],['thousand'],['million'],['billion']][i/3];x%=10**i
 l+=[c=='.'and p or D[int(c)]for c in'%.2g'%x][n**2>=1:];return' '.join(l)
c=lambda n,l:c(eval(`n`+l[0]+`f(l[1])`),l[2:])if l else n
i=S(' (?=. )|(?<= .) ',U('di.*?y','/',U('times','*',U('minus','-',U('plus','+',raw_input())))))
try:print F(c(f(i[0]),i[1:]))
except:print'E'

Teknik özelliklere göre olması gerektiği gibi çalıştığını düşünüyorum, ancak muhtemelen birkaç hata daha var. Girdi> = bir milyar veya yanlış yorumladığı beklenmedik kelimeler için garip davranabilir.

İşte birkaç değişiklikle biraz daha okunabilir bir sürüm:

import re
words = re.split(' ', re.sub('_', 'teen ', 'zero one two three four five six seven eight nine ten eleven twelve thir_four_fif_six_seven_eigh_nine_') + re.sub('_', 'ty ', 'twen_thir_for_fif_six_seven_eigh_nine_'))
values = range(20) + range(20, 99, 10)
d = dict(zip(words, values))
D = dict(zip(values, words))

def str_to_num(s):
    s = re.split('[ -]', s)
    n = 0.0
    multiplier = 10 ** ('point' in s and (s.index('point') - len(s)))

    for word in s[::-1]:
        multiplier *= 10 * (multiplier < 1) + 100 * ('hundred' == word) + 1e3 * ('thousand' == word) + 1e6 * ('million' == word) or 1
        n += (word in d) and multiplier * d[word]

    return n - 2 * n * ('negative' in s)


three_digit_num_to_str = lambda n: (n > 99) * [D[n / 100], 'hundred'] + (n % 100 > 0) * [n % 100 in D and D[n % 100] or D[n % 100 - n % 10] + '-' + D[n % 10]]

def num_to_str(n):
    word_list = ['negative'] * (n < 0)
    x = abs(n)

    for i in (9, 6, 3, 0):
        three_digit_str = three_digit_num_to_str(int(x / 10 ** i))
        if three_digit_str:
            word_list += three_digit_str + [[], ['thousand'], ['million'], ['billion']][i / 3]

        x %= 10 ** i

    word_list += [char == '.' and 'point' or D[int(char)] for char in '%.2g' % x][n ** 2 >= 1:]
    return ' '.join(word_list)

calculate = lambda n, l: calculate(eval(str(n) + l[0] + str(str_to_num(l[1]))), l[2:]) if l else n

i = re.split(' (?=. )|(?<= .) ', re.sub('di.*?y', '/', re.sub('times', '*', re.sub('minus', '-', re.sub('plus', '+', raw_input())))))

try:
    print num_to_str(calculate(str_to_num(i[0]), i[1:]))
except:
    print 'E'

1

Oraya gidiyoruz. Sürüm kırılmadan önce golf oynamak, ama şimdi tekrar çevrimiçi olduk. Daha fazla golf oynayabileceğinden eminim. Yarın üzerinde daha çok çalışacağım. Olsa da, golf olmadan düzgün çalışması için yeterince zordu ve gözlerim ona bakmaktan yorgun. haha

Java - 3220

import java.util.*;class a{int D=0,i,l,j;static boolean T=true,F=false;enum O{A("plus"),S("minus"),M("times"),D(""),P("point");String t;O(String u){t=u;}double p(double f,double s){if(this==A)f+=s;if(this==S)f-=s;if(this==M)f*=s;if(this==D)f/=s;return f;}static O f(String s){O r=null;for(O o:values())if(s.equals(o.t))r=o;return r;}}enum N{A("zero",0,F),B("one",1,F),C("two",2,F),D("three",3,F),E("four",4,F),AG("five",5,F),G("six",6,F),H("seven",7,F),I("eight",8,F),J("nine",9,F),K("ten",10,F),L("eleven",11,F),M("twelve",12,F),N("thirteen",13,F),O("fourteen",14,F),P("fifteen",15,F),Q("sixteen",16,F),R("seventeen",17,F),S("eighteen",18,F),AH("nineteen",19,F),U("twenty",20,F),V("thirty",30,F),W("forty",40,F),X("fifty",50,F),Y("sixty",60,F),Z("seventy",70,F),AA("eighty",80,F),AB("ninety",90,F),AC("hundred",100,T),AD("thousand",1000,T),AE("million",1000000,T),AF("billion",1000000000,T);String t;double v;boolean q;N(String u,int w,boolean r){t=u;v=w;q=r;}static N f(String s){N r=null;for(N n:values())if(s.equals(n.t))r=n;return r;}static N f(char s){return d(q(""+s));}static N d(double v){N r=null;for(N n:values())if(v==n.v)r=n;return r;}static String c(double n){return d(n).t;}}public static void main(String[]a){new a();}a(){while(T){try{List p=p(new Scanner(System.in).nextLine()),t=new ArrayList();double d=0;for(j=0;j<p.size();j++){Object o=p.get(j);if(o(o)){if((O)o==O.P){t.add((d(t.get(t.size()-1))+((d=d(p.get(j+1)))<10?d*=100:d<100?d*=10:d)/1000));t.remove(t.size()-2);j++;}else t.add(o);}else {N n=N.d(d(o));if(n!=null&&n.q){t.add((d(o))*d(t.get(t.size()-1)));t.remove(t.size()-2);}else t.add(o);}}double r=d(t.get(0));for(j=1;j<t.size();j++){Object c=t.get(j),l=t.get(j-1);if(o(c))continue;if(c instanceof Double&&l instanceof Double)r+=d(c);else r=((O)t.get(j-1)).p(r,d(t.get(j)));}System.out.println(p(r));}catch(Exception e){System.out.println("E");}}}List p(String s) {List r=new ArrayList();Scanner i=new Scanner(s);while(i.hasNext()){String c=i.next();if(c.equals("divided")){r.add(O.D);i.next();}else if(c.indexOf("-")!=-1){String[] num=c.split("-");r.add(N.f(num[0]).v+N.f(num[1]).v);}else{Object o=N.f(c);r.add(o!=null?((N)o).v:O.f(c));}}return r;}String p(double n){String a=String.valueOf(n),w,d=null,b="";l=a.indexOf(".");if(l!=-1){w=a.substring(0,l);d=a.substring(l+1);}else w=a;if(d.equals("0"))d=null;D=0;while(w.length()%3!=0)w=" "+w;for(i=w.length();i>0;i-=3,D++)b=w(w.substring(i-3,i))+b;return b+d(d);}String w(String w) {if(w==null)return "";w=w.trim();String b="";l=w.length();if(l>1&&w.charAt(l-2)!='0'){if(w.charAt(l-2)=='1')b=N.d(q(w.substring(l-2))).t;else b+=N.d(q(w.charAt(l-2)+"0")).t+"-"+N.f(w.charAt(l-1)).t;}for(j=(b.equals("")?l-1:l-3);j>-1;j--){N n=N.f(w.charAt(j));if(n==N.A)continue;if(j==l-1)b=n.t;else if(j==l-2)b=N.f(n.t+"0")+"-"+b;else if(j==l-3)b=n.t+" hundred "+b;}if(!b.trim().equals("")){if(D==1)b+=" thousand ";if(D==2)b+=" million ";if(D==3)b+=" billion ";}return b;}String d(String d) {if(d==null)return"";if(d.length()>3)d=d.substring(0,3);String b = " point ";for(char n:d.toCharArray())b+=N.f(n).t+" ";return b;}boolean o(Object o){return o instanceof O;}Double d(Object o){return (Double)o;}static double q(String s){return Double.parseDouble(s);}}

Satır kesmeleri ve sekmelerle

import java.util.*;

class a{

    int D=0,i,l,j;
    static boolean T=true,F=false;

    enum O{
        A("plus"),
        S("minus"),
        M("times"),
        D(""),
        P("point");

        String t;       
        O(String u){
            t=u;
        }

        double p(double f,double s){
            if(this==A)f+=s;
            if(this==S)f-=s;
            if(this==M)f*=s;
            if(this==D)f/=s;
            return f;
        }

        static O f(String s){
            O r=null;
            for(O o:values())if(s.equals(o.t))r=o;
            return r;
        }
    }

    enum N{
        A("zero",0,F),
        B("one",1,F),
        C("two",2,F),
        D("three",3,F),
        E("four",4,F),
        AG("five",5,F),
        G("six",6,F),
        H("seven",7,F),
        I("eight",8,F),
        J("nine",9,F),
        K("ten",10,F),
        L("eleven",11,F),
        M("twelve",12,F),
        N("thirteen",13,F),
        O("fourteen",14,F),
        P("fifteen",15,F),
        Q("sixteen",16,F),
        R("seventeen",17,F),
        S("eighteen",18,F),
        AH("nineteen",19,F),
        U("twenty",20,F),
        V("thirty",30,F),
        W("forty",40,F),
        X("fifty",50,F),
        Y("sixty",60,F),
        Z("seventy",70,F),
        AA("eighty",80,F),
        AB("ninety",90,F),
        AC("hundred",100,T),
        AD("thousand",1000,T),
        AE("million",1000000,T),
        AF("billion",1000000000,T);

        String t;
        double v;
        boolean q;

        N(String u,int w,boolean r){
            t=u;
            v=w;
            q=r;
        }

        static N f(String s){
            N r=null;
            for(N n:values())if(s.equals(n.t))r=n;
            return r;
        }

        static N f(char s){
            return d(q(""+s));
        }

        static N d(double v){
            N r=null;
            for(N n:values())if(v==n.v)r=n;
            return r;
        }

        static String c(double n){
            return d(n).t;
        }

    }


    public static void main(String[]a){
        new a();
    }


    a(){
        while(T){
            try{
                List p=p(new Scanner(System.in).nextLine()),t=new ArrayList();
                double d=0;
                for(j=0;j<p.size();j++){
                    Object o=p.get(j);
                    if(o(o)){
                        if((O)o==O.P){
                            t.add((d(t.get(t.size()-1))+((d=d(p.get(j+1)))<10?d*=100:d<100?d*=10:d)/1000));
                            t.remove(t.size()-2);
                            j++;
                        }
                        else t.add(o);
                    }
                    else {
                        N n=N.d(d(o));
                        if(n!=null&&n.q){
                            t.add((d(o))*d(t.get(t.size()-1)));
                            t.remove(t.size()-2);
                        }
                        else t.add(o);
                    }
                }

                double r=d(t.get(0));
                for(j=1;j<t.size();j++){
                    Object c=t.get(j),l=t.get(j-1);
                    if(o(c))continue;
                    if(c instanceof Double&&l instanceof Double)r+=d(c);
                    else r=((O)t.get(j-1)).p(r,d(t.get(j)));
                }

                System.out.println(p(r));
            }
            catch(Exception e){
                System.out.println("E");
            }
        }
    }

    List p(String s) {
        List r=new ArrayList();
        Scanner i=new Scanner(s);
        while(i.hasNext()){
            String c=i.next();
            if(c.equals("divided")){
                r.add(O.D);
                i.next();
            }
            else if(c.indexOf("-")!=-1){
                String[] num=c.split("-");
                r.add(N.f(num[0]).v+N.f(num[1]).v);
            }
            else{
                Object o=N.f(c);
                r.add(o!=null?((N)o).v:O.f(c));
            }
        }
        return r;
    }

    String p(double n){

        String a=String.valueOf(n),w,d=null,b="";

        l=a.indexOf(".");
        if(l!=-1){
            w=a.substring(0,l);
            d=a.substring(l+1);
        }
        else w=a;

        if(d.equals("0"))d=null;

        D=0;
        while(w.length()%3!=0)w=" "+w;

        for(i=w.length();i>0;i-=3,D++)b=w(w.substring(i-3,i))+b;

        return b+d(d);
    }


    String w(String w) {
        if(w==null)return "";
        w=w.trim();

        String b="";
        l=w.length();

        if(l>1&&w.charAt(l-2)!='0'){
            if(w.charAt(l-2)=='1')b=N.d(q(w.substring(l-2))).t;
            else b+=N.d(q(w.charAt(l-2)+"0")).t+"-"+N.f(w.charAt(l-1)).t;
        }

        for(j=(b.equals("")?l-1:l-3);j>-1;j--){
            N n=N.f(w.charAt(j));
            if(n==N.A)continue;
            if(j==l-1)b=n.t;
            else if(j==l-2)b=N.f(n.t+"0")+"-"+b;
            else if(j==l-3)b=n.t+" hundred "+b;
        }

        if(!b.trim().equals("")){
            if(D==1)b+=" thousand ";
            if(D==2)b+=" million ";
            if(D==3)b+=" billion ";
        }

        return b;
    }


    String d(String d) {
        if(d==null)return"";
        if(d.length()>3)d=d.substring(0,3);

        String b = " point ";
        for(char n:d.toCharArray())b+=N.f(n).t+" ";

        return b;
    }

    boolean o(Object o){
        return o instanceof O;
    }

    Double d(Object o){
        return (Double)o;
    }

    static double q(String s){
        return Double.parseDouble(s);
    }

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