Analizować literał całkowity C ++ 14


27

Zgodnie z http://en.cppreference.com/w/cpp/language/integer_literal literały liczb całkowitych składają się z literału dziesiętnego / szesnastkowego / ósemkowego / binarnego i opcjonalnego sufiksu liczb całkowitych, który jest oczywiście całkowicie niepotrzebny, marnuje cenne bajty i jest niewykorzystane w tym wyzwaniu.

Dziesiętny dosłowny to 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).

Oktalowy literał to the digit zero (0) followed by zero or more octal digits (0, 1, 2, 3, 4, 5, 6, 7).

Literał szesnastkowy to 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)(zwróć uwagę na niewrażliwość na wielkość liter abcdefx).

Binarny literał to the character sequence 0b or the character sequence 0B followed by one or more binary digits (0, 1).

Dodatkowo, opcjonalnie mogą występować pewne 's jako separator cyfr. Nie mają znaczenia i można je zignorować.

Wkład

Ciąg znaków reprezentujący literał całkowity C ++ 14 lub tablicę jego znaków.

Wydajność

Liczba reprezentowana przez łańcuch wejściowy w podstawie 10, z opcjonalnym końcowym znakiem nowej linii. Prawidłowa moc wyjściowa nigdy nie przekroczy 2 * 10 ^ 9

Kryteria wygranej

Współpracownicy GCC potrzebują do tego ponad 500 linii kodu, dlatego nasz kod musi być możliwie jak najkrótszy!

Przypadki testowe:

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; jak się spodziewałeś, że zostanie to przeanalizowane?
mój zaimek to monicareinstate

1
Zakładam, że po prostu napisanie funkcji w C ++ 14 byłoby oszustwem, prawda? Ponieważ kompilator robi to już automatycznie (nawet jeśli wewnętrznie jest to ponad 500 linii kodu ...)
Darrel Hoffman

5
@DarrelHoffman Nie można tego po prostu zrobić za pomocą „funkcji w C ++ 14”, ponieważ nie wymagałoby to wprowadzenia ciągu. Może z jakimś skryptem, który wywołuje kompilator C ++.
aschepler

2
Ciąg 0może być dobrym przypadkiem testowym do dodania (ujawnił błąd w jednej z moich ostatnich wersji).
Daniel Schepler

Odpowiedzi:



22

kod maszynowy x86 (32-bit), 59 57 bajtów

Ta funkcja przyjmuje esiwskaźnik jako łańcuch zakończony znakiem null i zwraca wartość w edx. (Poniżej wymieniono dane wejściowe GAS w składni 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

I liczy się demontaż z bajtami - tym razem w formacie Intela, na wypadek, gdybyś wolał ten.

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    

A jeśli chcesz go wypróbować, oto kod sterownika testowego C ++, który z nim powiązałem (łącznie ze specyfikacją konwencji wywoływania w składni 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 bajt z powodu komentarza Petera Cordesa

-1 bajt od aktualizacji do użycia dwóch dekrementów do zmiany 10 na 8


1
Tylko brakuje testów przepełnienia ... Kompilatory zgłaszają zbyt dużą liczbę.
Alexis Wilke

2
Czy możesz zamienić użycie rejestru rdxi rbx ? Then you can use 1-byte cdq` na zero rdxz eax.
Peter Cordes

1
Powinna to być albo liczba bajtów twojego zestawu, albo być oznaczona jako 59 bajtów kodu maszynowego x86.
Ziemniak44

2
@PeterCordes Dzięki, nie wiedziałem o tym. (Patrząc na to jeszcze raz, zauważyłem, że zmiana bazy z 10 na 8 może być 2 bajtami - z dwóch instrukcji dekrementacji - zamiast 3 bajtów.)
Daniel Schepler

3
@AlexisWilke Nie testuje również nieprawidłowego formatu (np. Cyfr spoza zakresu podanej bazy), co również mogłyby zrobić kompilatory. Jednak zgodnie ze stwierdzeniem problemu dane wejściowe są prawidłowe i nie przepełniają 32-bitowej liczby całkowitej ze znakiem.
Daniel Schepler


7

C ++ (gcc), 141 138 134 120 bajtów

Jest to funkcja, która przenosi tablicę znaków (określoną jako parę wskaźników na początek i na koniec - używając pary idiomów iteratorów) i zwraca liczbę. Zauważ, że funkcja mutuje tablicę wejściową.

(Zależy to od zachowania gcc / libstdc ++, które #include<cstdlib>również umieszcza funkcje w zasięgu globalnym. W przypadku kodu ściśle zgodnego ze standardem zamień #include<stdlib.h>na na koszt jeszcze jednego znaku.)

Krótki opis: kod najpierw wykorzystuje std::removedo odfiltrowywania 'znaków (ASCII 39). Następnie strtolna bazie 0 będzie już obsługiwać po przecinku, ósemkowy i przypadki szesnastkowym, więc jedyna inna sprawa do sprawdzenia jest wiodącym 0bczy 0B, a jeśli tak, to ustawić bazę do strtoldo 2 i zacząć parsowania po czołowych 2 znaki.

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

Wypróbuj online.


Zaoszczędzono 3 bajty dzięki sugestii sufitowego kota i późniejszej grze w golfa.

Zapisano 4 bajty dzięki sugestiom grastropner.

-2 bajty autorstwa Lucasa

-12 bajtów na l4m2



Włączone, dzięki.
Daniel Schepler


Jeśli niepoprawne wprowadzanie jest niezdefiniowanym zachowaniem, nie trzeba sprawdzać, czy 1. znak jest 0dla podstawy 2
l4m2

więc 124
14m2



4

R , 79 71 69 bajtów

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

Wypróbuj online!

strtoirobi wszystko oprócz konwersji podstawowych 2 i ignorowanie ', więc jest całkiem sporo bajtów tylko po to, żeby to naprawić.

Podziękowania dla Aarona Haymana za -6 bajtów i inspirowanie -4 dodatkowych bajtów (i wciąż rośnie!)

Sprawdź wszystkie przypadki testowe (stara wersja)


Można zapisać bajt zastępując sub("0b|B"z sub("b|B", od wiodącego „0” nie będzie miało wpływu na wartości. Można uzyskać inną, zmieniając nazwęstrtoi
Aaron Hayman


1
@AaronHayman wow, nigdy wcześniej nie widziałem na.omit. Bardzo przydatny tutaj, a ja grałem w golfa trochę więcej :-)
Giuseppe

1
Jeśli założymy, że każda porażka pierwszego strtoijest binarna, możesz użyć substringzamiast subzapisać kolejny bajt: Wypróbuj online!
Aaron Hayman

1
@AaronHayman możemy usunąć pierwsze 2 znaki, sużywając subzamiast tego, sub('..','',s)który jest kolejnym bajtem krótszym!
Giuseppe

4

05AB1E , 16 14 bajtów

Zaoszczędzono 2 bajty dzięki Grimy

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

Wypróbuj online! lub jako pakiet testowy

Wyjaśnienie

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


A oto fałszywa 13 (przechodzi wszystkie przypadki testowe, ale zawiedzie np 0010.).
Grimmy

@Grimy: Dzięki! Fajne użycie ï!
Emigna

4

Excel, 115 bajtów

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

Dane wejściowe z A1, dane wyjściowe do każdego miejsca, w którym umieścisz ten wzór. Formuła tablicowa, więc użyj Ctrl+ Shift+, Enteraby ją wprowadzić.

Dodałem kilka przypadków testowych, które można zobaczyć na obrazku - niektóre wczesne próby poprawnie obsługiwały wszystkie podane przypadki testowe, ale błędne były wiersze 16 i / lub 17.

wprowadź opis zdjęcia tutaj


Czy niezgodne z regułami jest pominięcie dwóch ostatnich nawiasów zamykających i skorzystanie z faktu, że „kompilator” (naciśnięcie klawisza Return lub Tab) poprawi błąd?
Lucas

Moim osobistym zdaniem tak. Nie sądzę, że istnieje zgodność strony. Excel dodając nawiasy wydaje się być odpowiednikiem funkcji uzupełniania kodu w IDE innego języka, którą należy zignorować przy liczeniu bajtów. (Ale myślę, że „?” Powinien być liczony jako 1 bajt w języku BASIC, mimo że zostanie on po cichu rozwinięty do „PRINT”, więc może nie jestem tutaj całkowicie spójny).
Sophia Lechner

3

kod maszynowy x86-64, 44 bajty

(Ten sam kod maszynowy działa również w trybie 32-bitowym.)

Odpowiedź @Daniela Scheplera była punktem wyjścia do tego, ale ma to co najmniej jeden nowy algorytmiczny pomysł (nie tylko lepszą grę w golfa tego samego pomysłu): kody ASCII dla 'B'( 1000010) i 'X'( 1011000) dają 16 i 2 po maskowaniu0b0010010 .

Więc po wykluczeniu dziesiętnej (niezerowej cyfry wiodącej) i ósemkowej (char after '0'jest mniejsza niż 'B'), możemy po prostu ustawić base = c & 0b0010010i przejść do pętli cyfr.

Można wywoływać za pomocą x86-64 System V as unsigned __int128 parse_cxx14_int(int dummy, const char*rsi); Wyodrębnij wartość zwracaną EDX z górnej połowy unsigned __int128wyniku za pomocą tmp>>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

Zmienione bloki vs. wersja Daniela są (głównie) wcięte mniej niż inne instrukcje. Również główna pętla ma u dołu gałąź warunkową. Okazało się to neutralną zmianą, ponieważ żadna ścieżka nie mogła wpaść na sam szczyt, a dec ecx / loop .Lentrypomysł wejścia do pętli okazał się nie być wygraną po różnym potraktowaniu ósemki. Ale ma mniej instrukcji wewnątrz pętli z pętlą w formie idiomatycznej do {} podczas tworzenia struktury, więc ją zachowałem.

Wiązka testowa Daniela C ++ Daniela działa bez zmian w trybie 64-bitowym z tym kodem, który wykorzystuje tę samą konwencję wywoływania jak jego 32-bitowa odpowiedź.

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

Demontaż, w tym bajty kodu maszynowego, które są rzeczywistą odpowiedzią

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   

Inne zmiany w porównaniu z wersją Daniela obejmują zapisywanie sub $16, %alod wewnątrz pętli cyfr, poprzez użycie więcej subzamiast w testramach wykrywania separatorów oraz cyfr w porównaniu ze znakami alfabetycznymi.

W przeciwieństwie do Daniela każda postać poniżej '0'jest traktowana jako separator, nie tylko '\''. (Z wyjątkiem ' ': and $~32, %al/ jnzw obu naszych pętlach traktuje spację jako terminator, co jest prawdopodobnie wygodne do testowania za pomocą liczby całkowitej na początku linii.)

Każda operacja, która modyfikuje się %alw pętli, ma gałąź używającą flagi ustawioną przez wynik, a każda gałąź przechodzi (lub spada) w inne miejsce.


Czy potrzebujesz nawet inicjalizacji, eaxbiorąc pod uwagę, że AIUI w trybach 64-bitowych z kodami małych miejsc docelowych zresetuje wyższe bity na 0?
Daniel Schepler

@Daniel: pisanie rejestru 32-bitowego zera rozszerza się na 64-bit . Zapisanie 8- lub 16-bitowego rejestru zachowuje zachowanie z innych trybów: połączenie z istniejącą wartością. AMD64 nie naprawiło fałszywej zależności dla rejestrów 8 i 16-bitowych i nie zmieniło się setcc r/m8w setcc r/m32, więc nadal potrzebujemy głupiej 2-instrukcji xor-zero / set flags / setcc %alsekwencja, aby utworzyć 32/64-bit 0 lub 1 zmienna i potrzebuje zerowanego rejestru przed ustawieniem flagi. (Lub użyj mov $0, %eaxzamiast lub użyj movzxna ścieżce krytycznej).
Peter Cordes

1

Siatkówka , 96 bajtów

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*
.+;

Wypróbuj online! Link zawiera pakiet testowy. Wyjaśnienie:

T`'L`_l

Usuń 's i przekonwertuj wszystko na małe litery.

\B
:

Rozdziel cyfry, ponieważ wszystkie cyfry szesnastkowe muszą zostać przeliczone na dziesiętne.

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

Zidentyfikuj podstawę liczby.

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

Konwertuj znaki a-gna liczby 10-16.

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

Wykonaj konwersję podstawową na liście cyfr. $.($`*$1*_*$2*jest skrótem, dla $.($`*$1*_*$2*_)którego mnoży się $`i $1razem i dodaje $2. ( $`jest częścią ciągu przed ;ie bazą).

.+;

Usuń bazę.


Doceniam dosłowne podejście do programowania, które podjąłeś, aby wyjaśnić kod :-)
grooveplex


1

Perl 6 , 29 bajtów

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

Wypróbuj online!

Perl 6 wymaga jawnego 0oprzedrostka ósemkowego i nie obsługuje takich jak przedrostek wielkich liter 0X.

Wyjaśnienie

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

1

Oktawa , 29 21 20 bajtów

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

Wypróbuj online!

-8 bajtów dzięki @TomCarpenter


Dla 22 bajtów:@(x)str2num(x(x~="'"))
Tom Carpenter

Który staje się dla 21 bajtów:@(x)str2num(x(x~=39))
Tom Carpenter

Oktal nie wydaje się działać (przynajmniej na TIO) ... na przykład f=("077")zwraca, ans = 77gdy powinien wynosić 63. Lub, jak w przypadku testowym w OP, f=("012345")powinien zwracać 5349, ale zamiast tegoans = 12345
brhfl

1

Bash, 33 bajty

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

TIO

Zsh, 29 27 bajtów

-2 bajty dzięki @GammaFunction

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

TIO


Sprytny! Myślałem, że setopt octalzeroesbędzie to konieczne dla Zsh.
GammaFunction

Możesz zapisać 2 bajty w Zsh <<<$[...]zamiast zamiastecho $[...]
GammaFunction

dzięki, nie wiedziałem, że puste polecenie zsh z przekierowaniem może wyświetlać dane wyjściowe, nie wiem dużo o zsh, wiem o wiele lepszy bash
Nahuel Fouilleul

wiedziałem, że bash automatycznie interpretuje liczby z wiodącym zerem na ósemkę i musi zostać usunięty na przykład w dacie / czasie
Nahuel Fouilleul

0

Idź, 75

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

Wydaje się, że nie działa to w przypadku literałów binarnych ani pojedynczych cudzysłowów.
Nick Matteo

O kurcze. Zaraz to naprawię. Całkowicie zapomniałem o ogranicznikach
vityavv

0

JavaScript (ES6), 112 bajtów

n=>+(n=n.toLowerCase().replace(/'/g,""))?n[1]=="b"?parseInt(n.substr(2),2):parseInt(n,+n[0]?10:n[1]=="x"?16:8):0







0

C ++, G ++, 189 bajtów

#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");}

Nie ma potrzeby przeprowadzania testów

Wymaga instalacji g++z obsługą C ++ 14

Teraz wyjaśnienia:

Zapisuje plik o nazwie a.cpp, używa GCC do jego skompilowania i podaje plik, który wypisuje liczbę




0

C (gcc) / Bash / C ++, 118 bajtów

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

Wypróbuj online!


Grałem w golfa trochę kodu. Potem zdałem sobie sprawę, że nie ma żadnego powodu, aby to działało, ale wydaje się, że działa; 158 bajtów .
mój zaimek to monicareinstate

@ ktoś, to okropne, ale mi się podoba!
Johan du Toit

148 bajtów przez połączenie popenisystem . Myślę -x, że G ++ ma flagę do odczytu ze standardowego wejścia. To może być krótsze niż fopen, ale nie wiem, jak wywoływać ze stdin w C.
mój zaimek to monicareinstate

@someone, Wszystko jest teraz połączone w popenpolecenie
Johan du Toit

printf-> echowydaje się działać. Wkrótce będziesz programować w bash.
mój zaimek to monicareinstate

0

Java, 158 154 bajtów

To tylko czekanie na obrzucenie ogniem. Po prostu wypróbowuje wyrażenia regularne, aż coś zadziała i domyślnie zostanie hex.
-4 bajty dzięki @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);}

Wypróbuj online

Za pomocą ScriptEngine, 92 87 bajtów

Jadący pociąg ewaluacyjny. Technicznie rzecz biorąc, przekazuje pochodnię JS, więc nie jest to moje główne przesłanie.

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

TIO


Użyj [bBxX]i 0[bB].+dla niektórych szybkich optymalizacji wyrażeń regularnych.
Wartość tuszu

@ValueInk dzięki
Benjamin Urquhart

To nie jest liczba całkowita, to długa, tytuł wyraźnie mówi, że liczba całkowita, pojedyncza lub podwójna precyzja IEEE754 może stać się niepoprawna z powodu metody zastosowanej do zapisania liczby, gdy z powodu systemu miejsc dziesiętnych w IEEE754 pl.wikipedia.org/wiki/ IEEE_754 # Roundings_to_nearest , obsługuje również liczbę wyższą niż 2 biliony ( 0x9999999999)
Martin Barker

@MartinBarker wolno używać Longzamiast Integerdo gry w golfa. Ponadto, jeśli masz rację, Python nie może konkurować, ponieważ ma skutecznie liczby całkowite o dowolnej dokładności. Również longw Javie jest liczbą całkowitą reprezentowaną przez 64 bity zamiast 32. Nie ma miejsc dziesiętnych.
Benjamin Urquhart

Długą rzeczą było to, że używasz długiej, a nie całkowitej liczby i mylisz się co do celów golfowych, The correct output never will exceed 2*10^9dość wyraźnie stwierdza, że ​​oznacza to, że długiego nie można użyć samodzielnie, ponieważ mogę go podać, 0x9999999999a wygeneruje liczbę wyższa niż 2 * 10 ^ 9, podczas gdy C ++ spowodowałoby to problem przepełnienia pamięci, ponieważ używasz więcej niż 32 bitów pamięci, gdy przypisałeś tylko 32 bity pamięci do tej liczby
Martin Barker
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.