İngilizceyi yerleşik veya kitaplık içermeyen bir sayıya dönüştürme


14

Bu zorluk benzer bu diğer ancak (aşağıda kalın metin bakınız) Ben çok diffent ve (umarım) eğlenceli ya yapılan olacağını düşünüyorum bir kısıtlama yapılan.

Meydan okuma

Herhangi bir programlama dilinde, pozitif bir tamsayının İngilizce adını ngeçmeyen 100ve ntamsayı olarak dönen bir program veya işlev yazın .

Standart boşluklar yasaktır ve bu işi zaten yapan yerleşik bir işlevi, harici aracı veya kütüphaneyi kullanamazsınız .

Bayt cinsinden en kısa kaynak kodu kazanır.

Ölçek

İşte tüm input->outputdavalar:

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
İşin yarısını yapan, örneğin bir kod noktasının unicode adını bulmak için yerleşik olana ne dersiniz?
Brad Gilbert b2gills

@ BradGilbertb2gills Hayır, iyi değil.
Bob

Yanıtlar:


22

C, 160 bayt

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

Dene

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

Nasıl çalışır

Bazı denemeden sonra ben "olağanüstü" numaralarını eşleştiren bir fonksiyon buldum 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, yazdırılabilir ASCII karakter k, ., [, <, *, , c, K, w, y, e, (, S, _, -, C, ), 7, =, 4, &,o, ], s, Y, g, m, N, Sırasıyla.

Bu işlev:

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

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

    return r%45+77;
}

Golfçü program hash, girişin fonksiyonunu dizenin veya karakterin sonuna ulaşıncaya kadar hesaplar -. Daha sonra dizedeki karmayı arar k.[<* cKwye(S_-C)7=4&o]sYgmNve karşılık gelen sayıyı belirler. Giriş dizesinin sonuna ulaşılmışsa, sayı döndürülür, bunun yerine a -değerine ulaşılırsa, sayı artı giriş dizesinin geri kalanına uygulanan golfed programının sonucu döndürülür.


Bence, C'nin golf versiyonu olsaydı, aslında CJam Pyth Japt gibi dilleri yenebilir ...
busukxuan

11

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

@Neil sayesinde 7 bayt kaydedildi

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``

Burada doğrulayın:

Nasıl çalışır

Temel fikir, her sayıyı rakam sözcüklerine bölmek, ardından her kelimeyi karşılık gelen basamağa eşlemektir. Hemen hemen tüm kelimeler basit bir normal ifade ile düzgün bir şekilde eşleşecek şekilde ayarlanmıştır, ancak birkaç anormallik vardır:

  • elevenyoluyla nineteen: Eğer kelime bir el, veya teortasında bir ( varsa) içeriyorsa , başlangıcına tena ekleriz on-ve bunları yerine on-elevengeçeriz on-nineteen.
  • twenty, thirtyVb .: bir arka değiştirilmesi yile -ddeğişiklik Bunlara twent-d, thirt-dvb

Şimdi tire, boşluk ve bölmelere ayrıldık dr. Bu, 11'den 99'a kadar her şeyi karşılık gelen rakam sözcüklerine ve "one hundred"içine böler [one,hun,ed]. Sonra bu kelimelerin her birini bir dizi normal ifade ile eşleriz ve önce eşleşen kelimenin dizinini tutarız.

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.

Şimdiye kadar, her bir girdi uygun basamakların dizisi olacaktır. Tek yapmamız gereken onlara katılmak join``, tekli bir sayıya dönüştürmek +ve işimiz bitti.


Lütfen açıkla.
Bob

@Bob Tabii, açıklama eklendi.
ETHproductions

Çalışmıyor mu .findIndex(y=>x.match(y))?
Neil

@Neil bunun olacağını fark etmedim, ama oluyor, teşekkürler!
ETHproductions

Takma ad yapabileceğinizden eminim replace.
Mama Fun Roll

6

sh + coreutils, 112 bayt

Tüm test senaryolarında bir seferde, her satıra bir tane olmak üzere çalıştırılabilir.

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

açıklama

Backticked betiği awkdeğerlendirirsed

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

bu sayıların bir kısmını sayısal gösterimlerine dönüştürür.

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

Sed komut dosyasının ek satırları

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

özen -tys ve one hundred.

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

Son olarak, lider kaldırmak +s ve olmayan her şeyi +, *ya da rakam.

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

Yalnızca matematik ifadeleri kalır

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

ve içine sokulabilir bc.


4

Pyth, 79 76 75 68 bayt

7 bayt için @ETHproductions 'a teşekkür ederiz.

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

Temel olarak ilk önce 100 köşe kasasını kontrol eder, daha sonra girişin anlamını belirlemek ve değeri sonek ("-ty" ve "-teen"; " lv ", 12'de başka bir köşe durumudur). Önce girdiyi bir kelime listesine böler, sonra her birini bir değerle eşleştirir ve toplar.

Pythonic sözde kodunda:

                           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

Test odası


Python 3, 218 bayt

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("-"))))

Temel olarak Pyth cevabı ile aynı.


Konu dışı:

Hayata, evrene ve her şeye cevabın anlamlı bir versiyonunu keşfettim: çay susuz dallar. Vay canına, çay için özlenen dallar! Bunu kaç tane daha cevap verdiğinden emin değilim, ancak cevabım için girdi "çay susuz-dallar" ise çıktı 42'dir.


Paketlenmiş bir dize kullanarak yedi bayt kaydedebileceğinize inanıyorum . Çıktıyı kopyalayın ve "ontwthfofisiseeiniteel"bu programa yerleştirin.
ETHproductions

@ETHproductions Vay, teşekkürler! En son kontrol ettiğimde, ipin başında hala "ze" vardı ve paketleme işe yaramadı. Ben golf sonra bir kez daha kontrol etmedi. Tekrar, teşekkürler xD
busukxuan

@ETHproductions evet aslında yaptım, sözde kodun altında.
busukxuan

2

Python 3, 365 361 310 303 karakter

golfed

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

Ungolfed

 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

45 karakter daha kısa: 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(",")Ama gördüğüm gibi, n değişkenine atamadan çalışmalı, .index()doğrudan çağırın .
manatwork

7 karakter daha kısa: "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

StackExchange site motoru rahatsız edici bir alışkanlığa sahiptir: yorumlarda yayınlanan koda görünmez karakterler (U200C Sıfır Genişlikli Birleştirici ve U200B Sıfır Genişlik Alanı) ekler. Siz de kopyaladınız. Yayınınızı kaldırmak için düzenledim.
manatwork

2

Haskell, 252 231 bayt

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..])

Bu, "bir" ile "doksan dokuz" arasındaki tüm İngilizce numara adlarının bir listesini oluşturur ve ardından girişin dizinini arar. Eğer mevcut değilse, "yüz" kenar durumundayız, bu yüzden geri döner 100, aksi takdirde dizini döndürür.

Ungolfed

-- 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 karakter

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

Basit, her sayının bir listesini oluşturur ve dizini bulur.


1

Japt, 82 bayt

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

Her biri ¿yazdırılamaz bir karakterdir. Çevrimiçi test edin!

JS yanıtımı temel alır. Çıktının bir tamsayı olması gerekmiyorsa bir bayt çıkarın, çünkü bir dize ile tamamen aynı görünür.

Nasıl çalışır

+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, 214199 bayt

Her zaman olduğu gibi: bunun rekabet etmek için çok uzun olduğu ortaya çıktı, ama şimdi bittiğim için bunu göndermemek bir atık olurdu.

Belki de göz ardı ettiğim bu kadar golf oynamak için bariz bir yolu var mı?

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:''))

Test senaryoları için JSFiddle


1
Nasıl değiştirme hakkında fhiç 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:''))? Ayrıca, böyle bir işleve tek bir dize argümanı iletilebilir:s.indexOf`lv`
ETHproductions

@ETHproductions Harika, teşekkürler! JS'nin virgül operatörü olduğunu bilmiyordum ve dize geçişi için kısayol da gerçekten yararlı.
vvye

1

Perl, 158 bayt

@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

Komut satırından çalışır. iki giriş olarak yorumlanmasını durdurmak one hundrediçin girilmelidir "one hundred".

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.