Англійська цифрова калькулятор


16

Виклик

Напишіть калькулятор, який приймає введення у словесній формі (як можна говорити рівняння), а також виводить у словесній формі (як можна говорити число).

Правила

Калькулятор повинен вміти:

  • додавати, віднімати, множити і ділити
  • обробляти операнди від мінус мільйона до одного мільйона
  • обробляти обсяги виробництва від мінус до мільярда
  • обробляти десяткові крапки на вводі та розміщувати їх правильно у своєму висновку
  • обробляти десятковий вихід до сотого місця, округлюючи, де потрібно

Усі операції, що дають дробові результати, повинні округлюватись до найближчого сотого місця (ідентично формату виходу).

Повідомте з висновком "E" (за помилку), коли введення призведе до відмови програми через неправильне відформатування або ділення на 0; По суті, програма не повинна виходити з ладу при поганому введенні, тому що це був би паршивий калькулятор.

Калькулятор дозволений , але не зобов’язаний повідомляти про помилки, коли операнди або вихідні дані виходять з їх меж. Це покликане спростити проблему, але якщо ви не погоджуєтесь зі мною, сміливо робіть калькулятор, здатний правильно керувати більшими операндами та виходами без помилок повідомлення.

Виведіть "E" у тому випадку, якщо операнд для операції перевищує межі, визначені для операндів.

Виведіть "E" у тому випадку, якщо вихід перевищує межі, описані для виходів

Те, як програма поводиться з чутливістю до регістру та пробілом, залишається за гольфістом, як і вибір англійської чи американської англійської. 1

Програми, які обходять реалізацію калькулятора за допомогою мови або бібліотеки, яка вже реалізувала описаний вище функціонал, не підлягають перемозі.

Переможець

Перемагає програма з найменшою кількістю символів.

Приклади

Вхід: два плюс два
Вихід: чотири

Введення: двадцять одна точка п’ять мінус одна точка п’ять
Вихід: двадцять

Вхід: один мінус два
Вихід: негативний

Вхід: п’ять разів п’ять
Вихід: двадцять п’ять

Вхід: двадцять п’ять ділиться на п'ять
Вихід: п’ять

Введення: два плюс два мінус п’ять разів п'ять ділиться на від’ємну нульову точку п'ять
Вихід: десять

Вхідні дані один мільйон разів на тисячу
Вихід: один мільярд

Вхід: мільйон разів одна тисяча плюс один
вихід: E

Вхід: два мільйони плюс один мільйон
Вихід: E

Вхід: один мільйон плюс мільйон плюс один мільйон
Вихід: E


2
Який порядок оцінювання ви використовуєте? Зазвичай, two plus two minus five times five divided by negative zero point five-> 2 + 2 - 5 * 5 / -0.5-> 54.
marinus

1
@marinus виглядає суворо зліва направо. Дякуємо, що помітили
Джон Дворак

1
чи не доведеться виходити з ладу one million oneна вході чи one billion oneна виході? Також, чи застосовується межа 1e6 або межа 1e9 і для проміжних результатів?
Джон Дворак

2
@JanDvorak Я хочу сказати, що не потрібно відмовлятися ні від чого (введення, виводу, посередницьких результатів), щоб ви могли забезпечити правильний вихід; метою невдачі було полегшити людям чесність.
гість

1
Ви говорите про підтримку десяткових знаків, але не вказуєте належним чином, як з ними поводитися. Для чого був би правильний вихід one hundred divided by three point nought? (Крім того, чому результат остаточного прикладу, Eа не three million?)
Пітер Тейлор

Відповіді:


6

Перш за все, це цілком хитро, і не повно.

вимагає --disable-web-security прапор на хромі, +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]()

Перший вимкнення - це також приклад виведення
Вхідні two plus two minus five times five divided by negative zero point fiveвиходи

введіть тут опис зображення

Будь-який інший випадок повинен вирішуватися штрафом (зараз), це все ще досить неперероблено, як є, я просто хотів, щоб це виправили.

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

О, і якщо ви дійсно збираєтеся перевірити це, це може зайняти кілька секунд, оскільки він завантажує повну сторінку Wolfram Alpha до двох разів.

Що ж, може бути багато чого покращити.


Я не можу заперечити, що це забавна відповідь, хоча це занадто погано, що вона не забезпечує вихід у правильному форматі. Зауважте, що останні два приклади також мають неправильний вихід. Звичайно, є також питання, наскільки ця відповідь є правомірною ... хоча я прямо не заявив, що ви не можете запитати якусь іншу попередньо існуючу програму, я мав намір донести думку про те, що переклад з англійської на номер , обчислення та переклад з числа на англійську мову повинен виконувати гольфіст. Однак воно проходить буквальне тлумачення правил, я дам це так. :)
гість

@guest =) Я повністю згоден з вами з цього приводу =) Це цікавіше відповідь, дотримуючись правил, ніж власне кодовий гольф мента. Я перебуваю в процесі виправлення результатів і розміщую нову версію. Вольфрам Альфа використовує лише зображення, знадобився мені час, щоб зрозуміти, що його зберігається як атрибут даних, кодований b64.
C5H8NNaO4

@guest, оновив його. Я сподіваюся, що результати тепер нормальні =)
C5H8NNaO4

Якщо ви це зробите в Mathematica, ви можете керувати результатами, щоб дати правильну кількість десяткових знаків і так далі (що робитиме N для дробів): скріншот

+1 за те, що насправді проявляє творчість із обманом, хоча це не конкурс популярності .
nyuszika7h

4

Пітон, 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'

Я думаю, що це працює як слід відповідно до специфікацій, але, ймовірно, є ще кілька помилок. Це може діяти дивно за введення> = мільярд або будь-які несподівані слова, які вони трактують неправильно.

Ось дещо зручніша для читання версія з кількома змінами:

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

Там ми йдемо. Гольф версії, перш ніж її зламати, але зараз ми знову в Інтернеті. Я впевнений, що це може бути додатково гольф. Я буду працювати над цим більше завтра. Це було досить важко, щоб змусити його нормально працювати БЕЗ гольфу, хоча мої очі втомилися від цього дивитись. Ха-ха

Ява - 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);}}

З розривами рядків та вкладками

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

}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.