Decidi un valore letterale intero C.

Oct 14 2020

Obbiettivo

Data una stringa ASCII, decidere se si tratta di un valore letterale intero C valido.

C intero letterale

Il valore letterale intero AC è costituito da:

  • Uno di:

    • 0seguito da zero o più cifre ottali ( 0- 7)

    • Una cifra decimale diversa da zero seguita da zero o più cifre decimali ( 0- 9)

    • 0Xoppure 0x, seguito da una o più cifre esadecimali ( 0- 9, A- Fe a- f)

  • facoltativamente seguito da uno di:

    • Uno tra Uo u, che sono i suffissi "non firmati"

    • Uno dei L, l, LL, o ll, che sono il "lungo" e "long long" suffissi

    • Qualsiasi combinazione di quanto sopra, in qualsiasi ordine.

Tieni presente che possono esserci molte cifre arbitrariamente, anche se C non supporta interi di lunghezza arbitraria. Allo stesso modo, anche se il letterale with le co superasse il longtipo o co, è comunque considerato un letterale valido.

Si noti inoltre che ci deve non essere un segno che porta più o meno, perché non è considerato una parte del letterale.

Regole

  • È definito dall'implementazione per accettare spazi bianchi iniziali o finali.

  • La stringa non ASCII rientra nella situazione non importa .

Esempi

Verità

  • 0

  • 007

  • 42u

  • 42lu

  • 42UL

  • 19827489765981697847893769837689346573uLL(Le cifre possono essere arbitrariamente molte anche se non si adattano al unsigned long longtipo)

  • 0x8f6aa032838467beee3939428l(Così può per il longtipo)

  • 0XCa0 (Puoi mescolare i casi)

Falsità

  • 08 (Cifra non ottale)

  • 0x(Una cifra deve seguire Xo x)

  • -42 (La firma principale non fa parte del letterale)

  • 42Ll(Solo LLo llè valido per il long longtipo)

  • 42LLLL (Identificatore di tipo ridondante)

  • 42Uu (Identificatore di tipo ridondante)

  • 42Ulu (Identificatore di tipo ridondante)

  • 42lul (Identificatore di tipo ridondante)

  • 42H (Identificatore di tipo non valido)

  • 0b1110010000100100001 (C ++ valido, ma non C valido)

  • Hello

  • Stringa vuota

Soluzione ungolfed

Haskell

Non riconosce gli spazi bianchi iniziali o finali.

Ritorno ()in caso di successo. Altrimenti fallimento monadico.

import Text.ParserCombinators.ReadP

decideCIntegerLit :: ReadP ()
decideCIntegerLit = do
    choice [
        do
            '0' <- get
            munch (flip elem "01234567"),
        do
            satisfy (flip elem "123456789")
            munch (flip elem "0123456789"),
        do
            '0' <- get
            satisfy (flip elem "Xx")
            munch1 (flip elem "0123456789ABCDEFabcdef")
        ]
    let unsigned = satisfy (flip elem "Uu")
    let long = string "l" +++ string "L" +++ string "ll" +++ string "LL"
    (unsigned >> long >> return ()) +++ (optional long >> optional unsigned)
    eof

Risposte

9 Neil Oct 14 2020 at 07:10

Retina 0.8.2 , 60 59 byte

i`^(0[0-7]*|0x[\da-f]+|[1-9]\d*)(u)?(l)?(?-i:\3?)(?(2)|u?)$

Provalo online! Il collegamento include casi di test. Modifica: 1 byte salvato grazie a @FryAmTheEggMan. Spiegazione:

i`

Trova la corrispondenza tra maiuscole e minuscole.

^(0[0-7]*|0x[\da-f]+|[1-9]\d*)

Inizia con ottale, esadecimale o decimale.

(u)?

Identificatore non firmato facoltativo.

(l)?

Specificatore di lunghezza opzionale.

(?-i:\3?)

Facoltativamente, ripetere il caso dello specificatore di lunghezza in modo sensibile.

(?(2)|u?)$

Se non esiste ancora uno specificatore senza segno, un'altra possibilità per uno specificatore facoltativo, prima della fine del letterale.

5 Xcali Oct 14 2020 at 12:01

Perl 5 -p , 65 61 byte

@NahuelFouilleul ha rasato 4 byte

$_=/^(0[0-7]*|0x\p{Hex}+|[1-9]\d*)(u?l?l?|l?l?u?)$/i*!/lL|Ll/

Provalo online!

5 KevinCruijssen Oct 14 2020 at 15:11

Java 8 / Scala polyglot, 89 79 byte

s->s.matches("(?!.*(Ll|lL))(?i)(0[0-7]*|[1-9]\\d*|0x[\\da-f]+)(u?l?l?|l?l?u?)")

-10 byte grazie a @NahuelFouilleul

Provalo online in Java 8.
Provalo online in Scala (eccetto con =>invece di ->- grazie a @TomerShetah ).

Spiegazione:

s->           // Method with String parameter and boolean return-type
  s.matches(  //  Check whether the input-string matches the regex
    "(?!.*(Ll|lL))(?i)(0[0-7]*|[1-9]\\d*|0x[\\da-f]+)(u?l?l?|l?l?u?)")

Spiegazione dell'espressione regolare:

In Java, il String#matchesmetodo aggiunge implicitamente un interlinea e uno finale ^...$per abbinare l'intera stringa, quindi la regex è:

^(?!.*(Ll|lL))(?i)(0[0-7]*|[1-9]\d*|0x[\da-f]+)(u?l?l?|l?l?u?)$
 (?!         )     # The string should NOT match:
^   .*             #   Any amount of leading characters
      (     )      #   Followed by:
       Ll          #    "Ll"
         |lL       #    Or "lL"
                   # (Since the `?!` is a negative lookahead, it acts loose from the
                   #  rest of the regex below)

 (?i)              # Using case-insensitivity,
^    (             # the string should start with:       
       0           #   A 0
        [0-7]*     #   Followed by zero or more digits in the range [0,7]
      |            #  OR:
       [1-9]       #   A digit in the range [1,9]
            \d*    #   Followed by zero or more digits
      |            #  OR:
       0x          #   A "0x"
         [     ]+  #   Followed by one or more of:
          \d       #    Digits
            a-f    #    Or letters in the range ['a','f'] 
     )(            # And with nothing in between,
              )$   # the string should end with:
        u?         #   An optional "u"
          l?l?     #   Followed by no, one, or two "l"
       |           #  OR:
        l?l?       #   No, one, or two "l"
            u?     #   Followed by an optional "u"
5 skytomo Oct 14 2020 at 20:34

C # (.NET Core) , 197191 byte

@nwellnhof rasato 6 byte:

using c=System.Console;class P{static void Main(){c.WriteLine(System.Text.RegularExpressions.Regex.IsMatch(c.ReadLine(),@"^(?!.*(Ll|lL))(?i)(0[0-7]*|[1-9]\d*|0x[\da-f]+)(u?l?l?|l?l?u?)$"));}}

Originale:

using c=System.Console;using System.Text.RegularExpressions;class P{static void Main(){c.WriteLine(Regex.IsMatch(c.ReadLine(),@"^(?!.*(Ll|lL))(?i)(0[0-7]*|[1-9]\d*|0x[\da-f]+)(u?l?l?|l?l?u?)$"));}}

Provalo online!

4 HyperNeutrino Oct 14 2020 at 06:59

Python 3 , 103 byte

import re;re.compile("^(0[0-7]*|[1-9]\d*|0[xX][\dA-Fa-f]+)([uU](L|l|LL|ll)?|(L|l|LL|ll)[uU]?)?$").match

Provalo online!

solo una regex di base, probabilmente molto subottimale

restituisce un oggetto match per true e None per falsy; l'input non può contenere spazi bianchi circostanti

-3 byte grazie a Digital Trauma (sulla mia risposta Retina)
-1 byte grazie a FryAmTheEggman (sulla mia risposta Retina)
-3 byte grazie a pxeger

3 HyperNeutrino Oct 14 2020 at 07:04

Retina 0.8.2 , 73 byte

^(0[0-7]*|[1-9]\d*|0[xX][\dA-Fa-f]+)([uU](L|l|LL|ll)?|(L|l|LL|ll)[uU]?)?$

Provalo online!

Proprio la stessa regex che ho usato. La prima volta che usi Retina, sono sicuro che può essere ottimizzato con alcune cose del golf Retina!

-3 byte grazie a Digital Trauma
-1 byte grazie a FryAmTheEggman

2 Arnauld Oct 14 2020 at 14:02

JavaScript (ES6), 77 byte

s=>/^(0x[\da-f]+|0[0-7]*|[1-9]\d*)(u?l?l?|l?l?u?)$/i.test(s)&!/Ll|lL/.test(s)

Provalo online!

Come?

La prima regex non fa distinzione tra maiuscole e minuscole. Gli unici pattern non validi che non possono essere filtrati in questo modo sono "Ll"e "lL". Quindi usiamo una seconda espressione regolare che distingue tra maiuscole e minuscole per prenderci cura di loro.

2 Neil Oct 14 2020 at 18:15

Carboncino , 76 byte

≔⊟Φ³¬⌕↧θ…0xιη≔✂↧θη⁻LθL⊟Φ⪪”{“↧←;⭆δa”¶⁼ι↧…⮌θLι¹ζ›∧⁺Lζ¬⊖η⬤ζ№E∨×⁸ηχ⍘λφι∨№θLl№θlL

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

≔⊟Φ³¬⌕↧θ…0xιη

Trova la lunghezza del prefisso più lungo di 0xnell'input minuscolo.

≔✂↧θη⁻LθL⊟Φ⪪”{“↧←;⭆δa”¶⁼ι↧…⮌θLι¹ζ

Tagliare via il prefisso e controllare anche per un suffisso minuscolo di ull, ul, lluo lu, in caso affermativo poi tagliare che fuori pure.

›...∨№θLl№θlL

L'input originale non deve contenere Llo lL.

∧⁺Lζ¬⊖η

La stringa suddivisa in sezioni non deve essere vuota a meno che non lo sia il prefisso 0.

⬤ζ№E∨×⁸ηχ⍘λφι

Convertire la lunghezza del prefisso a 10, 8o 16opportunamente, poi prendere che molti di base 62 cifre e verificare che tutti i caratteri rimanenti sono cambiate in maiuscolo una di quelle cifre.

2 KevinCruijssen Oct 14 2020 at 15:57

05AB1E , 63 61 62 byte

„Uuõª„LLæDl«âDí«JéRʒÅ¿}нõ.;Ðć_ilDć'xQiA6£мÐþQë\7ÝKõQë\þQ}sõÊ*

Questo non è troppo facile senza regex ..: / Può sicuramente essere giocato un po 'di più, però.

+1 byte come bug-fix per ingressi desiderate "u", "l", "LL", ecc (grazie per notare @Neil )

Provalo online o verifica tutti i casi di test .

Spiegazione:

„Uu                 # Push string "Uu"
   õª               # Convert it to a list of characters, and append an empty string:
                    #  ["U","u",""]
     „LL            # Push string "LL"
        æ           # Take its powerset: ["","L","L","LL"]
         Dl         # Create a lowercase copy: ["","l","l","ll"]
           «        # Merge the lists together: ["","L","L","LL","","l","l","ll"]
            â       # Create all possible pairs of these two lists
             Dí     # Create a copy with each pair reversed
               «    # Merge the list of pairs together
                J   # Join each pair together to a single string
                 éR # Sort it by length in descending order

Ora abbiamo l'elenco:

["llu","LLu","llU","LLU","ull","uLL","Ull","ULL","ll","LL","lu","lu","Lu","Lu","lU","lU","LU","LU","ll","LL","ul","ul","uL","uL","Ul","Ul","UL","UL","l","l","L","L","u","u","U","U","l","l","L","L","u","u","U","U","","","",""]
ʒ                   # Filter this list by:
 Å¿                 #  Where the (implicit) input ends with this string
}н                  # After the filter: only leave the first (longest) one
  õ.;               # And remove the first occurrence of this in the (implicit) input
ÐD                  # Triplicate + duplicate (so there are 4 copies on the stack now)
  ć                 # Extract head; pop and push remainder-string and first character
                    # separated to the stack
   _i               # If this first character is a 0:
     l              #  Convert the remainder-string to lowercase
      D             #  Duplicate it †¹
       ć            #  Extract head again
        'xQi       '#  If it's equal to "x":
            A       #   Push the lowercase alphabet
             6£     #   Only leave the first 6 characters: "abcdef"
               м    #   Remove all those characters from the string
                Ð   #   Triplicate it †²
                 þ  #   Only keep all digits in the copy
                  Q #   And check that the two are still the same
                    #   (thus it's a non-negative integer without decimal .0s)
          ë         #  Else:
           \        #   Discard the remainder-string
            7Ý      #   Push list [0,1,2,3,4,5,6,7]
              K     #   Remove all those digits
               õQ   #   Check what remains is an empty string
   ë                # Else:
    \               #  Discard the remainder-string
     þ              #  Only keep all digits
      Q             #  And check that the two are still the same
                    #  (thus it's a non-negative integer without decimal .0s)
   }s               # After the if-else: Swap the two values on the stack
                    # (this will get the remaining copy of †² for "0x" cases,
                    #  or the remaining copy of †¹ for other cases)
     õÊ             # Check that this is NOT an empty string
       *            # And check that both are truthy
                    # (after which the result is output implicitly)
2 Noodle9 Oct 14 2020 at 17:07

AWK , 86 byte

{print/^(0[0-7]*|[1-9][0-9]*|0[xX][0-9A-Fa-f]+)([uU](L|l|LL|ll)?|(L|l|LL|ll)[uU]?)?$/}

Provalo online!

Stampa semplicemente vero o falso a seconda che la riga di input corrisponda o meno all'espressione regolare. Non accetta spazi iniziali o finali.

1 Lynn Oct 14 2020 at 19:12

Haskell , 169 byte

import Data.Char
s!p=s>""&&dropWhile p s`elem`do u<-["","u","U"];l<-"":words"L l LL ll";[u++l,l++u]
f('0':x:s)|elem x"xX"=s!isHexDigit|1<2=(x:s)!isOctDigit
f s=s!isDigit

Provalo online!

1 pxeger Oct 15 2020 at 03:01

Ruby , 67 byte

->s{/^(0[0-7]*|[1-9]\d*|0x[\da-f]+)(u?l?l?|l?l?u?)?$/i=~s&&/Ll/!~s}

Provalo online!

1 pxeger Oct 15 2020 at 03:08

Elisir , 74 byte

&(&1=~~r/^(0[0-7]*|[1-9]\d*|0x[\da-f]+)(u?l?l?|l?l?u?)?$/i&&!(&1=~~r/Ll/))

Provalo online!