Chuyển đổi một chuỗi các chữ số từ các từ thành một số nguyên


19

Chuyển đổi một chuỗi chứa các chữ số dưới dạng các từ thành một số nguyên, bỏ qua các số 0 đứng đầu.

Ví dụ

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

Giả định

Đệ trình có thể giả định rằng:

  1. Chuỗi đầu vào bao gồm các từ chữ số được phân tách bằng dấu cách.
  2. Tất cả các từ đều hợp lệ (trong phạm vi "không" .. "chín") và chữ thường. Hành vi cho đầu vào trống rỗng là không xác định.
  3. Chuỗi đầu vào luôn đại diện cho một số không dấu trong phạm vi intvà không bao giờ là một chuỗi trống.

Chấm điểm

Câu trả lời sẽ được tính bằng byte với ít byte hơn.


3
Chào mừng đến với trang web. Có một vài điều mà chúng ta thường mong đợi từ những câu hỏi còn thiếu ở đây. Điều quan trọng nhất sẽ là một tiêu chí chấm điểm khách quan mà tất cả các thử thách phải có.
Thuật sĩ lúa mì

3
Bên cạnh đó, câu hỏi này rất ít về đặc điểm kỹ thuật. Bạn nên xác định chính xác những gì được yêu cầu của bài nộp mà không mơ hồ. Một câu và một ví dụ không theo tiêu chuẩn rõ ràng của chúng tôi cho các thách thức.
Thuật sĩ lúa mì

3
Ngoài những gì đã được nói, chúng tôi có một hộp cát nơi người dùng có thể đăng các thử thách của họ trước khi đăng chúng lên chính. Bằng cách đó bạn sẽ bỏ lỡ ít thông tin hơn khi thực hiện bài viết. Nếu bạn xem các bài đăng gần đây khác trên trang web với sự tiếp nhận hợp lý tích cực, tôi nghĩ bạn sẽ thấy rằng cả câu hỏi và giải pháp của bạn đều không phù hợp với những gì chúng tôi làm ở đây.
FryAmTheEggman

3
Có nguy cơ bị phạm tội, tôi muốn chỉ ra rằng điều đó range "zero".."nine"không được chỉ định đầy đủ.
Chuỗi không liên quan

4
Khó chịu, phần dựng sẵn Interpreter@"SemanticNumber"thực hiện chính xác điều này trong Mathicala, ngoại trừ việc nó bị lỗi trên chuỗi bắt đầu bằng zero zero .
Greg Martin

Câu trả lời:


22

PHP , 74 byte

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

Hãy thử trực tuyến!

Đã cố gắng để có được một giải pháp mà không sao chép câu trả lời hiện có. Tôi nhận được đa thức kiểm tra dự phòng chu kỳ có độ dài 32 bit ( crc32 ) cho mỗi từ và sau đó thực hiện một mod 20 và mod 11 trên đó để có được các giá trị duy nhất từ ​​0 đến 10 (thiếu 6) cho mỗi chữ số. Sau đó, sử dụng giá trị duy nhất đó tôi tìm thấy chữ số thực tế.

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

Một thay thế CRC32 74 byte khác bằng cách sử dụng %493%10: Dùng thử trực tuyến!

Một thay thế CRC32 74 byte khác bằng cách sử dụng %2326%11: Dùng thử trực tuyến!


PHP , 74 byte

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

Hãy thử trực tuyến!

Một cách khác có cùng độ dài, lấy ký tự thứ 22 trong md5từ (chỉ ký tự mang lại giá trị duy nhất cho mỗi từ) và sau đó sử dụng ký tự đó để ánh xạ thành một chữ số.


Đây là một câu trả lời thú vị
Juan Sebastian Lozano



6

Thạch ,  19  17 byte

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

Một liên kết đơn thể chấp nhận một danh sách các ký tự mang lại một số nguyên.

Hãy thử trực tuyến!

Khá nhiều cổng của câu trả lời Python 2 của tôi.


Trước

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

Hãy thử trực tuyến!

thể có một cách ngắn hơn, nhưng đây là cách đầu tiên bạn nghĩ đến.


Loại bỏ số 0 khỏi chuỗi enklact để tránh giảm dần, vì không tìm thấy là số 0 dù sao đi nữa ... thông minh!
Chuỗi không liên quan

1
Ah tôi thấy bạn đã làm phương pháp tương tự, tốt đẹp.
Jonathan Allan

5

Python 3 , 107 , 91 , 77 , 90 byte

-16 byte bởi Sriotchilism O'Z cổ

+13 byte để loại bỏ các số 0 hàng đầu

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

Hãy thử trực tuyến!



Đẹp quá Bằng cách đó, tôi thậm chí có thể bỏ hoàn toàn dấu phân cách :)
Movatica

1
Với các bản cập nhật cho thử thách, điều này không còn hợp lệ vì nó bao gồm các số 0 đứng đầu. :(
Thuật sĩ lúa mì


1
@movatica Khắc phục của bạn không chính xác. Các lstripphương pháp dải mỗi nhân vật trong chuỗi mà được cho là nó lập luận, vì vậy "tám hai" trở thành "ight hai", là "e" bị tước. Ngoài ra, "zero zero zero" sẽ in ra "0", không đưa ra lỗi.
NemPlayer

5

Perl 6 , 35 32 byte

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

Hãy thử trực tuyến!

Giải trình

{                              }  # 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 byte

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

Hãy thử trực tuyến!

Nhờ các thủ thuật thông minh nhất @Czingcat:

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

3

05AB1E , 18 16 byte

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

Hãy thử trực tuyến.

Giải trình:

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

Xem 05AB1E mẹo này của tôi (phần Làm thế nào để chuỗi nén không nằm trong từ điển? ) Để hiểu tại sao .•ƒ/ÿßÇf•"rothuvsein".



3

05AB1E , 17 16 byte

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

Hãy thử trực tuyến!

vạt hoàn hảo với câu trả lời 05AB1E khác , nhưng sử dụng một cách tiếp cận hoàn toàn khác.

•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

Võng mạc 0.8.2 , 46 45 byte

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

^0+\B

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. Giải trình:

\w+
¶$&$&$&

Đặt mỗi từ trên dòng riêng của nó và ba lần nó.

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

Chuyển ngữ ký tự thứ 7 của mỗi dòng bằng chuỗi @ UnrelatedString.

\D

Xóa tất cả các ký tự không có chữ số còn lại.

^0+\B

Xóa các số 0 đứng đầu (nhưng để lại ít nhất một chữ số).

Giải pháp truyền thống hơn 46 byte trước đây:

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

^0+\B

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. Giải trình:

T`z\wuxg`E

Những lời zero, two, four, sixeightduy nhất chứa các chữ cái zwuxg. Chuyển từ những chữ số chẵn

on
1
th
3
fi
5
se
7
ni
9

Đối với các chữ số lẻ, chỉ cần ghép hai chữ cái đầu tiên của mỗi từ riêng lẻ.

\D

Xóa tất cả các ký tự không có chữ số còn lại.

^0+\B

Xóa các số 0 đứng đầu (nhưng để lại ít nhất một chữ số).


2

Thạch , 20 18 17 byte

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

Hãy thử trực tuyến!

-2 byte từ việc chạy "rothuvsein" thông qua máy nén chuỗi của user202729 .

-1 byte từ việc đánh cắp chuỗi enklact không miễn phí của Jonathan Allan và đưa nó vào một chương trình có cấu trúc khác biệt.

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

¸mg6 ì`Ψuv 

Thử nó

Có vẻ như mọi người khác đánh bại tôi theo cùng một ý tưởng - có thể đã tự cứu mình khỏi rắc rối khi viết một kịch bản để buộc chuỗi tối ưu để nén, chỉ để thấy rằng, lên chỉ mục 1,000,000(đó là sớm, tôi đã không có caffeine chưa!), "rothuvsein" là chuỗi duy nhất có thể!

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

Chuỗi nén chứa các ký tự ở codepoints 206, 168, 117, 118, 160& 136.


1
... bạn đã thực sự thử tới 1000000 chưa? Độ dài lcm của độ dài của tên chữ số là 60, vì vậy không có điểm nào cố gắng vượt quá (60 tương đương với 0, 61 đến 1, v.v.).
Grimmy

1
@Grimy, còn sớm, tôi chưa có cafein! Việc cắm một triệu vào kịch bản mà tôi đã viết để tạo ra tất cả các khả năng cũng dễ như mọi số khác và giúp tôi tiết kiệm khi làm toán trên LCM.
Xù xì

2

Ruby , 63 byte , 52 byte , 50 byte

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

-2 nhờ vào giá trị mực của đỉnh


Chào mừng bạn đến với Code Golf! Trong Ruby, $*là một bí danh cho ARGV, vì vậy hãy sử dụng nó để tiết kiệm thêm byte.
Mực giá trị

2

T-SQL, 110 byte

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

Ngắt dòng chỉ dành cho khả năng đọc.

Đầu vào được lấy qua bảng Tôi, theo quy tắc IO của chúng tôi . Tôi có thể đã lưu 14 byte bằng cách điền trước một biến chuỗi, nhưng điều đó chỉ được phép nếu ngôn ngữ không có các phương thức nhập khác.

Giải trình:

  1. STRING_SPLIT lấy chuỗi đầu vào và phân tách nó tại khoảng trắng
  2. CHARINDEXnhận 2 ký tự đầu tiên và trả về vị trí (dựa trên 1) trong chuỗi '_ontwthfofisiseeini'.'ze'cho số 0 không có trong chuỗi và trả về 0 cho "không tìm thấy". Gạch dưới đảm bảo chúng tôi chỉ nhận được bội số của hai.
  3. Chia cho 2 để có được chữ số cuối cùng
  4. STRING_AGG đập các chữ số lại với nhau mà không có dấu phân cách
  5. 0+buộc chuyển đổi ngầm thành INT và giảm bất kỳ số 0 đứng đầu nào. 1*cũng sẽ làm việc

2

mã máy x86, 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

Đó là một fastcallhàm - nhận một con trỏ tới chuỗi trong ecxvà trả về kết quả eax.

Hàm băm nhân với một số ma thuật 1856645926, thực hiện XORvới byte đầu vào và dịch chuyển sang phải 2 bit.

Việc lưu và khôi phục các thanh ghi noclobber ( ediebx) mất 4 byte, nhưng tôi không tìm thấy cách nào hiệu quả hơn để thực hiện điều này. Lưu trữ liên tục 10 trong ebxlà đặc biệt khó chịu!

Tháo gỡ với các byte mã tương ứng:

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

Mã C tương đương:

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

Làm thế nào bạn tìm thấy những con số ma thuật?
Sparkler

Tôi đã thực hiện tìm kiếm bằng mã C của mình - đã thử tất cả các số 32 bit và tất cả các ca. Chỉ có một vài khả năng - mã chỉ tìm thấy một trong phạm vi lên tới 2000000000.
anatolyg

bạn có thể sử dụng edx thay vì edi (đẩy edx trước idiv, pop eax sau nó, imul với ebx, thêm eax vào edx) để lưu một byte.
perr ferrie



1

Than , 19 byte

I⍘⭆⪪S §ι⁶rothuvsein

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Câu trả lời 05AB1E của cảng @ KevinCruijssen. Giải trình:

    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 byte

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

Hãy thử trực tuyến!

Sử dụng rothuvseinmánh khóe giống như những người khác, nhờ Jonathan Allan. Yêu cầu các đối số đầu vào thông qua việc ghép nối, trên TIO biểu hiện dưới dạng các đối số dòng lệnh riêng biệt.


1

Kotlin, 83 byte

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

+1 byte nếu bạn muốn hỗ trợ lâu dài với toLong()

Cùng lừa rothuvsein như những người khác, tiết kiệm một số byte quý giá nhờ sự tốt đẹp của kotlin toInt()fold(). Tôi chỉ không thể lay chuyển được cảm giác rằng một số byte có thể bị loại bỏ mặc dù ...



1

Batch Windows, 169 byte

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

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

Khớp hai ký tự đầu tiên trong một chuỗi, không loại trừ.


0

BaCon , 83 72 byte

Giả sử chuỗi được cung cấp bằng w $, mã này tìm kiếm chỉ mục trong "zeontwthfofisiseeini" bằng cách sử dụng biểu thức chính quy dựa trên 2 ký tự đầu tiên duy nhất của mỗi từ. Chỉ số sau đó được chia cho 2 cung cấp kết quả chính xác.

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