เครื่องคิดเลขตัวเลขภาษาอังกฤษ


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 ดูเหมือนจากซ้ายไปขวาอย่างเคร่งครัด ขอบคุณที่สังเกต
John Dvorak

1
เราต้องล้มเหลวone million oneในอินพุตหรือone billion oneเอาต์พุตหรือไม่? นอกจากนี้ขีด จำกัด 1e6 หรือขีด จำกัด 1e9 จะนำไปใช้กับผลลัพธ์ระดับกลางเช่นกันหรือไม่
John Dvorak

2
@JanDvorak ฉันจะบอกว่ามันไม่จำเป็นที่จะล้มเหลวในสิ่งใด (อินพุต, เอาต์พุต, ผลลัพธ์ตัวกลาง) ตราบใดที่คุณสามารถส่งผลลัพธ์ที่ถูกต้อง; จุดประสงค์ของความล้มเหลวคือการทำให้คนซื่อสัตย์ได้ง่ายขึ้น
แขกรับเชิญ

1
คุณพูดคุยเกี่ยวกับการสนับสนุนทศนิยม แต่คุณไม่ได้ระบุอย่างถูกต้องว่าจะจัดการได้อย่างไร เอาต์พุตที่ถูกต้องมีไว้เพื่อone hundred divided by three point noughtอะไร? (นอกจากนี้ทำไมผลลัพธ์ของตัวอย่างสุดท้ายEไม่ใช่three million?)
Peter Taylor

คำตอบ:


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 =) ฉันทั้งหมดเห็นด้วยกับคุณในเรื่องนั้น =) มันเป็นคำตอบที่สนุกมากขึ้นการวางกติกา ฉันอยู่ระหว่างการแก้ไขเอาต์พุตและโพสต์เวอร์ชันใหม่ Wolfram Alpha ใช้ภาพเท่านั้นฉันใช้เวลาสักครู่เพื่อคิดว่ามันถูกเก็บไว้เป็น data data ซึ่งเข้ารหัส b64
C5H8NNaO4

@guest อัปเดต ฉันหวังว่าผลลัพธ์จะเป็นไร =)
C5H8NNaO4

หากคุณทำสิ่งนี้ใน Mathematica คุณสามารถควบคุมผลลัพธ์เพื่อให้ได้ตำแหน่งทศนิยมที่ถูกต้องและอื่น ๆ (ซึ่งเป็นสิ่งที่ N จะทำเพื่อเศษส่วน): screenshot

+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'

ฉันคิดว่ามันทำงานได้ตามที่ควรเป็นไปตามสเป็ค แต่อาจมีข้อบกพร่องอีกเล็กน้อย มันอาจทำหน้าที่แปลก ๆ สำหรับการป้อนข้อมูล> = หนึ่งพันล้านคำหรือคำที่ไม่คาดคิดใด ๆ ที่แปลผิด

นี่เป็นเวอร์ชันที่อ่านง่ายขึ้นเล็กน้อยโดยมีการเปลี่ยนแปลงเล็กน้อย:

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

เราจะไปที่นั่น. ตีกอล์ฟเวอร์ชั่นก่อนที่จะพัง แต่ตอนนี้เรากลับมาออนไลน์แล้ว ฉันคิดว่ามันสามารถเล่นกอล์ฟต่อไปได้ พรุ่งนี้ฉันจะทำงานให้มากกว่านี้ มันยากพอที่จะทำให้มันทำงานอย่างถูกต้องโดยที่ไม่ต้องตีกอล์ฟและตาของฉันก็เบื่อที่จะจ้องมอง ฮ่าฮ่า

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

ด้วยตัวแบ่งบรรทัดและแท็บ

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.