영어 숫자 계산기


16

도전

구두 형식으로 입력 (수식을 말할 수 있음)하고 구두 형식으로 출력하는 계산기를 작성하십시오 (숫자가 말할 수 있음).

규칙

계산기는 다음을 수행 할 수 있어야합니다.

  • 더하기, 빼기, 곱하기 및 나누기
  • 음수 백만에서 백만 사이의 피연산자 처리
  • 마이너스 10 억에서 10 억 사이의 출력 처리
  • 입력에서 소수점을 처리하고 출력에 올바르게 배치하십시오.
  • 소수점 이하 자릿수를 100 분의 1까지 처리하고 필요한 경우 반올림

소수 결과를 생성하는 모든 작업은 가장 가까운 100 분의 1 (둥글게는 출력 형식)로 반올림해야합니다.

입력으로 인해 형식이 잘못되었거나 0으로 나누어 프로그램이 실패 할 경우 출력 "E"(오류)로보고하십시오. 기본적으로 프로그램은 잘못된 입력으로 인해 충돌하지 않아야합니다.

계산기는 허용 되지만 피연산자 또는 출력이 경계를 벗어날 때 오류를보고 할 필요없습니다 . 이것은 문제를 단순화하기위한 것이지만, 동의하지 않으면 오류를보고하지 않고 더 큰 피연산자와 출력을 올바르게 처리 할 수있는 계산기를 만드십시오.

연산의 피연산자가 피연산자에 대해 정의 된 범위를 초과하는 경우 "E"를 출력합니다.

출력이 출력에 대해 설명 된 범위를 초과하는 경우 출력 "E"

프로그램이 대소 문자 구분을 처리하는 방법과 공백은 영국 또는 미국 영어의 선택과 같이 골퍼에게 달려 있습니다. 1

위에서 설명한 기능을 이미 구현 한 언어 또는 라이브러리를 사용하여 계산기 구현을 우회하는 프로그램은 승리 할 수 ​​없습니다.

우승자

문자 수가 가장 적은 프로그램이 승리합니다.

입력 : 2 더하기 2
출력 : 4

입력 : 21 점 5 빼기 1 점 5
출력 : 20

입력 : 1 빼기 2
출력 : 빼기 1

입력 : 5 곱하기 5
출력 : 25

입력 : 25를 5로 나눈
출력 : 5

입력 : 2 더하기 2 빼기 5 곱하기 5를 음의 영점 5로 나눈
출력 : 10

입력 백만 번 천
출력 :

입력 : 백만 곱하기 1,000 더하기
출력 : E

입력 : 2 백만 + 1 백만
출력 : 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는 엄격하게 왼쪽에서 오른쪽으로 보입니다. 주목 해 주셔서 감사합니다
John Dvorak

1
우리가 할 실패하는 one million one입력 또는 one billion one출력에? 또한 1e6 제한 또는 1e9 제한이 중간 결과에도 적용됩니까?
존 드보락

2
@JanDvorak 올바른 출력을 전달할 수 있다면 아무 것도 (입력, 출력, 중간 결과) 실패하지 않아도됩니다. 실패의 목적은 사람들이 정직하게하기 쉽게하는 것이 었습니다.
손님

1
소수를 지원하는 것에 대해 이야기하지만 어떻게 처리해야하는지 제대로 지정하지 않았습니다. 올바른 출력은 무엇입니까 one hundred divided by three point nought? (또한 최종 예제의 출력 Ethree million? 가 아닌 왜입니까?)
Peter Taylor

답변:


6

우선, 이것은 완전히 건전하며 사양에 완전하지 않습니다.

--disable-web-security크롬에 깃발이 필요합니다 , +22

자바 스크립트 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 =) 전적으로 동의합니다. =) 실제 멘션 코드 골프보다 규칙에 기반을 둔 재미있는 답변입니다. 출력을 수정하고 새 버전을 게시하는 중입니다. Wolfram Alpha는 이미지 만 사용하고 b64로 인코딩 된 데이터 속성으로 저장된 이미지를 파악하는 데 시간이 걸렸습니다.
C5H8NNaO4

@guest, 업데이트했습니다. 내가 출력이 이제 괜찮 = 희망)
C5H8NNaO4

Mathematica에서이 작업을 수행하면 올바른 소수점 이하 자릿수 등을 제공하도록 출력을 제어 할 수 있습니다 (N은 분수에 대해 수행하는 것임) : screenshot

비록 이것이 인기 콘테스트 가 아니더라도 실제로 부정 행위로 창의적으로 행동하는 데 +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'

사양에 따라 작동한다고 생각하지만 몇 가지 버그가 더 있습니다. 입력> = 10 억 또는 잘못 해석 한 예기치 않은 단어에 대해 이상하게 작동 할 수 있습니다.

다음은 약간의 변경 사항이있는 약간 더 읽기 쉬운 버전입니다.

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

}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.