Chuyển đổi tiếng Anh sang số không có thư viện hoặc thư viện


14

Thử thách này cũng tương tự như thử thách này , tuy nhiên tôi đã đưa ra một hạn chế (xem văn bản in đậm bên dưới) mà tôi nghĩ sẽ làm cho nó khác đi nhiều và (tôi hy vọng) cũng vui.

Các thách thức

Viết chương trình hoặc hàm trong bất kỳ ngôn ngữ lập trình nào lấy đầu vào tên tiếng Anh của số nguyên dương nkhông vượt quá 100và trả về ndưới dạng số nguyên.

Các lỗ hổng tiêu chuẩn bị cấm và bạn không thể sử dụng bất kỳ chức năng tích hợp, công cụ bên ngoài hoặc thư viện nào đã thực hiện công việc này .

Mã nguồn ngắn nhất tính bằng byte thắng.

Kiểm tra

Đây là tất cả các input->outputtrường hợp:

one              -> 1
two              -> 2
three            -> 3
four             -> 4
five             -> 5
six              -> 6
seven            -> 7
eight            -> 8
nine             -> 9
ten              -> 10
eleven           -> 11
twelve           -> 12
thirteen         -> 13
fourteen         -> 14
fifteen          -> 15
sixteen          -> 16
seventeen        -> 17
eighteen         -> 18
nineteen         -> 19
twenty           -> 20
twenty-one       -> 21
twenty-two       -> 22
twenty-three     -> 23
twenty-four      -> 24
twenty-five      -> 25
twenty-six       -> 26
twenty-seven     -> 27
twenty-eight     -> 28
twenty-nine      -> 29
thirty           -> 30
thirty-one       -> 31
thirty-two       -> 32
thirty-three     -> 33
thirty-four      -> 34
thirty-five      -> 35
thirty-six       -> 36
thirty-seven     -> 37
thirty-eight     -> 38
thirty-nine      -> 39
forty            -> 40
forty-one        -> 41
forty-two        -> 42
forty-three      -> 43
forty-four       -> 44
forty-five       -> 45
forty-six        -> 46
forty-seven      -> 47
forty-eight      -> 48
forty-nine       -> 49
fifty            -> 50
fifty-one        -> 51
fifty-two        -> 52
fifty-three      -> 53
fifty-four       -> 54
fifty-five       -> 55
fifty-six        -> 56
fifty-seven      -> 57
fifty-eight      -> 58
fifty-nine       -> 59
sixty            -> 60
sixty-one        -> 61
sixty-two        -> 62
sixty-three      -> 63
sixty-four       -> 64
sixty-five       -> 65
sixty-six        -> 66
sixty-seven      -> 67
sixty-eight      -> 68
sixty-nine       -> 69
seventy          -> 70
seventy-one      -> 71
seventy-two      -> 72
seventy-three    -> 73
seventy-four     -> 74
seventy-five     -> 75
seventy-six      -> 76
seventy-seven    -> 77
seventy-eight    -> 78
seventy-nine     -> 79
eighty           -> 80
eighty-one       -> 81
eighty-two       -> 82
eighty-three     -> 83
eighty-four      -> 84
eighty-five      -> 85
eighty-six       -> 86
eighty-seven     -> 87
eighty-eight     -> 88
eighty-nine      -> 89
ninety           -> 90
ninety-one       -> 91
ninety-two       -> 92
ninety-three     -> 93
ninety-four      -> 94
ninety-five      -> 95
ninety-six       -> 96
ninety-seven     -> 97
ninety-eight     -> 98
ninety-nine      -> 99
one hundred      -> 100

1
Điều gì về một công cụ tích hợp thực hiện một nửa công việc, ví dụ như tìm tên unicode của một mật mã.
Brad Gilbert b2gills

@ BradGilbertb2gills Không, nó không ổn.
Bob

Câu trả lời:


22

C, 160 byte

g(char*s){char i=1,r=0,*p="k^[#>Pcx.yI<7CZpVgmH:o]sYK$2";for(;*s^'-'&&*s;r+=*s++|9);r=r%45+77;for(;*p!=r;p++,i++);return((*s^'-')?0:g(s+1))+(i<21?i:10*(i-18));}

Kiểm tra nó

int main ()
{
    char* w[] = {"", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty", "twenty-one", "twenty-two", "twenty-three", "twenty-four", "twenty-five", "twenty-six", "twenty-seven", "twenty-eight", "twenty-nine", "thirty", "thirty-one", "thirty-two", "thirty-three", "thirty-four", "thirty-five", "thirty-six", "thirty-seven", "thirty-eight", "thirty-nine", "forty", "forty-one", "forty-two", "forty-three", "forty-four", "forty-five", "forty-six", "forty-seven", "forty-eight", "forty-nine", "fifty", "fifty-one", "fifty-two", "fifty-three", "fifty-four", "fifty-five", "fifty-six", "fifty-seven", "fifty-eight", "fifty-nine", "sixty", "sixty-one", "sixty-two", "sixty-three", "sixty-four", "sixty-five", "sixty-six", "sixty-seven", "sixty-eight", "sixty-nine", "seventy", "seventy-one", "seventy-two", "seventy-three", "seventy-four", "seventy-five", "seventy-six", "seventy-seven", "seventy-eight", "seventy-nine", "eighty", "eighty-one", "eighty-two", "eighty-three", "eighty-four", "eighty-five", "eighty-six", "eighty-seven", "eighty-eight", "eighty-nine", "ninety", "ninety-one", "ninety-two", "ninety-three", "ninety-four", "ninety-five", "ninety-six", "ninety-seven", "ninety-eight", "ninety-nine", "one hundred"};

    int n;
    for (n = 1; n <= 100; n++)
    {
        printf ("%s -> %d\n", w[n], g(w[n]));
        if (n != g(w[n]))
        {
            printf ("Error at n = %d", n);
            return 1;
        }
    }
    return 0;
}

Làm thế nào nó hoạt động

Sau một số nỗ lực, tôi tìm thấy một chức năng mà các bản đồ số "đặc biệt" one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty, thirty, forty, fifty, sixty, seventy, eighty, ninety, one hundred, để các ký tự ASCII in k, ., [, <, *, , c, K, w, y, e, (, S, _, -, C, ), 7, =, 4, &,o, ], s, Y, g, m, N, Tương ứng.

Chức năng này là:

char hash (char* s)
{
    char r = 0;

    while (*s)
    {
        r += *s|9;
        s++;
    }

    return r%45+77;
}

Chương trình đánh gôn tính toán hashchức năng của đầu vào cho đến khi đến cuối chuỗi hoặc ký tự -. Sau đó, nó tìm kiếm hàm băm trong chuỗi k.[<* cKwye(S_-C)7=4&o]sYgmNvà xác định số tương ứng. Nếu kết thúc chuỗi đầu vào đã đạt được, số được trả về, nếu thay vào đó là một chuỗi -, thì nó được trả về số cộng với kết quả của chương trình đánh gôn được áp dụng cho phần còn lại của chuỗi đầu vào.


Tôi đang nghĩ, nếu có một phiên bản chơi gôn của C, nó thực sự có thể đánh bại các ngôn ngữ như CJam Pyth Japt, v.v ...
busukxuan

11

JavaScript (ES6), 175 166 163 156 153 147 byte

Đã lưu 7 byte nhờ @Neil

a=>+a.replace(/.+te|.*el|y$/,x=>x[1]?'on-'+x:'-d').split(/ |-|dr/).map(x=>"un|d,on|le,w,th,fo,f,x,s,h,i,".split`,`.findIndex(y=>x.match(y))).join``

Xác nhận nó ở đây:

Làm thế nào nó hoạt động

Ý tưởng cơ bản là chia mỗi số thành các chữ số của nó, sau đó ánh xạ từng từ thành chữ số tương ứng. Hầu như tất cả các từ được thiết lập để được kết hợp đúng với một biểu thức chính đơn giản, nhưng có một vài điều bất thường:

  • eleventhông qua nineteen: nếu từ có chứa một elhoặc một teở giữa (để tránh ten), chúng ta thêm một on-từ đầu, thay đổi những từ này thành on-eleventhông qua on-nineteen.
  • twenty, thirty, V.v .: thay thế một dấu yvới -dnhững thay đổi này để twent-d, thirt-dvv

Bây giờ chúng tôi phân chia tại dấu gạch nối, dấu cách và drs. Điều này phân chia mọi thứ từ 11 đến 99 thành các từ chữ số tương ứng và "one hundred"thành [one,hun,ed]. Sau đó, chúng tôi ánh xạ từng từ này thông qua một loạt các biểu thức chính quy và giữ chỉ mục của từ phù hợp đầu tiên.

0: /un|d/ - This matches the "hun" and "ed" in 100, as well as the "d" we placed on the end of 20, 30, etc.
1: /on|le/ - Matches "one" and the "on" we placed on the beginning of 11 through 19, along with "eleven".
2: /w/ - Matches "two", "twelve", and "twenty".
3: /th/ - Matches "three" and "thirty".
4: /fo/ - Matches "four" and "forty".
5: /f/ - "five" and "fifty" are the only words by now that contain an "f".
6: /x/ - "six" and "sixty" are the only words that contain an "x".
7: /s/ - "seven" and "seventy" are the only words by now that contain an "s".
8: /h/ - "eight" and "eighty" are the only words by now that contain an "h".
9: /i/ - "nine" and "ninety" are the only words by now that contain an "i".
10: /<empty>/ - "ten" is the only word left, but it still has to be matched.

Đến bây giờ, mỗi đầu vào sẽ là mảng các chữ số thích hợp. Tất cả những gì chúng ta phải làm là tham gia cùng họ join``, chuyển đổi thành một số với unary +và chúng ta đã hoàn thành.


Vui lòng giải thích.
Bob

@Bob Chắc chắn, giải thích thêm.
Sản xuất ETH

Không .findIndex(y=>x.match(y))hoạt động?
Neil

@Neil Tôi không nhận ra điều đó, nhưng nó, cảm ơn!
Sản xuất ETH

Tôi khá chắc chắn rằng bạn có thể bí danh replace.
Mama Fun Roll

6

sh + coreutils, 112 byte

Có thể chạy trên tất cả các testcase cùng một lúc, mỗi dòng trên một dòng.

sed -r "`awk '$0="s/"$0"/+"NR"/g"'<<<"on
tw
th
fo
fi
si
se
ei
ni
te|lv
el"`
s/ /y0/
s/y/*10/
s/^\+|[a-z-]//g"|bc

Giải trình

Các backticky awkđánh giá sedkịch bản

s/on/+1/g       # one, one hundred
s/tw/+2/g       # two, twelve, twenty
s/th/+3/g       # three, thirteen, thirty
s/fo/+4/g       # ...
s/fi/+5/g
s/si/+6/g
s/se/+7/g
s/ei/+8/g
s/ni/+9/g
s/te|lv/+10/g   # ten, -teen, twelve
s/el/+11/g      # eleven

mà biến đổi các phần của số thành biểu diễn số của chúng.

fife            ->    +5ve
ten             ->    +10n
eleven          ->    +11even
twelve          ->    +2e+10e
sixteen         ->    +6x+10en
thirty-seven    ->    +3irty-+7ven
forty-four      ->    +4rty-+4ur
eighty          ->    +8ghty
one hundred     ->    +1e hundred

Các dòng bổ sung của tập lệnh sed

s/ /y0/
s/y/*10/

chăm sóc của -tys và one hundred.

+3irty-+7ven    ->    +3irt*10-+7ven
+4rty-+4ur      ->    +4rt*10-+4ur
+8ghty          ->    +8ght*10
+1e hundred     ->    +1ey0hundred      ->    +1e*100hundred

Cuối cùng, xóa +s hàng đầu và mọi thứ không +, *hoặc một chữ số.

s/^\+|[a-z-]//g"

Chỉ các biểu thức toán học còn lại

fife            ->    5
sixteen         ->    6+10
forty-four      ->    4*10+4
eighty          ->    8*10
one hundred     ->    1*100

và có thể được dẫn vào bc.


4

Pyth, 79 76 75 68 byte

Cảm ơn @ETHproductions cho 7 byte.

?}"hu"z100sm*+hxc."ewEСBu­["2<d2?|}"een"d}"lv"dTZ?}"ty"dT1cz\-

Về cơ bản, trước tiên hãy kiểm tra trường hợp góc là 100, sau đó sử dụng một mảng gồm hai chữ cái đầu tiên của các số từ 0 đến 11 để xác định ngữ nghĩa của đầu vào và sửa đổi giá trị theo hậu tố ("-ty" và "-teen"; " lv "trong 12 là một trường hợp góc khác). Đầu tiên phân tách đầu vào thành một danh sách các từ, sau đó ánh xạ từng từ thành một giá trị và tổng hợp chúng lại.

Trong mã giả pythonic:

                           z = input()    # raw, unevaluated
                           Z = 0
                           T = 10
?}"hu"z                    if "hu" in z:  # checks if input is 100
  100                        print(100)
                           else:
sm                           sum(map( lambda d: # evaluates each word, then sum
  *                            multiply(
   +hxc."ewEСBu­["2<d2           plusOne(chop("ontwth...niteel",2).index(d[:2])) + \
                                 # chops string into ["on","tw",..."el"]
                                 # ."ewEСBu­[" is a packed string
     ?|}"een"d}"lv"dTZ               (T if "een" in d or "lv" in d else Z),
                                     # add 10 for numbers from 12 to 19
   ?}"ty"dT1                     T if "ty" in d else 1),  # times 10 if "-ty"
  cz\-                         z.split("-"))  # splits input into words

Bộ kiểm tra


Python 3, 218 byte

z=input()
if "hu" in z:print(100);exit()
print(sum(map(lambda d:([0,"on","tw","th","fo","fi","si","se","ei","ni","te","el"].index(d[:2])+(10 if "een" in d or "lv" in d else 0))*(10 if "ty" in d else 1),z.split("-"))))

Về cơ bản giống hệt câu trả lời của Pyth.


Đề ra:

Tôi vừa khám phá ra một phiên bản có ý nghĩa của câu trả lời cho cuộc sống, vũ trụ và mọi thứ: đó là cành cây khát trà. Wow, cành cây khao khát trà! Tôi không chắc có bao nhiêu câu trả lời khác làm điều này, nhưng đối với câu trả lời của tôi nếu đầu vào là "tách trà khát" thì đầu ra là 42.


Tôi tin rằng bạn có thể lưu bảy byte bằng cách sử dụng một chuỗi đóng gói . Sao chép đầu ra và đặt nó vào vị trí của "ontwthfofisiseeiniteel"chương trình này.
Sản xuất ETH

@ETHproductions Wow, cảm ơn! Lần cuối cùng tôi kiểm tra, vẫn còn "ze" ở đầu chuỗi và việc đóng gói không thể hoạt động. Tôi đã không kiểm tra một lần nữa sau khi tôi chơi nó. Một lần nữa, cảm ơn xD
busukxuan

@ETHproductions vâng tôi thực sự đã làm, nó nằm dưới mã giả.
busukxuan

2

Python 3, 365 361 310 303 ký tự

Chơi gôn

def f(a):
 y=0
 for i in a.split("-"):
  x="one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir;four;fif;six;seven;eigh;nine;twenty,thirty,forty,fifty,sixty,seventy,eighty,ninety,one hundred".replace(";","teen,").split(",").index(i)
  y+=x+1 if x<20 else range(30,110,10)[x-20]
 return y

Ung dung

 def nameToNumber (numberName):
    names = ["one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve","thirteen",
             "fourteen","fifteen","sixteen","seventeen","eighteen","nineteen","twenty","thirty","forty","fifty",
             "sixty","seventy","eighty","ninety","one hundred"]
    numbers = range(30, 110, 10)
    number = 0
    for n in numberName.split("-"):
        x = names.index(n)
        number += x + 1 if x < 20 else numbers[x - 20]
    return number

Ngắn hơn 45 ký tự: n="one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen,twenty,thirty,forty,fifty,sixty,seventy,eighty,ninety,one hundred".split(",")Nhưng như tôi thấy, nên hoạt động mà không gán nó cho biến n, chỉ cần gọi .index()trực tiếp vào nó.
manatwork

7 ký tự ngắn hơn : "one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir;four;fif;six;seven;eigh;nine;twenty,thirty,forty,fifty,sixty,seventy,eighty,ninety,one hundred".replace(";","teen,").split(",").
manatwork

Công cụ trang web StackExchange có một thói quen khó chịu: nó chèn các ký tự vô hình (U200C Zero Width Non-Joiner và U200B Zero Width Space) vào mã được đăng trong các bình luận. Bạn sao chép-dán chúng quá. Tôi đã chỉnh sửa bài viết của bạn để loại bỏ chúng.
manatwork

2

Haskell, 252 231 byte

let l=words;k=l"six seven eight nine";w=l"one two three four five"++k++l"ten eleven twelve"++((++"teen")<$>l"thir four fif"++k)++[n++"ty"++s|n<-l"twen thir for fif"++k,s<-"":['-':x|x<-take 9w]]in maybe 100id.flip lookup(zip w[1..])

Điều này tạo ra một danh sách tất cả các tên số tiếng Anh từ "một" đến "chín mươi chín" và sau đó xem chỉ số của đầu vào lên. Nếu nó không tồn tại, chúng ta đang ở trong trường hợp cạnh "một trăm", vì vậy nó sẽ trả về 100, nếu không nó sẽ trả về chỉ mục.

Ung dung

-- k in the golfed variant
common = words "six seven eight nine" 

-- w in the golfed variant
numbers = words "one two three four five" ++ common
       ++ words "ten eleven twelve" ++ [p ++ "teen" | p <- words "thir four fif" ++ common]
       ++ [p ++ "ty" ++ s| p <- words "twen thir for fif" ++ common
                         , s <- "" : map ('-':) (take 9 numbers)]

-- part of the expression in the golfed variant
convert :: String -> Int
convert s = maybe 100 id $ lookup s $ zip numbers [1..]

2

Python 2, 275 ký tự

def x(n):a='one two three four five six seven eight nine ten eleven twelve'.split();t='twen thir four fif six seven eigh nine'.split();b=[i+'teen'for i in t[1:]];c=[i+'ty'for i in t];return(a+b+[i+j for i in c for j in ['']+['-'+k for k in a[:9]]]+['one hundred']).index(n)+1

Nó đơn giản xây dựng một danh sách của mỗi số và tìm thấy chỉ mục.


1

Japt, 82 byte

+Ur`(.+)¿``¿-$1` r"y$""-d" q$/ |-|dr/$ £`un|Üaiwo|ØÏ¿ifoifix¿iÊ¿¿e¿iv`qi b_XfZ}Ãq

Mỗi ¿đại diện cho một char không thể in. Kiểm tra nó trực tuyến!

Dựa trên câu trả lời JS của tôi. Trừ đi một byte nếu đầu ra không cần phải là số nguyên, vì nó sẽ xuất hiện giống hệt như một chuỗi.

Làm thế nào nó hoạt động

+Ur`(.+)¿` `¿-$1`  r"y$""-d" q/ |-|dr/ £  `un|Üaiwo|ØÏ¿ifoifix¿iÊ¿¿e¿iv`          qi b_ XfZ}à q
+Ur"(.+)te""on-$1" r"y$""-d" q/ |-|dr/ mX{"un|dioniwo|wenithifoifixisihineiteiniv"qi bZ{XfZ}} q

Ur"(.+)te""on-$1" // Replace "thirteen", "fourteen", etc. with "on-thiren", "on-fouren", etc.
r"y$""-d"         // Replace "twenty", "thirty", etc. with "twent-d", "thirt-d", etc.
q/ |-|dr/         // Split at occurances of a space, hyphen, or "dr". By now,
                  // "one", "thirteen", "twenty", "sixty-six", "one hundred" will have become:
                  // "one", "on" "thiren", "twent" "d", "sixty" "six", "one" "hun" "ed"
mX         }      // Map each item X in the resulting array to:
"..."qi           //  Take this string, split at "i"s,
b_XfZ}            //  and find the first item Z where X.match(RegExp(Z)) is not null.
                  //  See my JS answer to learn exactly how this works.
                  // Our previous example is now
                  // "1", "1" "3", "2" "0", "6" "6", "1" "0" "0"
+              q  // Join and convert to integer.
                  // 1, 13, 20, 66, 100

1

JavaScript, 214 199 byte

Như mọi khi: hóa ra điều này quá dài để cạnh tranh, nhưng bây giờ tôi đã làm xong, thật lãng phí nếu không đăng bài này.

Có lẽ có một cách rõ ràng để chơi golf xa hơn mà tôi đã bỏ qua?

e=s=>s.slice(-1)=='d'?100:'  ontwthfofisiseeinite'.indexOf(s.slice(0,2))/2;f=s=>([t,u]=s.split('-'),~s.indexOf`le`?11:~s.indexOf`lv`?12:e(t)+(t.slice(-3)=='een')*10+''+(u?e(u):t.slice(-1)=='y'?0:''))

JSFiddle cho các trường hợp thử nghiệm


1
Làm thế nào về việc thay đổi fđể f=s=>([t,u]=s.split('-'),~s.indexOf('le')?11:~s.indexOf('lv')?12:e(t)+(t.slice(-3)=='een')*10+''+(u?e(u):t.slice(-1)=='y'?0:''))? Ngoài ra, một đối số chuỗi đơn có thể được truyền cho một hàm như vậy:s.indexOf`lv`
ETHproductions 10/2/2016

@ETHproductions Thật tuyệt, cảm ơn! Tôi không biết JS có toán tử dấu phẩy và tốc ký cho chuỗi truyền cũng thực sự hữu ích.
vvye 10/2/2016

1

Perl, 158 byte

@s=split/(\d+)/,'te1ten0l1le1on1tw2th3fo4fi5si6se7ei8ni9d00';foreach(split'-',$n=$ARGV[0]){for($i=0;$i<$#s;$i+=2){m/$s[$i]/&&print$s[$i+1]}}$n=~/ty$/&&print 0

Chạy từ dòng lệnh. one hundredphải được nhập vào "one hundred"để ngăn chặn nó được hiểu là hai đầu vào.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.