Konwertuj ciąg cyfr ze słów na liczbę całkowitą


19

Konwertuj ciąg zawierający cyfry jako słowa na liczbę całkowitą, ignorując początkowe zera.

Przykłady

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

Założenia

Zgłoszenia mogą zakładać, że:

  1. Łańcuch wejściowy składa się z cyfr oddzielonych spacjami.
  2. Wszystkie słowa są poprawne (w zakresie „zero” .. „dziewięć”) i małe litery. Zachowanie pustych danych wejściowych jest niezdefiniowane.
  3. Łańcuch wejściowy zawsze reprezentuje liczbę bez znaku w zakresie inti nigdy nie jest łańcuchem pustym.

Punktacja

Odpowiedzi będą oceniane w bajtach, przy czym mniej bajtów będzie lepszych.


3
Witamy na stronie. Jest kilka rzeczy, których zwykle oczekujemy od pytań, których tutaj brakuje. Najważniejsze byłoby obiektywne kryterium punktacji, które muszą mieć wszystkie wyzwania.
Wheat Wizard

3
Poza tym pytanie to jest bardzo rzadkie w specyfikacji. Powinieneś dokładnie określić, co jest wymagane od zgłoszeń bez dwuznaczności. Jedno zdanie i przykład po prostu nie odpowiadają naszym standardom jasności dotyczącym wyzwań.
Wheat Wizard

3
Oprócz tego, co zostało już powiedziane, mamy piaskownicę, w której użytkownicy mogą publikować swoje wyzwania przed wysłaniem ich do głównego. W ten sposób będziesz tracić mniej informacji podczas publikowania postów. Jeśli spojrzysz na inne ostatnie posty na stronie z dość pozytywnym odbiorem, myślę, że zobaczysz, że zarówno twoje pytanie, jak i rozwiązanie nie są zgodne z tym, co tutaj robimy.
FryAmTheEggman

3
Ryzykując pedantyczność, chciałbym zauważyć, że range "zero".."nine"nie jest to w pełni określone.
Niepowiązany ciąg

4
Irytujące jest to, że wbudowane Interpreter@"SemanticNumber"robi to dokładnie w Mathematica - z tym wyjątkiem, że zawodzi na ciągach zaczynających się od zero zero .
Greg Martin

Odpowiedzi:


22

PHP , 74 bajty

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

Wypróbuj online!

Próbowałem znaleźć rozwiązanie, które nie kopiuje istniejących odpowiedzi. Dostaję cykliczną redundancję sumy kontrolnej wielomianu 32-bitowych długości ( crc32 ) dla każdego słowa, a następnie robię na nim mod 20 i mod 11, aby uzyskać pomieszane unikalne wartości od 0 do 10 (brak 6) dla każdej cyfry. Następnie za pomocą tej unikalnej wartości znajduję rzeczywistą cyfrę.

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

Kolejna 74 bajtowa alternatywa CRC32 przy użyciu %493%10:Wypróbuj online!

Kolejna 74 bajtowa alternatywa CRC32 z wykorzystaniem %2326%11: Wypróbuj online!


PHP , 74 bajty

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

Wypróbuj online!

Inna alternatywa o tej samej długości, bierze 22 znak md5tego słowa (jedyny znak, który daje unikalną wartość dla każdego słowa), a następnie używa tego znaku do mapowania na cyfrę.


To fajna odpowiedź
Juan Sebastian Lozano



6

Galaretka ,  19  17 bajtów

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

Monadyczny link akceptujący listę znaków, który daje liczbę całkowitą.

Wypróbuj online!

Prawie port mojej odpowiedzi w Pythonie 2.


Poprzedni

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

Wypróbuj online!

Być może istnieje krótsza droga, ale ta właśnie przyszła mi do głowy.


Usunięcie zera z łańcucha enklact, aby uniknąć zmniejszenia, ponieważ nie znaleziono, to zero w każdym razie ... sprytne!
Niepowiązany ciąg

1
Ach, widzę, że zastosowałeś tę samą metodę.
Jonathan Allan

5

Python 3 , 107 , 91 , 77 , 90 bajtów

-16 bajtów autorstwa Sriotchilism O'Zaic

+13 bajtów, aby usunąć wiodące zera

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

Wypróbuj online!



Niezłe! W ten sposób mogę nawet całkowicie upuścić separator :)
movatica

1
W przypadku aktualizacji wyzwania nie jest to już ważne, ponieważ zawiera wiodące zera. :(
Wheat Wizard


1
@movatica Twoja poprawka jest nieprawidłowa. lstripMetoda paski każdy znak w łańcuchu, który jest podany jako argument, że to, więc „osiem dwa” staje się „rawo dwa”, jak „e” zostanie pozbawiony. Również „zero zero zero” powinno wypisać „0”, a nie dawać błędu.
NemPlayer

5

Perl 6 , 35 32 bajtów

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

Wypróbuj online!

Wyjaśnienie

{                              }  # 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 bajtów

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

Wypróbuj online!

Dzięki najmądrzejszym sztuczkom @Ceilingcat:

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

3

05AB1E , 18 16 bajtów

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

Wypróbuj online.

Wyjaśnienie:

#                 # 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)

Zobacz moją wskazówkę 05AB1E (sekcja Jak kompresować ciągi znaków nie będące częścią słownika? ), Aby zrozumieć, dlaczego tak .•ƒ/ÿßÇf•jest "rothuvsein".



3

05AB1E , 17 16 bajtów

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

Wypróbuj online!

Idealny remis z drugą odpowiedzią 05AB1E , ale z zupełnie innym podejściem.

•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 bajtów

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

^0+\B

Wypróbuj online! Link zawiera przypadki testowe. Wyjaśnienie:

\w+
¶$&$&$&

Umieść każde słowo w osobnej linii i potrój je.

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

Transliteruj siódmy znak każdego wiersza za pomocą ciągu @ UnrelatedString.

\D

Usuń wszystkie pozostałe znaki inne niż cyfry.

^0+\B

Usuń zera na początku (ale zostaw przynajmniej jedną cyfrę).

Poprzednie 46-bajtowe bardziej tradycyjne rozwiązanie:

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

^0+\B

Wypróbuj online! Link zawiera przypadki testowe. Wyjaśnienie:

T`z\wuxg`E

Słowa zero, two, four, sixi eightjednoznacznie zawierać litery zwuxg. Przetłumacz je na cyfry parzyste.

on
1
th
3
fi
5
se
7
ni
9

W przypadku cyfr nieparzystych wystarczy dopasować pierwsze dwie litery każdego słowa osobno.

\D

Usuń wszystkie pozostałe znaki inne niż cyfry.

^0+\B

Usuń zera na początku (ale zostaw przynajmniej jedną cyfrę).


2

Galaretka , 20 18 17 bajtów

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

Wypróbuj online!

-2 bajty od uruchomienia „rothuvsein” do kompresora ciągów user202729 .

-1 bajt od kradzieży łańcucha zerowego Jonathana Allana i umieszczenia go w programie o nieznacznie innej strukturze.

Ḳ                    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 bajtów

¸mg6 ì`Ψuv 

Spróbuj

Wygląda na to, że wszyscy inni pobili mnie do tego samego pomysłu - mógłbym zaoszczędzić sobie trudu pisania scenariusza, aby brutalnie wymusić optymalny ciąg znaków do kompresji, tylko po to, by to znaleźć, aż do indeksu 1,000,000(było wcześnie, nie miałem kofeina jeszcze!), „rothuvsein” to jedyny możliwy ciąg!

¸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"

Sprężone ciąg zawiera znaki na codepoints 206, 168, 117, 118, 160i 136.


1
... czy naprawdę próbowałeś do 1000000? Długość cm nazw cyfr wynosi 60, więc nie ma sensu próbować dalej (60 odpowiada 0, 61 do 1 itd.).
Grimmy

1
@Grimy, było wcześnie, nie miałem jeszcze kofeiny! Podłączenie miliona do skryptu, który napisałem, aby wygenerować wszystkie możliwości, było tak łatwe, jak każda inna liczba, i uratowało mi wykonywanie matematyki na LCM.
Shaggy


2

T-SQL, 110 bajtów

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

Podział linii służy wyłącznie do odczytu.

Dane wejściowe są pobierane za pomocą tabeli ja, zgodnie z naszymi zasadami IO . Mógłbym zapisać 14 bajtów, wypełniając wstępnie zmienną łańcuchową, ale jest to dozwolone tylko wtedy, gdy język nie ma innych metod wprowadzania.

Wyjaśnienie:

  1. STRING_SPLIT pobiera ciąg wejściowy i oddziela go w spacjach
  2. CHARINDEX pobiera pierwsze 2 znaki i zwraca pozycję (na podstawie 1) w ciągu '_ontwthfofisiseeini' .'ze'dla zera nie ma w ciągu i zwraca 0 dla „nie znaleziono”. Podkreślenie zapewnia, że ​​otrzymujemy tylko wielokrotności dwóch.
  3. Podziel przez 2, aby uzyskać końcową cyfrę
  4. STRING_AGG rozbija cyfry z powrotem bez separatora
  5. 0+wymusza niejawną konwersję na INT i usuwa wszelkie początkowe zera. 1*też by działał.

2

kod maszynowy x86, 46 bajtów

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

Jest to fastcallfunkcja - otrzymuje wskaźnik do łańcucha w ecxi zwraca wynikeax .

Funkcja haszująca mnoży się przez liczbę magiczną 1856645926, wykonuje aXOR bajt wejściowy i przesuwa się w prawo o 2 bity.

Zapisywanie i przywracanie rejestrów noclobber ( edii ebx) zajmowało 4 bajty, ale nie znalazłem bardziej wydajnego sposobu na wdrożenie tego. Przechowywanie stałej 10 ebxbyło szczególnie denerwujące!

Demontaż z odpowiednimi bajtami kodu:

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

Równoważny kod C:

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

Jak znalazłeś magiczne liczby?
Sparkler

Przeprowadziłem wyszukiwanie przy użyciu mojego kodu C - wypróbowałem wszystkie liczby 32-bitowe i wszystkie zmiany. Jest tylko kilka możliwości - kod znalazł tylko jedną z zakresu do 2000000000.
anatolyg

możesz użyć edx zamiast edi (push edx przed idiv, pop eax po nim, imul z ebx, dodaj eax do edx), aby zapisać jeden bajt.
Peter Ferrie



1

Węgiel drzewny , 19 bajtów

I⍘⭆⪪S §ι⁶rothuvsein

Wypróbuj online! Link jest do pełnej wersji kodu. Port z odpowiedzią 05AB1E @ KevinCruijssen. Wyjaśnienie:

    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 bajtów

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

Wypróbuj online!

Wykorzystuje tę samą rothuvseinsztuczkę, co inni, dzięki Jonathanowi Allanowi. Oczekuje argumentów wejściowych poprzez splatting, które w TIO przejawiają się jako osobne argumenty wiersza poleceń.


1

Kotlin, 83 bajty

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

+1 bajt, jeśli chcesz wspierać długie toLong()

Sama rothuvsein trik jak inni, oszczędzając cenne bajty dzięki Nicei Kotlin za toInt()i fold(). Po prostu nie mogę pozbyć się wrażenia, że ​​więcej bajtów można zgolić ...



1

Pakiet Windows, 169 bajtów

@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

VBA, 160 bajtów

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

Dopasowuje dwa pierwsze znaki w ciągu, z wyłączeniem zero.


0

BaCon , 83 72 bajty

Zakładając, że ciąg jest podany w w $, ten kod wyszukuje indeks w „zeontwthfofisiseeini” przy użyciu wyrażenia regularnego opartego na unikalnych pierwszych 2 znakach każdego słowa. Indeks jest następnie dzielony przez 2, zapewniając poprawny wynik.

FOR x$ IN w$:r=r*10+REGEX("zeontwthfofisiseeini",LEFT$(x$,2))/2:NEXT:?r
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.