แยกซีตัวอักษรจำนวนเต็ม C ++ 14


27

อ้างอิงจากhttp://en.cppreference.com/w/cpp/language/integer_literalตัวอักษรจำนวนเต็มประกอบด้วยทศนิยม / ฐานสิบหก / ฐานแปด / เลขฐานสองตัวอักษรและส่วนต่อท้ายที่เป็นตัวเลือกซึ่งเห็นได้ชัดว่าไม่จำเป็นอย่างสมบูรณ์เสียค่าล้ำค่าและเป็น ไม่ได้ใช้ในการท้าทายนี้

a non-zero decimal digit (1, 2, 3, 4, 5, 6, 7, 8, 9), followed by zero or more decimal digits (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)ทศนิยมที่แท้จริงคือ

the digit zero (0) followed by zero or more octal digits (0, 1, 2, 3, 4, 5, 6, 7)ฐานแปดตัวอักษรมี

ตัวอักษรฐานสิบหกคือthe character sequence 0x or the character sequence 0X followed by one or more hexadecimal digits (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, A, b, B, c, C, d, D, e, E, f, F)(หมายเหตุตัวพิมพ์เล็กและใหญ่abcdefx)

the character sequence 0b or the character sequence 0B followed by one or more binary digits (0, 1)ไบนารีที่แท้จริงคือ

นอกจากนี้อาจมีตัวเลือกบางตัว'เป็นตัวคั่นหลัก พวกมันไม่มีความหมายและสามารถเพิกเฉยได้

อินพุต

สตริงที่แสดงถึงตัวอักษรจำนวนเต็ม C ++ 14 หรืออาร์เรย์ของ charcodes

เอาท์พุต

จำนวนที่แสดงโดยสตริงอินพุตในฐาน 10 พร้อมกับบรรทัดใหม่ต่อท้ายที่เป็นทางเลือก เอาต์พุตที่ถูกต้องจะไม่เกิน 2 * 10 ^ 9

เกณฑ์การชนะ

ผู้มีส่วนร่วม GCC ต้องการโค้ดมากกว่า 500 บรรทัดในการทำเช่นนี้ดังนั้นโค้ดของเราจะต้องสั้นที่สุด!

กรณีทดสอบ:

0                       ->    0
1                       ->    1
12345                   ->    12345
12345'67890             ->    1234567890
0xFF                    ->    255
0XfF                    ->    255
0xAbCdEf                ->    11259375
0xa'bCd'eF              ->    11259375
0b1111'0000             ->    240
0b0                     ->    0
0B1'0                   ->    2
0b1                     ->    1
00                      ->    0
01                      ->    1
012345                  ->    5349
0'123'4'5               ->    5349


4
@LuisfelipeDejesusMunoz No; คุณคิดว่าจะแยกวิเคราะห์อย่างไร
คำสรรพนามของฉันคือ monicareinstate

1
ฉันคิดว่าการเขียนฟังก์ชันใน C ++ 14 น่าจะเป็นการโกงใช่ไหม เนื่องจากคอมไพเลอร์ทำมันโดยอัตโนมัติแล้ว (แม้ว่าจะเป็นโค้ดภายใน 500 บรรทัด ... )
Darrel Hoffman

5
@DarrelHoffman คุณไม่สามารถทำได้ด้วย "ฟังก์ชั่นใน C ++ 14" เนื่องจากว่าจะไม่ใช้อินพุตสตริง อาจมีบางสคริปต์ที่เรียกคอมไพเลอร์ C ++
aschepler

2
สตริง0อาจเป็นกรณีทดสอบที่ดีในการเพิ่ม (มันแสดงข้อผิดพลาดในการแก้ไขล่าสุดของฉัน)
Daniel Schepler

คำตอบ:



22

รหัสเครื่อง x86 (32 บิต) 59 57 ไบต์

ฟังก์ชั่นนี้จะใช้เวลาเป็นตัวชี้ไปยังสตริงที่สิ้นสุดและผลตอบแทนที่คุ้มค่าในesi edx(รายการด้านล่างคืออินพุต GAS ในไวยากรณ์ AT&T)

        .globl parse_cxx14_int
        .text
parse_cxx14_int:
        push $10
        pop %ecx                # store 10 as base
        xor %eax,%eax           # initialize high bits of digit reader
        cdq                     # also initialize result accumulator edx to 0
        lodsb                   # fetch first character
        cmp $'0', %al
        jne .Lparseloop2
        lodsb
        and $~32, %al           # uppercase letters (and as side effect,
                                # digits are translated to N+16)
        jz .Lend                # "0" string
        cmp $'B', %al           # after '0' have either digit, apostrophe,
                                # 'b'/'B' or 'x'/'X'
        je .Lbin
        jg .Lhex
        dec %ecx
        dec %ecx                # update base to 8
        jmp .Lprocessdigit      # process octal digit that we just read (or
                                # skip ' if that is what we just read)   
.Lbin:
        sub $14, %ecx           # with below will update base to 2
.Lhex:
        add $6, %ecx            # update base to 16
.Lparseloop:
        lodsb                   # fetch next character
.Lparseloop2:
        and $~32, %al           # uppercase letters (and as side effect,
                                # digits are translated to N+16)
        jz .Lend
.Lprocessdigit:
        cmp $7, %al             # skip ' (ASCII 39 which would have been
                                # translated to 7 above)
        je .Lparseloop
        test $64, %al           # distinguish letters and numbers
        jz .Lnum
        sub $39, %al            # with below will subtract 55 so e.g. 'A'==65
                                # will become 10
.Lnum:
        sub $16, %al            # translate digits to numerical value
        imul %ecx, %edx
#        movzbl %al, %eax
        add %eax, %edx          # accum = accum * base + newdigit
        jmp .Lparseloop
.Lend:
        ret

และการถอดชิ้นส่วนที่มีจำนวนไบต์ - ในรูปแบบ Intel เวลานี้ในกรณีที่คุณต้องการ

Disassembly of section .text:

00000000 <parse_cxx14_int>:
   0:   6a 0a                   push   0xa
   2:   59                      pop    ecx
   3:   31 c0                   xor    eax,eax
   5:   99                      cdq    
   6:   ac                      lods   al,BYTE PTR ds:[esi]
   7:   3c 30                   cmp    al,0x30
   9:   75 16                   jne    21 <parse_cxx14_int+0x21>
   b:   ac                      lods   al,BYTE PTR ds:[esi]
   c:   24 df                   and    al,0xdf
   e:   74 28                   je     38 <parse_cxx14_int+0x38>
  10:   3c 42                   cmp    al,0x42
  12:   74 06                   je     1a <parse_cxx14_int+0x1a>
  14:   7f 07                   jg     1d <parse_cxx14_int+0x1d>
  16:   49                      dec    ecx
  17:   49                      dec    ecx
  18:   eb 0b                   jmp    25 <parse_cxx14_int+0x25>
  1a:   83 e9 0e                sub    ecx,0xe
  1d:   83 c1 06                add    ecx,0x6
  20:   ac                      lods   al,BYTE PTR ds:[esi]
  21:   24 df                   and    al,0xdf
  23:   74 13                   je     38 <parse_cxx14_int+0x38>
  25:   3c 07                   cmp    al,0x7
  27:   74 f7                   je     20 <parse_cxx14_int+0x20>
  29:   a8 40                   test   al,0x40
  2b:   74 02                   je     2f <parse_cxx14_int+0x2f>
  2d:   2c 27                   sub    al,0x27
  2f:   2c 10                   sub    al,0x10
  31:   0f af d1                imul   edx,ecx
  34:   01 c2                   add    edx,eax
  36:   eb e8                   jmp    20 <parse_cxx14_int+0x20>
  38:   c3                      ret    

และในกรณีที่คุณต้องการลองนี่คือรหัสไดรเวอร์ทดสอบ C ++ ที่ฉันเชื่อมโยงกับมัน (รวมถึงข้อกำหนดการเรียกประชุมในไวยากรณ์ Asm ของ GCC):

#include <cstdio>
#include <string>
#include <iostream>

inline int parse_cxx14_int_wrap(const char *s) {
    int result;
    const char* end;
    __asm__("call parse_cxx14_int" :
            "=d"(result), "=S"(end) :
            "1"(s) :
            "eax", "ecx", "cc");
    return result;
}

int main(int argc, char* argv[]) {
    std::string s;
    while (std::getline(std::cin, s))
        std::printf("%-16s -> %d\n", s.c_str(), parse_cxx14_int_wrap(s.c_str()));
    return 0;
}

-1 ไบต์เนื่องจากคอมเม้นต์โดย Peter Cordes

-1 ไบต์จากการอัปเดตเพื่อใช้การลดลงสองครั้งเพื่อเปลี่ยน 10 ถึง 8


1
มีเพียงคุณที่ขาดการทดสอบการโอเวอร์โฟลว์ ... มีผู้รวบรวมคอมไพล์จำนวนมากเกินไป
Alexis Wilke

2
คุณสามารถสลับการใช้งานที่ลงทะเบียนของคุณสำหรับrdxและ RBX ? Then you can use 1-byte cdq` ให้เป็นศูนย์จากrdx eax
Peter Cordes

1
นี่ควรเป็นรายการจำนวนไบต์ของแอสเซมบลีของคุณหรือถูกระบุว่าเป็น 59 ไบต์ของรหัสเครื่อง x86
Potato44

2
@PeterCordes ขอบคุณไม่รู้เกี่ยวกับอันนั้น (เมื่อมองอีกครั้งฉันสังเกตเห็นว่าการเปลี่ยนฐานจาก 10 เป็น 8 อาจเป็น 2 ไบต์ - จากคำแนะนำการลดลงสองคำ - แทน 3 ไบต์)
Daniel Schepler

3
@AlexisWilke นอกจากนี้ยังไม่ได้ทดสอบรูปแบบที่ไม่ถูกต้อง (เช่นตัวเลขอยู่นอกช่วงฐานที่กำหนด) ซึ่งคอมไพเลอร์ก็จะทำเช่นกัน แต่ตามคำแถลงปัญหาการป้อนข้อมูลจะรับประกันว่าถูกต้องและไม่ล้นจำนวนเต็มที่ลงนาม 32- บิต
Daniel Schepler

12

JavaScript (โหนดบาเบล) , 26 ไบต์

ฮ่า ๆ x2

_=>eval(_.split`'`.join``)

ลองออนไลน์!


4
นี่ไม่ใช่ BabelJS เอกสิทธิ์มันทำงานได้จาก ES6 เป็นต้นไป
Bassdrop Cumberwubwubwub

1
@BassdropCumberwubwubwub ส่วนหัวอาจถูกคัดลอกมาจาก TIO
Shaggy

ดีฉันแรกพยายามใช้Numberเพราะมันจัดการไบนารีและฐานสิบหก แต่เห็นได้ชัดว่าไม่ใช่เลขฐานแปดNumber("010") === 10
Carl Walsh

7

C ++ (gcc) 141 138 134 120 ไบต์

นี่คือฟังก์ชั่นที่ใช้อาร์เรย์ของอักขระ (ระบุเป็นคู่ของพอยน์เตอร์ไปยังจุดเริ่มต้นและสิ้นสุด - ใช้คู่ของตัววนซ้ำตัวเอียง) และส่งกลับตัวเลข โปรดทราบว่าฟังก์ชั่นกลายเป็นอาร์เรย์อินพุต

(สิ่งนี้ขึ้นอยู่กับพฤติกรรมของ gcc / libstdc ++ ที่#include<cstdlib>วางฟังก์ชั่นไว้ในขอบเขตทั่วโลกสำหรับรหัสที่เป็นไปตามมาตรฐานอย่างเคร่งครัดให้แทนที่ด้วย#include<stdlib.h>ค่าตัวอักษรอีกหนึ่งตัว)

คำอธิบายสั้น ๆ : รหัสใช้std::removeเพื่อกรอง'อักขระ (ASCII 39) เป็นครั้งแรก จากนั้นstrtolด้วยฐาน 0 จะจัดการกับกรณีทศนิยมทศนิยมฐานแปดและฐานสิบหกดังนั้นกรณีอื่น ๆ ที่จะตรวจสอบเป็นผู้นำ0bหรือหรือ0Bถ้าเป็นเช่นนั้นตั้งฐานสำหรับstrtol2 และเริ่มการแยกหลังจากตัวละครนำ 2

#import<algorithm>
#import<cstdlib>
int f(char*s,char*e){e=s[*std::remove(s,e,39)=1]&31^2?s:s+2;return strtol(e,0,e-s);}

ลองออนไลน์


บันทึกแล้ว 3 ไบต์เนื่องจากข้อเสนอแนะโดยแมวป่าและอีกหลายสนามที่ตามมา

บันทึกแล้ว 4 ไบต์เนื่องจากคำแนะนำโดย grastropner

-2 ไบต์โดย Lucas

-12 ไบต์ by l4m2



รวมเอาไว้ขอบคุณ
Daniel Schepler


หากอินพุตไม่ถูกต้องเป็นพฤติกรรมที่ไม่ได้กำหนดไม่จำเป็นต้องตรวจสอบว่าถ่านตัวที่ 1 ใช้0สำหรับฐาน 2
l4m2

ดังนั้น124
l4m2



4

R , 79 71 69 69 ไบต์

`+`=strtoi;s=gsub("'","",scan(,""));na.omit(c(+s,sub("..",0,s)+2))[1]

ลองออนไลน์!

strtoiทำทุกอย่างยกเว้นการแปลงฐาน 2 และไม่สนใจ'ดังนั้นจึงมีจำนวนไบต์ค่อนข้างมากที่จะแก้ไขสิ่งเหล่านั้น

ขอบคุณAaron Hayman ที่มีค่า -6 ไบต์และให้แรงบันดาลใจ -4 ไบต์เพิ่มเติม (และเพิ่มขึ้นอีก!)

ตรวจสอบกรณีทดสอบทั้งหมด (เวอร์ชั่นเก่า)


สามารถบันทึกไบต์แทนsub("0b|B"ด้วยsub("b|B"เนื่องจากนำ "0" จะไม่ส่งผลกระทบต่อค่า สามารถได้รับอีกโดยเปลี่ยนชื่อstrtoi
Aaron Hayman


1
@AaronHayman ว้าวฉันไม่เคยเห็นna.omitมาก่อน มีประโยชน์มากที่นี่และฉันตีกอล์ฟเพิ่มอีกเล็กน้อย :-)
จูเซปเป้

1
หากเราถือว่าทุกความล้มเหลวของแรกstrtoiคือไบนารีคุณสามารถใช้substringแทนsubการบันทึกไบต์อื่น: ลองออนไลน์!
แอรอนเฮย์แมน

1
@AaronHayman เราสามารถตัดอักขระ 2 ตัวแรกที่sใช้subแทนsub('..','',s)ซึ่งจะมีขนาดสั้นกว่าอีกหนึ่งไบต์!
Giuseppe

4

05AB1E , 16 14 ไบต์

บันทึก 2 ไบต์ขอบคุณGrimy

''KlÐïK>i8ö}.E

ลองออนไลน์! หรือเป็นชุดทดสอบ

คำอธิบาย

''K                # remove "'" from input
   l               # and convert to lower-case
    Ð              # triplicate
     ï             # convert one copy to integer
      K            # and remove it from the second copy
       >i  }       # if the result is 0
         8ö        # convert from base-8 to base-10
            .E     # eval


และนี่เป็นของปลอม 13 รายการ (ผ่านทุกกรณีทดสอบ แต่ล้มเหลวในเช่น0010)
Grimmy

@Grimy: ขอบคุณ! ใช้เด็ดï!
Emigna

4

Excel, 115 ไบต์

=DECIMAL(SUBSTITUTE(REPLACE(A1,2,1,IFERROR(VALUE(MID(A1,2,1)),)),"'",),VLOOKUP(A1,{"0",8;"0B",2;"0X",16;"1",10},2))

ป้อนข้อมูลจาก A1 ส่งออกไปยังทุกที่ที่คุณใส่สูตร สูตรอาเรย์ดังนั้นควรใช้Ctrl + Shift+Enterเพื่อป้อน

ฉันเพิ่มกรณีทดสอบสองสามข้อที่คุณเห็นในภาพความพยายามเริ่มต้นบางอย่างจัดการกรณีทดสอบทั้งหมดที่ให้ถูกต้อง แต่เกิดความผิดพลาดขึ้นในแถว 16 และ / หรือ 17

ป้อนคำอธิบายรูปภาพที่นี่


เป็นการผิดกฎหรือไม่ที่จะไม่ใส่วงเล็บปิดสองอันสุดท้ายและใช้ประโยชน์จากข้อเท็จจริงที่ว่า“ คอมไพเลอร์” (การกดส่งคืนหรือแท็บ) จะแก้ไขข้อผิดพลาดให้คุณได้หรือไม่?
ลูคัส

ในความเห็นส่วนตัวของฉันใช่ ฉันไม่คิดว่าจะมีฉันทามติเว็บไซต์ Excel การเพิ่มวงเล็บให้ความรู้สึกเหมือนกับคุณลักษณะการทำให้โค้ดเสร็จสมบูรณ์ใน IDE ของภาษาอื่นซึ่งควรละเว้นเมื่อนับจำนวนไบต์ (แต่ฉันคิดว่า "?" ควรนับเป็น 1 ไบต์ในภาษาเบสิกถึงแม้ว่ามันจะขยายไปที่ "PRINT" อย่างเงียบ ๆ ดังนั้นบางทีฉันอาจไม่สอดคล้องกันทั้งหมดที่นี่)
Sophia Lechner

3

รหัสเครื่อง x86-64 ขนาด 44 ไบต์

(รหัสเครื่องเดียวกันทำงานในโหมด 32 บิตได้เช่นกัน)

คำตอบของ @Daniel Scheplerเป็นจุดเริ่มต้นสำหรับสิ่งนี้ แต่มีแนวคิดอัลกอริทึมใหม่อย่างน้อยหนึ่งแนวคิด (ไม่ใช่แค่การเล่นกอล์ฟที่ดีกว่าของความคิดเดียวกัน): รหัส ASCII สำหรับ'B'( 1000010) และ'X'( 1011000) ให้ 16 และ 2 หลังจากปิดบัง0b0010010หลังจากที่กำบังด้วย

ดังนั้นหลังจากไม่รวมทศนิยม (หลักนำที่ไม่ใช่ศูนย์) และฐานแปด (ถ่านหลังจาก'0'น้อยกว่า'B') เราก็สามารถตั้งค่าฐาน =c & 0b0010010และกระโดดเข้าไปในวงหลัก

Callable กับ x86-64 System V เป็นunsigned __int128 parse_cxx14_int(int dummy, const char*rsi); แยก EDX ค่าตอบแทนจากครึ่งสูงของผลกับunsigned __int128tmp>>64

        .globl parse_cxx14_int
## Input: pointer to 0-terminated string in RSI
## output: integer in EDX
## clobbers: RAX, RCX (base), RSI (points to terminator on return)
parse_cxx14_int:
        xor %eax,%eax           # initialize high bits of digit reader
        cdq                     # also initialize result accumulator edx to 0
        lea 10(%rax), %ecx      # base 10 default
        lodsb                   # fetch first character
        cmp $'0', %al
        jne .Lentry2
    # leading zero.  Legal 2nd characters are b/B (base 2), x/X (base 16)
    # Or NUL terminator = 0 in base 10
    # or any digit or ' separator (octal).  These have ASCII codes below the alphabetic ranges
    lodsb

    mov    $8, %cl              # after '0' have either digit, apostrophe, or terminator,
    cmp    $'B', %al            # or 'b'/'B' or 'x'/'X'  (set a new base)
    jb   .Lentry2               # enter the parse loop with base=8 and an already-loaded character
         # else hex or binary. The bit patterns for those letters are very convenient
    and    $0b0010010, %al      # b/B -> 2,   x/X -> 16
    xchg   %eax, %ecx
    jmp  .Lentry

.Lprocessdigit:
    sub  $'0' & (~32), %al
    jb   .Lentry                 # chars below '0' are treated as a separator, including '
    cmp  $10, %al
    jb  .Lnum
    add  $('0'&~32) - 'A' + 10, %al   # digit value = c-'A' + 10.  we have al = c - '0'&~32.
                                        # c = al + '0'&~32.  val = m+'0'&~32 - 'A' + 10
.Lnum:
        imul %ecx, %edx
        add %eax, %edx          # accum = accum * base + newdigit
.Lentry:
        lodsb                   # fetch next character
.Lentry2:
        and $~32, %al           # uppercase letters (and as side effect,
                                # digits are translated to N+16)
        jnz .Lprocessdigit      # space also counts as a terminator
.Lend:
        ret

บล็อกที่มีการเปลี่ยนแปลงเทียบกับเวอร์ชั่นของแดเนียล (ส่วนใหญ่) เยื้องน้อยกว่าคำสั่งอื่น ๆ นอกจากนี้ห่วงหลักมีสาขาตามเงื่อนไขที่ด้านล่าง สิ่งนี้กลายเป็นการเปลี่ยนแปลงที่เป็นกลางเพราะไม่มีเส้นทางใดสามารถตกลงบนจุดสูงสุดของมันและdec ecx / loop .Lentryความคิดในการเข้าสู่วงกลับกลายเป็นว่าไม่ชนะหลังจากจัดการแปดด้านต่างกัน แต่มันมีคำแนะนำน้อยกว่าภายในลูปโดยมีลูปในรูปแบบของสำนวนทำ {} ในขณะที่โครงสร้างดังนั้นฉันจึงเก็บมันไว้

ชุดควบคุมการทดสอบ C ++ ของ Daniel ทำงานไม่เปลี่ยนแปลงในโหมด 64 บิตด้วยรหัสนี้ซึ่งใช้หลักการเรียกที่เหมือนกันกับคำตอบ 32- บิตของเขา

g++ -Og parse-cxx14.cpp parse-cxx14.s &&
./a.out < tests | diff -u -w - tests.good

ถอดชิ้นส่วนรวมถึงไบต์รหัสเครื่องที่เป็นคำตอบที่แท้จริง

0000000000000000 <parse_cxx14_int>:
   0:   31 c0                   xor    %eax,%eax
   2:   99                      cltd   
   3:   8d 48 0a                lea    0xa(%rax),%ecx
   6:   ac                      lods   %ds:(%rsi),%al
   7:   3c 30                   cmp    $0x30,%al
   9:   75 1c                   jne    27 <parse_cxx14_int+0x27>
   b:   ac                      lods   %ds:(%rsi),%al
   c:   b1 08                   mov    $0x8,%cl
   e:   3c 42                   cmp    $0x42,%al
  10:   72 15                   jb     27 <parse_cxx14_int+0x27>
  12:   24 12                   and    $0x12,%al
  14:   91                      xchg   %eax,%ecx
  15:   eb 0f                   jmp    26 <parse_cxx14_int+0x26>
  17:   2c 10                   sub    $0x10,%al
  19:   72 0b                   jb     26 <parse_cxx14_int+0x26>
  1b:   3c 0a                   cmp    $0xa,%al
  1d:   72 02                   jb     21 <parse_cxx14_int+0x21>
  1f:   04 d9                   add    $0xd9,%al
  21:   0f af d1                imul   %ecx,%edx
  24:   01 c2                   add    %eax,%edx
  26:   ac                      lods   %ds:(%rsi),%al
  27:   24 df                   and    $0xdf,%al
  29:   75 ec                   jne    17 <parse_cxx14_int+0x17>
  2b:   c3                      retq   

การเปลี่ยนแปลงอื่น ๆ จากเวอร์ชันของ Daniel รวมถึงการบันทึกsub $16, %alจากภายในวงหลักโดยใช้มากกว่าsubแทนtestเป็นส่วนหนึ่งของการตรวจจับตัวคั่นและตัวเลขกับตัวอักษรและตัวอักษร

ซึ่งแตกต่างจากแดเนียลเป็นทุกตัวอักษรด้านล่างจะถือว่าเป็นตัวคั่นไม่เพียง'0' '\''(ยกเว้น' ': and $~32, %al/ jnzในลูปทั้งสองของเราใช้พื้นที่เป็นเทอร์มิเนเตอร์ซึ่งอาจสะดวกในการทดสอบด้วยจำนวนเต็มที่จุดเริ่มต้นของบรรทัด)

การดำเนินการทุกอย่างที่แก้ไข%alภายในลูปจะมีแฟลกการแบรนช์ย่อยที่กำหนดโดยผลลัพธ์และแต่ละสาขาจะไป (หรือผ่าน) ไปยังตำแหน่งอื่น


คุณจำเป็นต้องมีการกำหนดค่าเริ่มต้นของeaxAIUI ในโหมด 64 บิตที่มีปลายทางขนาดเล็กซึ่งจะรีเซ็ตบิตที่สูงกว่าเป็น 0 หรือไม่?
Daniel Schepler

@ Daniel: การเขียนแบบ 32 บิตลงทะเบียนที่ศูนย์ขยายไปถึง 64 การเขียนเรจิสเตอร์ 8 หรือ 16 บิตจะรักษาลักษณะการทำงานจากโหมดอื่น: รวมเข้ากับค่าที่มีอยู่ AMD64 ไม่ได้แก้ไขการขึ้นต่อกันของเท็จสำหรับการลงทะเบียน 8 และ 16 บิตและไม่เปลี่ยนsetcc r/m8เป็นsetcc r/m32ดังนั้นเรายังคงต้องใช้คำสั่งโง่ ๆ 2 คำสั่งxor-zero / set flag / setcc %alsequence เพื่อสร้าง 32/64-bit 0 หรือ 1 ตัวแปรและมันต้องการการลงทะเบียนเป็นศูนย์ก่อนการตั้งค่าสถานะ (หรือใช้mov $0, %eaxแทนหรือใช้movzxบนเส้นทางวิกฤต)
Peter Cordes

1

เรติน่า 96 ไบต์

T`'L`_l
\B
:
^
a;
a;0:x:
g;
a;0:b:
2;
a;0:
8;
[a-g]
1$&
T`l`d
+`;(\d+):(\d+)
;$.($`*$1*_$2*
.+;

ลองออนไลน์! การเชื่อมโยงรวมถึงชุดทดสอบ คำอธิบาย:

T`'L`_l

ลบ's และแปลงทุกอย่างเป็นตัวพิมพ์เล็ก

\B
:

แยกตัวเลขออกเป็นตัวเลขฐานสิบหกใด ๆ ที่ต้องแปลงเป็นทศนิยม

^
a;
a;0:x:
g;
a;0:b:
2;
a;0:
8;

ระบุฐานของจำนวน

[a-g]
1$&
T`l`d

แปลงตัวอักษรเป็นตัวเลขa-g10-16

+`;(\d+):(\d+)
;$.($`*$1*_$2*

ดำเนินการแปลงฐานในรายการตัวเลข $.($`*$1*_*$2*สั้นสำหรับ$.($`*$1*_*$2*_)ที่คูณ$`และร่วมกันและเพิ่ม$1 $2( $`เป็นส่วนหนึ่งของสตริงก่อนที่จะ;กล่าวคือฐาน)

.+;

ลบฐาน


ฉันขอขอบคุณวิธีการเขียนโปรแกรมตามตัวอักษรที่คุณใช้เพื่ออธิบายรหัส :-)
grooveplex

1

J , 48 ไบต์

cut@'0x 16b +0b 2b +0 8b0 '''do@rplc~'+',tolower

ลองออนไลน์!

Eval หลังจากการแทนที่สตริง

0XfF -> +16bff -> 255
0xa'bCd'eF -> +16babcdef -> 11259375
0B1'0 -> +2b10 -> 2
0 -> 8b0 -> 0
01 -> 8b01 -> 1
0'123'4'5 -> 8b012345 -> 5349

ดูเหมือนว่าจะทำงานไม่ถูกต้องกับเลขฐานสิบหกที่ประกอบด้วย0b: tio.run/##FcwxCsIwFAbg/…
Galen Ivanov

1
@ GalenIvanov พบที่ดีได้รับการแก้ไข
FrownyFrog

1

Perl 6 , 29 ไบต์

{+lc S/^0)>\d/0o/}o{S:g/\'//}

ลองออนไลน์!

Perl 6 ต้องการชัดเจนคำนำหน้าสำหรับฐานแปดและไม่สนับสนุนการคำนำหน้าตัวพิมพ์ใหญ่เช่น0o0X

คำอธิบาย

                   {S:g/\'//}  # remove apostrophes
{                }o  # combine with function
     S/^0)>\d/0o/    # 0o prefix for octal
  lc  # lowercase
 +    # convert to number

1

Octave , 29 21 20 bytes

@(x)str2num(x(x>39))

ลองออนไลน์!

-8 ไบต์ขอบคุณ @TomCarpenter


สำหรับ 22 ไบต์:@(x)str2num(x(x~="'"))
Tom Carpenter

ซึ่งจะกลายเป็น 21 ไบต์:@(x)str2num(x(x~=39))
Tom Carpenter

Octal ดูเหมือนจะไม่ทำงาน (อย่างน้อยใน TIO) ... ตัวอย่างเช่นf=("077")คืนans = 77เมื่อมันควรจะเป็น 63 หรือในกรณีทดสอบใน OP f=("012345")ควรกลับ 5349 แต่แทนans = 12345
brhfl

1

Bash, 33 ไบต์

x=${1//\'};echo $[${x/#0[Bb]/2#}]

TIO

Zsh, 29 27 ไบต์

-2 ไบต์ขอบคุณ @GammaFunction

<<<$[${${1//\'}/#0[Bb]/2#}]

TIO


ฉลาด! ฉันคิดว่าsetopt octalzeroesคงจะเป็นสิ่งจำเป็นสำหรับ Zsh
GammaFunction

คุณสามารถบันทึก 2 ไบต์ใน Zsh ด้วย<<<$[...]แทนecho $[...]
GammaFunction

ขอบคุณฉันไม่ทราบว่าคำสั่ง zsh ว่างเปล่าที่มีการเปลี่ยนเส้นทางสามารถแสดงผลลัพธ์ได้ฉันไม่รู้อะไรเกี่ยวกับ zsh มากฉันรู้ว่าทุบตีได้ดีขึ้นมาก
Nahuel Fouilleul

ผมรู้ว่าทุบตีที่จะตีความตัวเลขที่มีศูนย์นำไปฐานแปดและจะต้องออกเช่นในวันที่ / เวลา
Nahuel Fouilleul

0

ไป 75

import "strconv"
func(i string)int64{n,_:=strconv.ParseInt(i,0,0);return n}

สิ่งนี้ดูเหมือนจะไม่ทำงานสำหรับตัวอักษรไบนารีหรือตัวคั่นหลักเดียวที่มีเครื่องหมายคำพูด
Nick Matteo

โอ้อึ ฉันจะแก้ไขเร็ว ๆ นี้
ลืมตัว




0

Java (JDK) , 101 ไบต์

n->{n=n.replace("'","");return n.matches("0[bB].+")?Long.parseLong(n.substring(2),2):Long.decode(n);}

ลองออนไลน์!

Long.decode จัดการกับตัวอักษรทุกชนิดยกเว้นไบนารี

เทมเพลตยืมมาจากคำตอบของเบนจามิน


ดี ฉันต้องการที่จะดูเพิ่มเติมที่ฟังก์ชั่นห่อแบบดั้งเดิมได้
Benjamin Urquhart




0

C ++, G ++, 189 ไบต์

#include<fstream>
#include<string>
void v(std::string s){{std::ofstream a("a.cpp");a<<"#include<iostream>\nint main(){std::cout<<"<<s<<";}";}system("g++ -std=c++14 a.cpp");system("a.exe");}

ไม่จำเป็นต้องทำการทดสอบ

ต้องติดตั้งg++ด้วยการสนับสนุน C ++ 14

ตอนนี้คำอธิบาย:

มันเขียนไฟล์ที่เรียกว่าa.cppใช้ GCC เพื่อรวบรวมและให้ไฟล์ที่ส่งออกจำนวน



0

Pyth , 27 ไบต์

Jscz\'?&qhJ\0}@J1r\0\7iJ8vJ

ลองออนไลน์!

ต่างจากคำตอบ Pyth ก่อนหน้า (ถูกลบไปแล้ว) กรณีนี้ผ่านการทดสอบทั้งหมดในคำถามแม้ว่าจะยาวกว่า 3 ไบต์


ยินดีต้อนรับสู่เว็บไซต์!
ข้าวสาลี Wizard

0

C (gcc) / Bash / C ++, 118 ไบต์

f(i){asprintf(&i,"echo \"#import<iostream>\nmain(){std::cout<<%s;}\">i.C;g++ i.C;./a.out",i);fgets(i,i,popen(i,"r"));}

ลองออนไลน์!


ฉันตีกอล์ฟบางรหัส จากนั้นฉันก็ตระหนักว่าไม่มีเหตุผลอะไรเลยที่จะให้มันทำงาน แต่มันก็ใช้ได้ 158 ไบต์
สรรพนามของฉันคือ monicareinstate

@ ใครบางคนมันน่ารังเกียจ แต่ฉันชอบมัน!
Johan du Toit

148 ไบต์โดยการรวมpopensystemและ ฉันคิดว่า G ++ มีการตั้งค่าสถานะ-xเพื่ออ่านจาก stdin นั่นอาจจะสั้นกว่าของ fopen แต่ฉันไม่รู้ว่าจะเรียกใช้ stdin ใน C ได้อย่างไร
สรรพนามของฉันคือ monicareinstate

@someone ทุกอย่างถูกรวมเข้ากับpopenคำสั่ง
Johan du Toit

printf-> echoดูเหมือนว่าจะทำงาน คุณกำลังจะเขียนโปรแกรมด้วยการทุบตีในไม่ช้า
สรรพนามของฉันคือ monicareinstate

0

Java, 158 154 ไบต์

นี่แค่รอที่จะได้รับ outgolfed เพียงลอง regexes จนกว่าจะมีบางอย่างใช้งานได้
-4 ไบต์ขอบคุณ @ValueInk

n->{n=n.replace("'","");var s=n.split("[bBxX]");return Long.parseLong(s[s.length-1],n.matches("0[bB].+")?2:n.matches("0\\d+")?8:n.matches("\\d+")?10:16);}

ลองออนไลน์

ใช้ ScriptEngine, 92 87 ไบต์

รถไฟ Eval ผ่านมา ในทางเทคนิคแล้วนี่คือการส่งคบเพลิงไปยัง JS ดังนั้นมันจึงไม่ใช่การส่งหลักของฉัน

n->new javax.script.ScriptEngineManager().getEngineByName("js").eval(n.replace("'",""))

TIO


ใช้[bBxX]และ0[bB].+สำหรับการเพิ่มประสิทธิภาพ regex อย่างรวดเร็ว
Ink Value

@ValueInk ขอบคุณ
Benjamin Urquhart

นั่นไม่ใช่จำนวนเต็มมันยาวชื่อชัดเจนว่า Integer IEEE754 ที่มีความแม่นยำเพียงหนึ่งหรือสองครั้งอาจไม่ถูกต้องเนื่องจากวิธีที่ใช้ในการบันทึกหมายเลขเมื่อเกิดจากระบบทศนิยมใน IEEE754 en.wikipedia.org/wiki/ IEEE_754 # Roundings_to_nearestมันยังรองรับตัวเลขที่สูงกว่า 2 ล้านล้าน ( 0x9999999999)
Martin Barker

@MarkinBarker อนุญาตให้ใช้LongแทนIntegerจุดประสงค์ในการเล่นกอล์ฟได้ นอกจากนี้หากคุณถูกต้องงูใหญ่ไม่สามารถแข่งขันได้เพราะมีจำนวนเต็มความแม่นยำโดยพลการ นอกจากนี้ a longใน Java เป็นจำนวนเต็มที่แทนด้วย 64 บิตแทน 32 ไม่มีตำแหน่งทศนิยม
Benjamin Urquhart

สิ่งที่ยาวคือคุณกำลังใช้จำนวนเต็มไม่ใช่จำนวนเต็มและคุณผิดเกี่ยวกับจุดประสงค์ในการเล่นกอล์ฟThe correct output never will exceed 2*10^9มันค่อนข้างชัดเจนที่ระบุว่าความหมายที่ยาวไม่สามารถใช้ด้วยตัวเองได้เพราะฉันสามารถให้ได้0x9999999999และมันจะสร้างตัวเลข สูงกว่า 2 * 10 ^ 9 ในขณะที่ C ++ มันจะสร้างปัญหาหน่วยความจำล้นเพราะคุณใช้หน่วยความจำมากกว่า 32 บิตเมื่อคุณจัดสรรหน่วยความจำ 32 บิตไปยังหมายเลขนี้
Martin Barker
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.