Konvertiert eine Ziffernfolge von Wörtern in eine Ganzzahl

19

Konvertieren Sie eine Zeichenfolge, die Ziffern als Wörter enthält, in eine Ganzzahl, wobei führende Nullen ignoriert werden.

Beispiele

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

Annahmen

Einreichungen können davon ausgehen, dass:

  1. Die Eingabezeichenfolge besteht aus durch Leerzeichen getrennten Ziffernwörtern.
  2. Alle Wörter sind gültig (im Bereich "Null" .. "Neun") und in Kleinbuchstaben. Das Verhalten bei Leereingabe ist undefiniert.
  3. Die Eingabezeichenfolge stellt immer eine vorzeichenlose Zahl im Bereich von dar intund ist niemals eine leere Zeichenfolge.

Wertung

Antworten werden in Bytes bewertet, wobei weniger Bytes besser sind.

Wunderkerze
quelle
3
Willkommen auf der Seite. Es gibt ein paar Dinge, die wir normalerweise von Fragen erwarten, die hier fehlen. Das wichtigste wäre ein objektives Bewertungskriterium, das alle Herausforderungen haben müssen.
Weizen-Assistent
3
Abgesehen davon ist diese Frage sehr spärlich zu spezifizieren. Sie sollten genau angeben, was von Einsendungen ohne Mehrdeutigkeit verlangt wird. Ein Satz und ein Beispiel entsprechen einfach nicht unseren Klarheitsstandards für Herausforderungen.
Weizen-Assistent
3
Zusätzlich zu dem, was bereits gesagt wurde, haben wir eine Sandbox, in der Benutzer ihre Herausforderungen posten können, bevor sie sie an main senden. Auf diese Weise werden Sie beim Verfassen von Beiträgen weniger Informationen vermissen. Wenn Sie sich andere kürzlich veröffentlichte Beiträge auf der Website ansehen, die eine einigermaßen positive Resonanz erhalten, werden Sie feststellen, dass sowohl Ihre Frage als auch Ihre Lösung nicht ganz mit dem übereinstimmen, was wir hier tun.
FryAmTheEggman
3
Ich weise auf die Gefahr hin, pedantisch zu sein range "zero".."nine" nicht vollständig spezifiziert ist.
Unrelated String
4
Es ist ärgerlich, dass das Builtin Interpreter@"SemanticNumber"in Mathematica genau dies tut - außer dass es bei Zeichenfolgen fehlschlägt, die mit beginnen zero zero .
Greg Martin

Antworten:

22

PHP , 74 Bytes

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

Probieren Sie es online!

Es wurde versucht, eine Lösung zu finden, bei der vorhandene Antworten nicht kopiert werden. Ich erhalte ein zyklisches Redundanzprüfsummenpolynom mit einer Länge von 32 Bit ( crc32 ) für jedes Wort und führe dann eine Modifikation 20 und eine Modifikation 11 aus, um eindeutige Werte von 0 bis 10 (fehlende 6) für jede Ziffer zu mischen. Mit diesem eindeutigen Wert ermittle ich dann die tatsächliche Ziffer.

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

Weitere 74-Byte-CRC32-Alternative mit %493%10: Online testen !

Weitere 74-Byte-CRC32-Alternative mit %2326%11: Online!


PHP , 74 Bytes

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

Probieren Sie es online!

Eine andere Alternative mit der gleichen Länge nimmt das 22. Zeichen md5des Wortes (das einzige Zeichen, das für jedes Wort einen eindeutigen Wert angibt) und ordnet dieses Zeichen dann einer Ziffer zu.

Night2
quelle
Dies ist eine coole Antwort
Juan Sebastian Lozano
9

Python 2 ,  71-70  Bytes

-1 dank ovs ( findanstelle von index)

lambda s:int(''.join(`'rothuvsein'.find((w*3)[6])`for w in s.split()))

Probieren Sie es online!

Jonathan Allan
quelle
6

Jelly ,  19  17 Bytes

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

Ein monadischer Link, der eine Liste von Zeichen akzeptiert, die eine Ganzzahl ergibt.

Probieren Sie es online!

Ziemlich genau ein Port meiner Python 2-Antwort.


Bisherige

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

Probieren Sie es online!

Es ist sehr wahrscheinlich ein kürzerer Weg, aber dies ist ein Weg, die ersten Sinn kam zu.

Jonathan Allan
quelle
Entfernen von Null aus der Enklact-Zeichenfolge, um ein Dekrementieren zu vermeiden, da "Nicht gefunden" ohnehin Null ist ... clever!
Unrelated String
1
Ah, ich sehe, du hast die gleiche Methode angewendet, nett.
Jonathan Allan
5

Python 3 , 107 , 91 , 77 , 90 Bytes

-16 Bytes von Sriotchilism O'Zaic

+13 Bytes, um führende Nullen zu entfernen

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

Probieren Sie es online!

movatica
quelle
Schön! Auf diese Weise kann ich das Trennzeichen sogar ganz
weglassen
1
Mit den Aktualisierungen der Challenge ist diese nicht mehr gültig, da sie führende Nullen enthält. :(
Wheat Wizard
1
@movatica Dein Fix ist falsch. Die lstripMethode entfernt jedes Zeichen in der Zeichenfolge, die als Argument angegeben wird, sodass "acht zwei" zu "acht zwei" wird, während "e" entfernt wird. Außerdem sollte "null null null" "0" ausgeben und keinen Fehler ausgeben.
NemPlayer
5

Perl 6 , 35 32 Bytes

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

Probieren Sie es online!

Erläuterung

{                              }  # 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
nwellnhof
quelle
5

C (gcc) 89 Bytes

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

Probieren Sie es online!

Dank der cleversten Tricks von @Ceilingcat:

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

05AB1E , 18 16 Bytes

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

Probieren Sie es online aus.

Erläuterung:

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

Sehen Sie diese 05AB1E Spitze Mine (Abschnitt Wie Kompresse Strings nicht Teil des Wörterbuchs? ) Zu verstehen , warum .•ƒ/ÿßÇf•ist "rothuvsein".

Kevin Cruijssen
quelle
3

05AB1E , 17 16 Bytes

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

Probieren Sie es online!

Perfekte Verbindung mit der anderen 05AB1E-Antwort , aber mit einem völlig anderen Ansatz.

•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
Grimmig
quelle
3

Retina 0.8.2 , 46 45 Bytes

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

^0+\B

Probieren Sie es online! Link enthält Testfälle. Erläuterung:

\w+
¶$&$&$&

Setzen Sie jedes Wort in eine eigene Zeile und verdreifachen Sie es.

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

Transliterieren Sie das 7. Zeichen jeder Zeile mit der Zeichenfolge von @ UnrelatedString.

\D

Löschen Sie alle verbleibenden nichtstelligen Zeichen.

^0+\B

Führende Nullen löschen (aber mindestens eine Ziffer belassen).

Bisherige 46-Byte-Lösung:

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

^0+\B

Probieren Sie es online! Link enthält Testfälle. Erläuterung:

T`z\wuxg`E

Die Worte zero, two, four, sixund eightenthalten eindeutig die Buchstaben zwuxg. Transkribieren Sie diese in die geraden Ziffern.

on
1
th
3
fi
5
se
7
ni
9

Für die ungeraden Ziffern passen Sie einfach die ersten beiden Buchstaben jedes Wortes einzeln an.

\D

Löschen Sie alle verbleibenden nichtstelligen Zeichen.

^0+\B

Führende Nullen löschen (aber mindestens eine Ziffer belassen).

Neil
quelle
2

Jelly , 20 18 17 Bytes

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

Probieren Sie es online!

-2 Bytes vom Ausführen von "rothuvsein" durch den String-Kompressor von user202729 .

-1 Byte davon, Jonathan Allans nullfreien Enklact-String gestohlen und in ein geringfügig anders strukturiertes Programm eingefügt zu haben.

Ḳ                    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.
Nicht verwandte Zeichenfolge
quelle
2

C ++ (gcc) , 478 218 142 Bytes

- (sehr) danke an Jo King

int f(string s){char c[]="N02K8>IE;6";int i=0,n=0;while(s[i]){n=n*10-1;while((s[i]^s[i+1])+47!=c[++n%10]);while(s[i++]!=' '&&s[i]);}return n;}

Probieren Sie es online!

Wunderkerze
quelle
1
127 Bytes
Ceilingcat
2

Japt , 13 Bytes

¸mg6 ì`Ψuv 

Versuch es

Sieht aus wie alle auf die gleiche Idee hat mich sonst - selbst die Mühe , ein Skript zu Brute - Force des Schreibens die optimale Saite für die Kompression gespeichert haben könnte, nur das zu finden, die bis zu Index 1,000,000(es früh war, ich hatte nicht meine Koffein noch!), "rothuvsein" ist die einzig mögliche Saite!

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

Die komprimierte Zeichenfolge enthält die Zeichen in Codepoints 206, 168, 117, 118, 160und 136.

Zottelig
quelle
1
... hast du wirklich bis 1000000 probiert? Der lcm der Länge der Ziffernnamen ist 60, es macht also keinen Sinn, es darüber hinaus zu versuchen (60 entspricht 0, 61 bis 1 usw.).
Grimmy
1
@Grimy, es war früh, ich hatte noch kein Koffein! Eine Million in das Skript einzustecken, das ich geschrieben habe, um alle Möglichkeiten zu generieren, war so einfach wie jede andere Zahl und ersparte mir das Rechnen mit dem LCM.
Shaggy
2

Ruby , 63 Bytes , 52 Bytes , 50 Bytes

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

-2 dank Wert Schwärze Spitze

Gequält
quelle
Willkommen bei Code Golf! In Ruby $*ist dies ein Alias ​​für. Sie ARGVkönnen ihn also verwenden, um zusätzliche Bytes zu sparen.
Value Ink
2

T-SQL, 110 Bytes

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

Zeilenumbruch dient nur der Lesbarkeit.

Die Eingabe erfolgt über die Tabelle ich, Je unseren IO Regeln . Ich hätte 14 Bytes einsparen können, indem ich eine Zeichenfolgenvariable vorab aufgefüllt hätte, aber das ist nur zulässig, wenn die Sprache keine anderen Eingabemethoden hat.

Erläuterung:

  1. STRING_SPLIT Nimmt die Eingabezeichenfolge und trennt sie an den Leerzeichen
  2. CHARINDEXNimmt die ersten 2 Zeichen und gibt die (1-basierte) Position in der Zeichenfolge zurück '_ontwthfofisiseeini'.'ze'for zero ist nicht in der Zeichenfolge und gibt 0 für "not found" zurück. Der Unterstrich stellt sicher, dass wir nur ein Vielfaches von zwei erhalten.
  3. Teilen Sie durch 2, um die endgültige Zahl zu erhalten
  4. STRING_AGG Zerschmettert die Ziffern ohne Trennzeichen
  5. 0+Erzwingt eine implizite Konvertierung in INT und löscht alle führenden Nullen. 1*würde auch funktionieren.
BradC
quelle
2

x86-Maschinencode, 46 Byte

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

Es ist eine fastcallFunktion - empfängt einen Zeiger auf den String in ecxund gibt das Ergebnis in zurück eax.

Die Hash - Funktion vervielfacht durch eine magische Zahl 1856645926, tut einXOR mit dem Eingabebyte und verschiebt sich um 2 Bits nach rechts.

Das Speichern und Wiederherstellen von Noclobber-Registern ( ediund ebx) dauerte 4 Byte, aber ich fand keinen effizienteren Weg, dies zu implementieren. Speichern der Konstante 10 inebx war besonders ärgerlich!

Demontage mit entsprechenden Code-Bytes:

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

Äquivalenter C-Code:

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;
}
anatolyg
quelle
Wie haben Sie die magischen Zahlen gefunden?
Wunderkerze
Ich habe mit meinem C-Code gesucht und alle 32-Bit-Zahlen und alle Schichten ausprobiert. Es gibt nur wenige Möglichkeiten - der Code hat nur eine im Bereich bis 2000000000 gefunden.
Anatolyg
Sie können edx anstelle von edi verwenden (push edx vor dem idiv, pop eax danach, imul mit ebx, add eax to edx), um ein Byte zu speichern.
Peter Ferrie
1

Holzkohle , 19 Bytes

I⍘⭆⪪S §ι⁶rothuvsein

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Port von @ KevinCruijssens 05AB1E Antwort. Erläuterung:

    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
Neil
quelle
1

PowerShell , 48 Byte

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

Probieren Sie es online!

Verwendet den gleichen rothuvseinTrick wie andere, dank Jonathan Allan. Erwartet Eingabeargumente über Splatting, das sich in TIO als separate Befehlszeilenargumente manifestiert.

AdmBorkBork
quelle
1

Kotlin, 83 Bytes

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

+1 Byte, wenn Sie Longs mit unterstützen möchten toLong()

Gleicher rothuvsein Trick wie die anderen, spart dank kotlins nettem toInt()und ein paar wertvolle Bytes fold(). Ich kann das Gefühl nicht loswerden, dass noch mehr Bytes entfernt werden können ...

Alex Papageorgiou
quelle
1

sed -re , 78 Bytes

s/three/3/g;s/five/5/g;s/\w\w(\w)\w*/\1/g;s/ //g;y/eouxvgnr/12467890/;s/^0*//
Herzausrufezeichen
quelle
1

Windows Batch, 169 Bytes

@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%
Peter Ferrie
quelle
0

VBA, 160 Bytes

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

Entspricht den ersten beiden Zeichen einer Zeichenfolge, ohne Null.

user3819867
quelle
0

BaCon , 83 72 Bytes

Unter der Annahme, dass die Zeichenfolge in w $ angegeben ist, sucht dieser Code den Index in "zeontwthfofisiseeini" mit einem regulären Ausdruck, der auf den eindeutigen ersten beiden Zeichen jedes Wortes basiert. Der Index wird dann durch 2 geteilt, um das richtige Ergebnis zu erhalten.

FOR x$ IN w$:r=r*10+REGEX("zeontwthfofisiseeini",LEFT$(x$,2))/2:NEXT:?r
Peter
quelle