Bir rakam dizesini kelimelerden bir tam sayıya dönüştürme


19

Sayıları içeren bir dizeyi, baştaki sıfırları yok sayarak bir tam sayıya dönüştürün.

Örnekler

  • "four two"-> 42.
  • "zero zero zero one"-> 1.

Varsayımlar

Başvurular şunları kabul edebilir:

  1. Giriş dizesi, boşlukla ayrılmış rakam sözcüklerinden oluşur.
  2. Tüm kelimeler geçerlidir ("sıfır" .. "dokuz" aralığında) ve küçük harftir. Boş girdi için davranış tanımlanmamış.
  3. Giriş dizesi her zaman için işaretsiz bir sayıyı temsil eder intve asla boş bir dize değildir.

puanlama

Yanıtlar daha az bayt daha iyi olacak şekilde bayt cinsinden puanlanacaktır.


3
Siteye hoş geldiniz. Burada eksik olan sorulardan genellikle beklediğimiz birkaç şey var. En önemlisi, tüm zorlukların sahip olması gereken objektif bir puanlama ölçütü olacaktır.
Rock Garf Hunter Post

3
Bunun dışında bu soru şartname üzerinde çok seyrek. Belirsizlik olmadan gönderilen gönderilerin tam olarak ne gerektiğini belirtmelisiniz. Bir cümle ve bir örnek sadece zorluklar için netlik standartlarımıza bağlı değildir.
Rock Garf Hunter Post

3
Daha önce söylenenlerin ötesinde , kullanıcıların zorluklarını anaya göndermeden önce gönderebilecekleri bir sanal alanımız var . Bu şekilde yayın yaparken daha az bilgi kaçırırsınız. Sitedeki diğer son yazılara makul bir resepsiyonla bakarsanız, hem sorunuzun hem de çözümünüzün burada yaptığımızla oldukça uyumlu olmadığını göreceksiniz.
FryAmTheEggman

3
Bilgiçlikçi olma riski altında range "zero".."nine", bunun tam olarak belirtilmediğini belirtmek isterim .
İlgisiz String

4
Can sıkıcı bir şekilde, yerleşik Interpreter@"SemanticNumber"tam olarak Mathematica'da bunu yapar - ancak, başlangıçta dizelerde başarısız olur zero zero .
Greg Martin

Yanıtlar:


22

PHP , 74 bayt

foreach(explode(' ',$argn)as$w)$n.='793251_8640'[crc32($w)%20%11];echo+$n;

Çevrimiçi deneyin!

Mevcut cevapları kopyalamayan bir çözüm bulmaya çalıştım. Her sözcük için 32 bit uzunluklu ( crc32 ) döngüsel artıklık sağlama toplamı polinomu alıyorum ve daha sonra her bir basamak için 0'dan 10'a (6 eksik) benzersiz değerleri karıştırmak için bir mod 20 ve mod 11 yapıyorum. Sonra bu benzersiz değeri kullanarak gerçek rakamı bulurum.

| Word  | CRC32      | %20 | %11 | Equivalent digit |
|-------|------------|-----|-----|------------------|
| zero  | 2883514770 | 10  | 10  | 0                |
| one   | 2053932785 | 5   | 5   | 1                |
| two   | 298486374  | 14  | 3   | 2                |
| three | 1187371253 | 13  | 2   | 3                |
| four  | 2428593789 | 9   | 9   | 4                |
| five  | 1018350795 | 15  | 4   | 5                |
| six   | 1125590779 | 19  | 8   | 6                |
| seven | 2522131820 | 0   | 0   | 7                |
| eight | 1711947398 | 18  | 7   | 8                |
| nine  | 2065529981 | 1   | 1   | 9                |

Başka bir 74 bayt CRC32 alternatif kullanarak %493%10: Çevrimiçi deneyin!

Başka bir 74 bayt CRC32 alternatif kullanarak %2326%11: Çevrimiçi deneyin!


PHP , 74 bayt

foreach(explode(' ',$argn)as$w)$n.=strpos(d07bfe386c,md5($w)[21]);echo+$n;

Çevrimiçi deneyin!

Aynı uzunluğa sahip başka bir alternatif md5, sözcüğün 22. karakterini alır (yalnızca her sözcük için benzersiz bir değer veren karakter) ve bu karakteri bir basamağa eşlemek için kullanır.


Bu harika bir cevap
Juan Sebastian Lozano



6

Jöle ,  19  17 bayt

Ḳµ7ị“*;nÄƲ]³Ṙ»i)Ḍ

Bir tamsayı veren karakterlerin listesini kabul eden monadik bir Bağlantı.

Çevrimiçi deneyin!

Python 2 cevabımın hemen hemen bir limanı.


Önceki

ḲŒ¿€i@€“©¥q£½¤MÆÑ‘Ḍ

Çevrimiçi deneyin!

Orada büyük olasılıkla daha kısa bir yol, ama bu ilk akla gelen bir yoludur.


Azalıştan kaçınmak için enklact dizesinden sıfır kaldırılması, çünkü bulunamadı her durumda sıfırdır ... zekice!
İlişkisiz String

1
Ah aynı yöntemi yaptığınızı görüyorum, güzel.
Jonathan Allan

5

Python 3 , 107 , 91 , 77 , 90 bayt

-16 bayt Sriotchilism O'Zaic tarafından

Baştaki sıfırları kaldırmak için +13 bayt

lambda s:int(''.join(map(lambda w:str('zeontwthfofisiseeini'.index(w[:2])//2),s.split())))

Çevrimiçi deneyin!



Güzel! Bu şekilde, sınırlayıcıyı tamamen bırakabilirim :)
movatica

1
Meydan okuma güncellemeleri ile bu, artık sıfır içerdiğinden artık geçerli değil. :(
Post Rock Garf Hunter


1
@movatica Düzeltmeniz yanlış. lstripYöntem böylece "sekiz iki" "e" elimden alır gibi, "ight iki" olur, 's argüman olarak verilir dize her karakter şeritler. Ayrıca, "sıfır sıfır sıfır" hata vermemek için "0" yazmalıdır.
NemPlayer

5

Perl 6 , 35 32 bayt

{+uniparse 'SP'~S:g/<</,DIGIT /}

Çevrimiçi deneyin!

açıklama

{                              }  # Anonymous block
                S:g/<</,DIGIT /   # Insert ",DIGIT " at
                                  # left word boundaries
           'SP'~  # Prepend 'SP' for space
  uniparse  # Parse list of Unicode names into string
 +  # Convert to integer

5

C (gcc) , 89 bayt

i,n;f(char*w){for(i=n=0;n=*w%32?n^*w:(i+=n-2)&&!printf(L"8 0  72 3  59641"+n%17),*w++;);}

Çevrimiçi deneyin!

@Ceilingcat akıllı hileleri sayesinde:

- printf instead of putchar.   
- !printf instead of printf()&0. 
- And wide char !

3

05AB1E , 18 16 bayt

#ε6è}.•ƒ/ÿßÇf•Åβ

Çevrimiçi deneyin.

Açıklama:

#                 # Split the (implicit) input-string on spaces
 ε  }             # Map each string to:
  6è              #  Get the character at 0-based index 6 (with automatic wraparound)
     .•ƒ/ÿßÇf    # Push compressed string "rothuvsein"
              Åβ  # Convert the characters from custom base-"rothuvsein" to an integer
                  # (after which the top of the stack is output implicitly as result)

Bu 05AB1E madenin ucu bakın (bölüm kompres dizeleri sözlükte parçası olmayan nasıl? ) Anlamak için .•ƒ/ÿßÇf•olduğunu "rothuvsein".



3

05AB1E , 17 16 bayt

•D±¾©xWÄ0•I#HèTβ

Çevrimiçi deneyin!

Diğer 05AB1E cevabı ile mükemmel bir bağ , ancak tamamen farklı bir yaklaşım kullanarak.

•D±¾©xWÄ0•               # compressed integer 960027003010580400
          I#             # split the input on spaces
            H            # convert each word from hex (eg "one" => 6526)
             è           # index (with wrap-around) into the digits of the large integer
              Tβ         # convert from base 10 to integer

3

Retina 0.8.2 , 46 45 bayt

\w+
¶$&$&$&
%7=T`r\ot\huvs\ein`d`.
\D

^0+\B

Çevrimiçi deneyin! Bağlantı, test senaryolarını içerir. Açıklama:

\w+
¶$&$&$&

Her kelimeyi kendi satırına koyun ve üçe katlayın.

%7=T`r\ot\huvs\ein`d`.

@ UnrelatedString dizesini kullanarak her bir satırın 7. karakterini çevirin.

\D

Geriye kalan tüm rakam olmayan karakterleri silin.

^0+\B

Baştaki sıfırları silin (ancak en az bir basamak bırakın).

Önceki 46 baytlık daha geleneksel çözüm:

T`z\wuxg`E
on
1
th
3
fi
5
se
7
ni
9
\D

^0+\B

Çevrimiçi deneyin! Bağlantı, test senaryolarını içerir. Açıklama:

T`z\wuxg`E

Kelimeler zero, two, four, sixve eightbenzersiz harf içerirler zwuxg. Bunları çift haneli rakamlara çevirin.

on
1
th
3
fi
5
se
7
ni
9

Tek rakamlar için, her bir kelimenin ilk iki harfini ayrı ayrı eşleştirmeniz yeterlidir.

\D

Geriye kalan tüm rakam olmayan karakterleri silin.

^0+\B

Baştaki sıfırları silin (ancak en az bir basamak bırakın).


2

Jöle , 20 18 17 bayt

Ḳ7ị“*;nÄƲ]³Ṙ»iƲ€Ḍ

Çevrimiçi deneyin!

-2 çalışmasını bayt "rothuvsein" aracılığıyla user202729 dize kompresörünün .

Jonathan Allan'ın sıfırsız enklact dizesini çalmak ve onu marjinal olarak farklı bir programa koymaktan -1 bayt.

Ḳ                    Split the input on spaces,
              Ʋ€     for each word
             i       find the 1-based index (defaulting to 0)
   “*;nÄƲ]³Ṙ»        in "othuvsein"
 7ị                  of the element at modular index 7,
                Ḍ    and convert from decimal digits to integer.


2

Japt , 13 bayt

¸mg6 ì`Ψuv 

Dene

Herkes beni aynı fikre yendi gibi görünüyor - kendimi sıkıştırma için en uygun dizgiyi zorlamak için bir komut dosyası yazma zahmetinden kurtarabilirdim, sadece bunu bulmak için, endekse kadar 1,000,000(erken olmuştu, kafein henüz!), "rothuvsein" olası tek dize!

¸mg6 ì`...     :Implicit input of string
¸              :Split on spaces
 m             :Map
  g6           :  Character at index 6 (0-based, with wrapping)
     ì         :Convert from digit array in base
      `...     :  Compressed string "rothuvsein"

Sıkıştırılmış dize codepoints de karakterler içeriyor 206, 168, 117, 118, 160ve 136.


1
... gerçekten 1000000'ü denedin mi? Rakam adlarının uzunluklarının lcm'i 60'tır, bu yüzden bunun ötesinde denemenin bir anlamı yoktur (60, 0, 61 ila 1'e eşittir).
Grimmy

1
@Grimy, erken oldu, henüz kafein almamıştım! Tüm olasılıkları oluşturmak için yazdığım senaryoya bir milyonu eklemek, diğer herhangi bir sayı kadar kolaydı ve LCM'de matematik yaparken beni kurtardı.
Shaggy

2

Yakut , 63 bayt , 52 bayt , 50 bayt

p $*.map{|d|'rothuvsein'.index (d*3)[6]}.join.to_i

-2 sayesinde değer mürekkebin ucunda


Code Golf'e hoş geldiniz! Ruby'de, $*bir takma addır ARGV, bu nedenle ekstra bayt kaydetmek için bunu kullanmaktan çekinmeyin.
Değer Mürekkebi

2

T-SQL, 110 bayt

SELECT 0+STRING_AGG(CHARINDEX(LEFT(value,2),'_ontwthfofisiseeini')/2,'')
FROM STRING_SPLIT((SELECT*FROM i),' ')

Satır sonu yalnızca okunabilirlik içindir.

Giriş tablo üzerinden alınır ben, ES kurallarımıza göre . Bir dize değişkenini önceden doldurarak 14 bayt kaydedebilirdim, ancak bu yalnızca dilin başka giriş yöntemleri yoksa izin verilir.

Açıklama:

  1. STRING_SPLIT girdi dizesini alır ve boşluklardan ayırır
  2. CHARINDEXilk 2 karakteri alır ve dizedeki (1 tabanlı) konumunu döndürür '_ontwthfofisiseeini'. 'ze'sıfır için dizede değil ve "bulunamadı" için 0 döndürür. Alt çizgi, yalnızca ikinin katlarını almamızı sağlar.
  3. Son rakamı almak için 2'ye bölün
  4. STRING_AGG ayırıcı olmadan rakamları yeniden birleştirir
  5. 0+örtük bir dönüşümü INT'ye zorlar ve baştaki sıfırları bırakır. 1*de işe yarar.

2

x86 makine kodu, 46 bayt

HexDump:

57 53 33 c0 33 ff f6 01 0f 75 15 6a 0a 5b 99 f7
f3 6b ff 0a 03 fa 33 c0 38 01 75 0f 97 5b 5f c3
69 c0 26 2b aa 6e 32 01 c1 e8 02 41 eb d8

Bu bir fastcallişlevdir - dizeye bir işaretçi alır ecxve sonucu döndürür eax.

Karma işlevi sihirli bir sayı ile çarpılır 1856645926, XORgiriş baytı ile a yapar ve sağa 2 bit kayar.

Noclobber kayıtlarını kaydetme ve geri yükleme (edi ve ebx) 4 bayt aldı, ancak bunu uygulamak için daha etkili bir yol bulamadım. Sabit 10'u depolamak ebxözellikle sinir bozucuydu!

İlgili kod baytlarıyla sökme:

57                   push        edi  ; edi = result
53                   push        ebx  ; we use ebx to store the constant 10
33 C0                xor         eax,eax  
33 FF                xor         edi,edi  
    myloop:
F6 01 0F             test        byte ptr [ecx],0Fh  ; check for end of word
75 15                jne         myhash
6A 0A                push        0Ah  
5B                   pop         ebx  
99                   cdq              ; prepare 64-bit dividend in edx:eax
F7 F3                div         eax,ebx  ; find the remainder of division by 10
6B FF 0A             imul        edi,edi,0Ah
03 FA                add         edi,edx  ; update the result
33 C0                xor         eax,eax  ; reset the hash temporary variable
38 01                cmp         byte ptr [ecx],al  ; check for end of input (here al=0)
75 0F                jne         mycontinue
97                   xchg        eax,edi  ; set the return register
5B                   pop         ebx  ; restore registers
5F                   pop         edi  ; restore registers
C3                   ret  
    myhash:
69 C0 26 2B AA 6E    imul        eax,eax,6EAA2B26h  ; hashing...
32 01                xor         al,byte ptr [ecx]  ; hashing...
C1 E8 02             shr         eax,2  ; hashing...
    mycontinue:
41                   inc         ecx  ; next input byte
EB D8                jmp         myloop

Eşdeğer C kodu:

int doit(const char* s)
{
    int result = 0;
    unsigned temp = 0;
    while (true)
    {
        int c = *s++;
        if ((c & 15) == 0)
        {
            temp %= 10;
            result = result * 10 + temp;
            temp = 0;
            if (c == 0)
                break;
            else
                continue;
        }
        temp *= 1856645926;
        temp ^= c;
        temp >>= 2;
    }
    return result;
}

Sihirli sayıları nasıl buldun?
Maytap

C kodumu kullanarak bir arama yaptım - tüm 32 bit sayıları ve tüm vardiyaları denedim. Sadece birkaç olasılık var - kod 2000000000'e kadar sadece bir tane bulundu.
anatolyg

bir bayt kaydetmek için edi yerine edx kullanabilirsiniz (idiv'den önce edx'i itin, arkasından pop eax, ebx ile imul, edx'e eax ekleyin).
peter ferrie



1

VBA, 160 bayt

Function e(s)
s = Split(s, " ")
For i = LBound(s) To UBound(s)
s(i) = Int((InStr("ontwthfofisiseeini", Left(s(i), 2)) + 1) / 2)
Next
e = Val(Join(s, ""))
End Function

Bir dizgideki ilk iki karakterle eşleşir, sıfır hariç.


(1/3) Burada harika bir yaklaşım var, ancak yeni satırları bayt olarak saymayı başaramadığınız ve bazı hileler kullanırsanız bayt sayısını azaltabileceğiniz anlaşılıyor. Yani, decaler gerek yoktur " "içinde Splitolduğu varsayılan değer olarak, Lbound(s)her zaman sıfır olacak ve bırak (...)+1sen başına bir boşluk eklerseniz InStrveri. Bundan Asside, daha iyi veri çıkan tutarak işlemek için bir dize veya varyantını kullanarak kapalı InStrsen kullanımına ihtiyaç yok gibi deyimi (i)veya Join(s,""). Oh ve Int(a/b)aynı a\b.
Taylor Scott

(2/3) Bunları ve bir for eachdöngüyü kullanarak işlevinizi Function G(x):For Each c In Split(x):G=10*G+InStr(" ontwthfofisiseeini",Left(c,2))\2:Next:End Functionalt bayt olarak çıktıyı örtük pencereye yazdırdığı için 101 bayt veya 101 bayta kadar alabilirsiniz Sub F(x):For Each c In Split(x):v=10*v+InStr(" ontwthfofisiseeini",Left(c,2))\2:Next:Debug.?v:End Sub. Cevabınızı kısıtlarsanız Excel VBA anlık pencere işlevi olarak 81 bayta bile alabilirsiniz For Each c In Split([A1]):v=10*v+InStr(" ontwthfofisiseeini",Left(c,2))\2:Next:?v.
Taylor Scott

(3/3) Bu yaklaşımlar hakkında daha fazla bilgi için VBA Sayfasındaki Golf için İpuçları sayfamıza göz atmanızı şiddetle tavsiye ederim . Şerefe
Taylor Scott

1

Kömür , 19 bayt

I⍘⭆⪪S §ι⁶rothuvsein

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. Bağlantı noktası @ KevinCruijssen'in 05AB1E cevabı. Açıklama:

    S               Input string
   ⪪                Split on spaces
  ⭆                 Map over words and join
       ι            Current word
      §             Cyclically indexed
        ⁶           Literal `6`
 ⍘       rothuvsein Custom base conversion
I                   Cast to string for implicit print

1

PowerShell , 48 bayt

+-join($args|%{'rothuvsein'.indexof(($_*3)[6])})

Çevrimiçi deneyin!

rothuvseinJonathan Allan sayesinde diğerleriyle aynı hileyi kullanır . TIO'da ayrı komut satırı bağımsız değişkenleri olarak görünen sıçrama yoluyla girdi bağımsız değişkenlerini bekler.


1

Kotlin, 83 bayt

fun String.d()=split(' ').fold(""){a,b->a+"rothuvsein".indexOf((b+b+b)[6])}.toInt()

Uzun süreleri desteklemek istiyorsanız +1 bayt toLong()

Diğerleri ile aynı rothuvsein hilesi, kotlin'in güzel toInt()ve sayesinde değerli bayt tasarrufu fold(). Yine de bazı baytların tıraş edilebileceği hissini sallayamıyorum ...



1

Windows Toplu İş, 169 bayt

@setlocal enabledelayedexpansion
@set z=zeontwthfofisiseeini
:a
@set b=%1
@for /l %%c in (0,2,18)do @if "!b:~0,2!"=="!z:~%%c,2!" set/aa=a*10+%%c/2&shift&goto a
@echo %a%


0

BaCon , 83 72 bayt

Dizenin w $ olarak verildiğini varsayarsak, bu kod "zeontwthfofisiseeini" içindeki dizini, her kelimenin benzersiz ilk 2 karakterine dayanan normal bir ifade kullanarak arar. Daha sonra indeks, doğru sonuç verecek şekilde 2'ye bölünür.

FOR x$ IN w$:r=r*10+REGEX("zeontwthfofisiseeini",LEFT$(x$,2))/2:NEXT:?r
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.