Entscheide dich für ein C-Integer-Literal

Oct 14 2020

Zielsetzung

Entscheiden Sie anhand einer ASCII-Zeichenfolge, ob es sich um ein gültiges C-Integer-Literal handelt.

C ganzzahliges Literal

Ein ganzzahliges AC-Literal besteht aus:

  • Einer von:

    • 0gefolgt von null oder mehr Oktalstellen ( 0- 7)

    • Eine Dezimalstelle ungleich Null, gefolgt von null oder mehr Dezimalstellen ( 0- 9)

    • 0Xoder 0xgefolgt von einer oder mehreren hexadezimalen Ziffern ( 0- 9, A- Fund a- f)

  • optional gefolgt von einem von:

    • Eines von Uoder u, das sind die "vorzeichenlosen" Suffixe

    • Einer von L, l, LLoder ll, die die „lange“ und „long long“ Suffixe sind

    • Beliebige Kombination der oben genannten in beliebiger Reihenfolge.

Beachten Sie, dass es beliebig viele Ziffern geben kann, obwohl C keine Ganzzahlen beliebiger Länge unterstützt. Auch wenn das Literal mit lund co den longTyp oder die Co überlaufen würde , wird es dennoch als gültiges Literal betrachtet.

Beachten Sie auch, dass es kein führendes Plus- oder Minuszeichen geben darf, da es nicht als Teil des Literal betrachtet wird.

Regeln

  • Es ist implementierungsdefiniert, um führende oder nachfolgende Leerzeichen zu akzeptieren.

  • Nicht-ASCII-Zeichenfolgen fallen in eine Situation, in der es egal ist.

Beispiele

Wahrheit

  • 0

  • 007

  • 42u

  • 42lu

  • 42UL

  • 19827489765981697847893769837689346573uLL(Ziffern können beliebig viele sein, auch wenn sie nicht zum unsigned long longTyp passen )

  • 0x8f6aa032838467beee3939428l(So ​​kann der longTyp)

  • 0XCa0 (Sie können Fälle mischen)

Falsch

  • 08 (Nicht oktale Ziffer)

  • 0x(Eine Ziffer muss folgen Xoder x)

  • -42 (Führende Signatur ist nicht Teil des Literal)

  • 42Ll(Nur LLoder llgültig für den long longTyp)

  • 42LLLL (Redundanter Typbezeichner)

  • 42Uu (Redundanter Typbezeichner)

  • 42Ulu (Redundanter Typbezeichner)

  • 42lul (Redundanter Typbezeichner)

  • 42H (Ungültiger Typbezeichner)

  • 0b1110010000100100001 (Gültiges C ++, aber nicht gültiges C)

  • Hello

  • Leerer String

Ungolfed Lösung

Haskell

Erkennt keine führenden oder nachfolgenden Leerzeichen.

Rückkehr ()zum Erfolg. Sonst monadisches Versagen.

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

Antworten

9 Neil Oct 14 2020 at 07:10

Retina 0,8,2 , 60 59 Bytes

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

Probieren Sie es online aus! Link enthält Testfälle. Bearbeiten: 1 Byte dank @FryAmTheEggMan gespeichert. Erläuterung:

i`

Match ohne Berücksichtigung der Groß- und Kleinschreibung.

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

Beginnen Sie entweder mit Oktal, Hex oder Dezimal.

(u)?

Optionaler vorzeichenloser Bezeichner.

(l)?

Optionaler Längenbezeichner.

(?-i:\3?)

Optional können Sie den Fall des Längenangaben empfindlich wiederholen.

(?(2)|u?)$

Wenn noch kein vorzeichenloser Bezeichner vorhanden ist, besteht vor dem Ende des Literal eine weitere Chance für einen optionalen Bezeichner.

5 Xcali Oct 14 2020 at 12:01

Perl 5 -p , 65 61 Bytes

@NahuelFouilleul rasierte 4 Bytes

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

Probieren Sie es online aus!

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 Bytes dank @NahuelFouilleul

Probieren Sie es online in Java 8 aus.
Probieren Sie es online in Scala aus (außer mit =>statt ->- dank @TomerShetah ).

Erläuterung:

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?)")

Regex Erklärung:

In Java String#matchesfügt die Methode implizit einen führenden und einen nachfolgenden hinzu ^...$, um der gesamten Zeichenfolge zu entsprechen. Der reguläre Ausdruck lautet also:

^(?!.*(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) , 197 191 Bytes

@wellnhof rasiert 6bytes:

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

Original:

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

Probieren Sie es online aus!

4 HyperNeutrino Oct 14 2020 at 06:59

Python 3 , 103 Bytes

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

Probieren Sie es online aus!

nur eine einfache Regex, wahrscheinlich sehr suboptimal

Gibt ein Übereinstimmungsobjekt für wahr und Keine für falsch zurück. Die Eingabe enthält möglicherweise keine umgebenden Leerzeichen

-3 Bytes dank Digital Trauma (auf meiner Retina-Antwort)
-1 Byte dank FryAmTheEggman (auf meiner Retina-Antwort)
-3 Bytes dank pxeger

3 HyperNeutrino Oct 14 2020 at 07:04

Retina 0,8,2 , 73 Bytes

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

Probieren Sie es online aus!

Genau die gleiche Regex, die ich verwendet habe. Ich bin mir sicher, dass dies bei der ersten Verwendung von Retina mit einigen Retina-Golf-Dingen optimiert werden kann!

-3 Bytes dank Digital Trauma
-1 Bytes dank 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)

Probieren Sie es online aus!

Wie?

Bei der ersten Regex wird die Groß- und Kleinschreibung nicht berücksichtigt. Die einzigen ungültigen Muster, die auf diese Weise nicht herausgefiltert werden können, sind "Ll"und "lL". Deshalb verwenden wir einen zweiten regulären Ausdruck, bei dem die Groß- und Kleinschreibung beachtet wird.

2 Neil Oct 14 2020 at 18:15

Holzkohle , 76 Bytes

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

Probieren Sie es online aus! Der Link führt zur ausführlichen Version des Codes. Erläuterung:

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

Suchen Sie die Länge des längsten Präfixes von 0xin der Eingabe in Kleinbuchstaben.

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

Scheibe aus dem Präfix und prüfen auch für einen Klein Suffix ull, ul, lluoder lu, und wenn ja , dann schneiden dass Off als auch.

›...∨№θLl№θlL

Die ursprüngliche Eingabe darf kein Lloder enthalten lL.

∧⁺Lζ¬⊖η

Die in Scheiben geschnittene Zeichenfolge darf nicht leer sein, es sei denn, das Präfix war 0.

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

Konvertieren Sie die Präfixlänge zu 10, 8oder in 16geeigneter Weise , nehmen Sie dann , dass viele Basis 62 Ziffern und prüfen, ob alle verbleibenden Kleinbuchstaben Zeichen einer dieser Ziffern sind.

2 KevinCruijssen Oct 14 2020 at 15:57

05AB1E , 63 61 62 Bytes

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

Ohne Regexes ist das nicht so einfach ..: / Kann aber definitiv ein bisschen mehr Golf spielen.

1 Byte als Bug-Fix für Eingaben wie "u", "l", "LL"usw. (Dank für bemerken @Neil )

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

„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

Wir haben jetzt die Liste:

["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 Bytes

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

Probieren Sie es online aus!

Druckt einfach wahrheitsgemäß oder falsch, je nachdem, ob die Eingabezeile mit dem regulären Ausdruck übereinstimmt oder nicht. Akzeptiert keine führenden oder nachfolgenden Leerzeichen.

1 Lynn Oct 14 2020 at 19:12

Haskell , 169 Bytes

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

Probieren Sie es online aus!

1 pxeger Oct 15 2020 at 03:01

Ruby , 67 Bytes

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

Probieren Sie es online aus!

1 pxeger Oct 15 2020 at 03:08

Elixier , 74 Bytes

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

Probieren Sie es online aus!