แปลงสตริงตัวเลขจากคำเป็นจำนวนเต็ม


19

แปลงสตริงที่มีตัวเลขเป็นคำเป็นจำนวนเต็มโดยไม่คำนึงถึงศูนย์นำหน้า

ตัวอย่าง

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

สมมติฐาน

การส่งสามารถสันนิษฐานได้ว่า:

  1. สตริงอินพุตประกอบด้วยคำหลักที่คั่นด้วยช่องว่าง
  2. คำทั้งหมดใช้งานได้ (ในช่วง "ศูนย์" .. "เก้า") และตัวพิมพ์เล็ก พฤติกรรมสำหรับการป้อนข้อมูลที่ว่างเปล่าไม่ได้กำหนด
  3. สตริงอินพุตจะแทนตัวเลขที่ไม่ได้ลงนามในช่วงintและจะไม่เป็นสตริงว่างเสมอ

เกณฑ์การให้คะแนน

คำตอบจะได้คะแนนเป็นไบต์ด้วยจำนวนไบต์ที่น้อยลง


3
ยินดีต้อนรับสู่เว็บไซต์ มีสองสิ่งที่เรามักคาดหวังจากคำถามที่หายไปที่นี่ สิ่งที่สำคัญที่สุดคือเกณฑ์การให้คะแนนตามวัตถุประสงค์ซึ่งความท้าทายทั้งหมดจะต้องมี
ตัวช่วยสร้างข้าวสาลี

3
นอกเหนือจากนั้นคำถามนี้มีน้อยมากในรายละเอียด คุณควรระบุสิ่งที่จำเป็นสำหรับการส่งโดยไม่ต้องคลุมเครือ ประโยคเดียวและตัวอย่างไม่ได้ขึ้นอยู่กับมาตรฐานความชัดเจนของเราสำหรับความท้าทาย
ตัวช่วยสร้างข้าวสาลี

3
นอกเหนือจากที่กล่าวมาแล้วเรามีกล่องทรายที่ผู้ใช้สามารถโพสต์ความท้าทายของพวกเขาก่อนที่จะโพสต์ไว้ที่หน้าหลัก ด้วยวิธีนี้คุณจะพลาดข้อมูลน้อยลงเมื่อทำการโพสต์ หากคุณดูโพสต์ล่าสุดอื่น ๆ ในเว็บไซต์ด้วยการต้อนรับที่ดีพอสมควรฉันคิดว่าคุณจะเห็นว่าทั้งคำถามและวิธีแก้ไขของคุณไม่สอดคล้องกับสิ่งที่เราทำที่นี่
FryAmTheEggman

3
ในความเสี่ยงของการเป็นคนพูดพาดพิงฉันอยากจะชี้ให้เห็นว่ายังrange "zero".."nine"ไม่ได้ระบุอย่างครบถ้วน
สตริงที่ไม่เกี่ยวข้อง

4
annoyingly, builtin Interpreter@"SemanticNumber"ไม่ตรงนี้ใน Mathematica zero zero ยกเว้นว่ามันล้มเหลวในสายที่เริ่มต้นด้วย
Greg Martin

คำตอบ:


22

PHP , 74 ไบต์

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

ลองออนไลน์!

พยายามรับโซลูชันที่ไม่คัดลอกคำตอบที่มีอยู่ ฉันได้รับพหุนามการตรวจสอบแบบวนซ้ำที่มีความยาว 32 บิต ( crc32 ) สำหรับแต่ละคำจากนั้นทำ mod 20 และ mod 11 ในนั้นเพื่อให้ได้ค่าที่ไม่ซ้ำกันจาก 0 ถึง 10 (ขาด 6) สำหรับแต่ละหลัก จากนั้นใช้ค่าที่ไม่ซ้ำกันฉันพบตัวเลขจริง

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

ทางเลือก CRC32 อีก 74 ไบต์ใช้%493%10: ลองออนไลน์!

ทางเลือก CRC32 อีก 74 ไบต์ใช้%2326%11: ลองออนไลน์!


PHP , 74 ไบต์

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

ลองออนไลน์!

อีกทางเลือกหนึ่งที่มีความยาวเท่ากันใช้อักขระที่ 22 ในmd5คำนั้น (เฉพาะอักขระที่ให้ค่าที่ไม่ซ้ำกันสำหรับแต่ละคำ) จากนั้นใช้อักขระนั้นเพื่อจับคู่กับตัวเลข


นี่เป็นคำตอบที่ยอดเยี่ยม
Juan Sebastian Lozano



6

เยลลี่ ,  19  17 ไบต์

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

ลิงก์ monadic ยอมรับรายการของอักขระที่ให้จำนวนเต็ม

ลองออนไลน์!

ค่อนข้างพอร์ตของ Python 2 คำตอบของฉัน


ก่อน

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

ลองออนไลน์!

นอกจากนี้ค่อนข้างเป็นไปได้ทางที่สั้นกว่า แต่นี้เป็นวิธีการที่แรกที่เข้ามาใจ


การลบศูนย์ออกจากสตริง enklact เพื่อหลีกเลี่ยงการลดลงเนื่องจากไม่พบเป็นศูนย์ แต่อย่างใด ... ฉลาด!
สตริงที่ไม่เกี่ยวข้อง

1
อ่าฉันเห็นว่าคุณทำแบบเดียวกันดีมาก
Jonathan Allan

5

Python 3 , 107 , 91 , 77 , 90 ไบต์

-16 ไบต์โดย Sriotchilism O'Zaic

+13 ไบต์เพื่อลบศูนย์นำหน้า

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

ลองออนไลน์!



ทำได้ดีนี่! วิธีการที่ฉันยังสามารถวางคั่นสมบูรณ์ :)
movatica

1
ด้วยการอัปเดตความท้าทายนี้ไม่สามารถใช้งานได้อีกต่อไปเนื่องจากมีศูนย์นำหน้า :(
Wheat Wizard


1
@movatica การแก้ไขของคุณไม่ถูกต้อง lstripวิธีแถบตัวละครทุกตัวในสายที่จะได้รับเป็นมันโต้แย้งว่า "แปดสอง" กลายเป็น "ight สอง" ในขณะที่ "อี" ได้รับการปล้น นอกจากนี้ "ศูนย์ศูนย์ศูนย์" ควรพิมพ์ "0" ไม่ให้เกิดข้อผิดพลาด
NemPlayer



3

05AB1E , 18 16 ไบต์

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

ลองออนไลน์

คำอธิบาย:

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

ดู 05AB1E นี้เคล็ดลับของฉัน (ส่วนวิธีการบีบอัดสตริงไม่ใช่ส่วนหนึ่งของพจนานุกรม? )จะเข้าใจว่าทำไมเป็น.•ƒ/ÿßÇf•"rothuvsein"



3

05AB1E , 17 16 ไบต์

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

ลองออนไลน์!

เน็คไทที่สมบูรณ์แบบด้วยคำตอบ 05AB1E อื่น ๆแต่ใช้วิธีการที่แตกต่างอย่างสิ้นเชิง

•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

เรติน่า 0.8.2 , 46 45 ไบต์

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

^0+\B

ลองออนไลน์! ลิงค์มีกรณีทดสอบ คำอธิบาย:

\w+
¶$&$&$&

วางคำแต่ละคำลงบนบรรทัดของตัวเองแล้วเพิ่มเป็นสามเท่า

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

แปลอักขระที่ 7 ของแต่ละบรรทัดโดยใช้สตริงของ @ UnrelatedString

\D

ลบอักขระที่ไม่ใช่ตัวเลขที่เหลือทั้งหมด

^0+\B

ลบศูนย์นำหน้า (แต่ต้องมีอย่างน้อยหนึ่งหลัก)

โซลูชันดั้งเดิมแบบ 46 ไบต์ก่อนหน้านี้เพิ่มเติม:

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

^0+\B

ลองออนไลน์! ลิงค์มีกรณีทดสอบ คำอธิบาย:

T`z\wuxg`E

คำzero, two, four, sixและไม่ซ้ำกันประกอบด้วยตัวอักษรeight zwuxgแปลเหล่านั้นให้เป็นเลขคู่

on
1
th
3
fi
5
se
7
ni
9

สำหรับตัวเลขคี่เพียงแค่จับคู่ตัวอักษรสองตัวแรกของแต่ละคำเป็นรายบุคคล

\D

ลบอักขระที่ไม่ใช่ตัวเลขที่เหลือทั้งหมด

^0+\B

ลบศูนย์นำหน้า (แต่ต้องมีอย่างน้อยหนึ่งหลัก)


2

เยลลี่ , 20 18 17 ไบต์

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

ลองออนไลน์!

-2 ไบต์จากการรัน"rothuvsein"ผ่านตัวบีบอัดสตริงของ user202729ของคอมเพรสเซอร์สตริง

-1 ไบต์จากการขโมยสตริง enklact ของโจนาธานอัลลันและวางไว้ในโปรแกรมที่มีโครงสร้างแตกต่างกันเล็กน้อย

Ḳ                    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 ไบต์

¸mg6 ì`Ψuv 

ลองมัน

ดูเหมือนว่าทุกคนจะเอาชนะฉันไปที่ความคิดเดียวกัน - สามารถช่วยตัวเองให้วุ่นวายกับการเขียนบทเพื่อบังคับให้สายอักขระที่เหมาะสมสำหรับการบีบอัดเท่านั้นที่จะพบว่าจนถึงดัชนี1,000,000(เร็วเกินไปฉันไม่มี คาเฟอีนยัง!) "rothuvsein" เป็นสตริงที่เป็นไปได้เท่านั้น !

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

สตริงบีบอัดมีอักขระที่ codepoints 206, 168, 117,118 , และ160136


1
... คุณลองถึง 1000000 จริงๆหรือ lcm ของความยาวของชื่อหลักคือ 60 ดังนั้นจึงไม่มีความพยายามอีกต่อไป (60 เท่ากับ 0, 61 ถึง 1, ฯลฯ )
Grimmy

1
@Grimy มันเร็ว แต่ฉันยังไม่มีคาเฟอีน! การเสียบล้านสคริปต์ที่ฉันเขียนเพื่อสร้างความเป็นไปได้ทั้งหมดนั้นง่ายเหมือนหมายเลขอื่นและช่วยให้ฉันทำคณิตศาสตร์ใน LCM
Shaggy

2

Ruby , 63 ไบต์ , 52 ไบต์ , 50 ไบต์

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

-2 ขอบคุณปลายหมึกที่คุ้มค่า


ยินดีต้อนรับสู่ Code Golf! ใน Ruby $*เป็นชื่อแทนARGVดังนั้นโปรดใช้เพื่อบันทึกเป็นไบต์พิเศษ
หมึกมูลค่า

2

T-SQL, 110 ไบต์

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

การขึ้นบรรทัดใหม่มีไว้เพื่อให้สามารถอ่านได้เท่านั้น

ผม

คำอธิบาย:

  1. STRING_SPLIT รับสตริงอินพุตและแยกที่ช่องว่าง
  2. CHARINDEXเตะ 2 ตัวอักษรแรกและส่งกลับ (1-based) '_ontwthfofisiseeini'ตำแหน่งในสตริง'ze'สำหรับศูนย์ไม่ได้อยู่ในสตริงและส่งคืน 0 สำหรับ "ไม่พบ" เครื่องหมายขีดล่างทำให้แน่ใจว่าเราจะได้รับทวีคูณของสองเท่านั้น
  3. หารด้วย 2 เพื่อให้ได้ตัวเลขสุดท้าย
  4. STRING_AGG แตกตัวเลขกลับมาพร้อมกันโดยไม่มีตัวคั่น
  5. 0+บังคับให้มีการแปลงโดยนัยเป็น INT และปล่อยศูนย์นำหน้าใด ๆ 1*ก็จะทำงานเช่นกัน

2

รหัสเครื่อง x86, 46 ไบต์

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

มันเป็นfastcallฟังก์ชั่น - รับตัวชี้ไปยังสตริงในecxและส่งคืนผลลัพธ์eaxและผลตอบแทนใน

ฟังก์ชั่นการแปลงแป้นพิมพ์จะคูณด้วยจำนวนเวทย์มนตร์1856645926ทำ a XORด้วยไบต์อินพุตและเลื่อนไปทางขวา 2 บิต

การบันทึกและกู้คืนการลงทะเบียน noclobber ( ediและebx) ใช้เวลา 4 ไบต์ แต่ฉันไม่พบวิธีที่มีประสิทธิภาพมากขึ้นในการดำเนินการนี้ การจัดเก็บค่าคงที่ 10 ในebxนั้นน่ารำคาญเป็นพิเศษ!

ถอดชิ้นส่วนที่มีรหัสไบต์ที่สอดคล้องกัน:

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

รหัส 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;
}

คุณค้นหาหมายเลขเวทย์มนตร์อย่างไร?
Sparkler

ฉันค้นหาโดยใช้รหัส C ของฉัน - ลองใช้ตัวเลข 32 บิตและกะทั้งหมด มีความเป็นไปได้เพียงไม่กี่ - รหัสที่พบเพียงหนึ่งในช่วงที่สูงถึง 2000000000
Anatolyg

คุณสามารถใช้ edx แทน edi (กด edx ก่อน idiv, pop eax หลังจากนั้น, imul ด้วย ebx, เพิ่ม eax to edx) เพื่อบันทึกหนึ่งไบต์
เตอร์เฟอร์รี



1

ถ่าน 19 ไบต์

I⍘⭆⪪S §ι⁶rothuvsein

ลองออนไลน์! การเชื่อมโยงคือการใช้รหัสเวอร์ชันอย่างละเอียด คำตอบ 05AB1E ของพอร์ต @ KevinCruijssen คำอธิบาย:

    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 ไบต์

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

ลองออนไลน์!

ใช้rothuvseinกลอุบายแบบเดียวกันกับคนอื่นขอบคุณ Jonathan Allan คาดหวังข้อโต้แย้งอินพุตผ่านการทำเครื่องหมายซึ่งใน TIO จะแสดงว่าเป็นอาร์กิวเมนต์บรรทัดคำสั่งที่แยกต่างหาก


1

Kotlin, 83 ไบต์

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

+1 ไบต์หากคุณต้องการการสนับสนุนเป็นเวลานาน toLong()

เคล็ดลับ rothuvsein เหมือนกับคนอื่น ๆ ประหยัดบางขอบคุณไบต์มีค่าที่จะมีความสุข Kotlin ของและtoInt() fold()ฉันไม่สามารถสั่นคลอนความรู้สึกที่จะสามารถกำจัดไบต์จำนวนมากออกไป ...





0

VBA ขนาด 160 ไบต์

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

จับคู่อักขระสองตัวแรกในสตริงยกเว้นศูนย์


0

BaCon , 83 72 ไบต์

สมมติว่าสตริงมีให้ใน w $ รหัสนี้จะค้นหาดัชนีใน "zeontwthfofisiseeini" โดยใช้นิพจน์ทั่วไปโดยยึดตามอักขระ 2 ตัวแรกของแต่ละคำ ดัชนีจะถูกหารด้วย 2 ให้ผลลัพธ์ที่ถูกต้อง

FOR x$ IN w$:r=r*10+REGEX("zeontwthfofisiseeini",LEFT$(x$,2))/2:NEXT:?r
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.